Outlook - Move Old Mail out of Inbox to Folder

This topic contains 10 replies, has 6 voices, and was last updated by Profile photo of shaps shaps 2 months ago.

  • Author
    Posts
  • #22912
    Profile photo of H Man
    H Man
    Participant

    Hello –

    I am looking to scan my inbox every day and identify old email messages , any messages Identified i'd look to move to a folder called "Older Than 6 Months", which is a sub folder n my inbox.

    Here is what I have so Far. I can get the inbox and have the filter, just not sure hwo to move the email to the "Older Than 6 Months" Folder

    
    $Date = [DateTime]::Now.AddDays(-180)
    
    $Last6Months =  $Date.tostring("MM/dd/yyyy")
    
    
    $o = New-Object -comobject outlook.application
    $n = $o.GetNamespace(“MAPI”)
    
    
    #Pick Which Folder
    $Account = $n.Folders | ? { $_.Name -eq 'jcool@logs.com' };
    $Inbox = $Account.Folders | ? { $_.Name -match 'Inbox' };
    
    
    
    
    $Inbox.Items | ? {$_.senton -ge "$Last6Months"  }  | foreach {
      
      #Need code to move emails here
      
    }
    
    
    
  • #22913
    Profile photo of Tim Pringle
    Tim Pringle
    Participant

    Hey fella,

    If you've got the code for identifying and parsing through the items, it should just be a case of using the Move method for each object.

    $TargetFolder = $Inbox.Folders.Item('Older Than 6 Months')
    
    $Inbox.Items |
    Where-Object -FilterScript {
        $_.senton -ge "$Last6Months"  
    }  |
    ForEach-Object -Process {
        $psitem.Move($TargetFolder)
    }
    
  • #22914
    Profile photo of H Man
    H Man
    Participant

    As always Thanks Tim Ill give this a try

  • #22915
    Profile photo of H Man
    H Man
    Participant

    Tim this is the final script

    
    $Date = [DateTime]::Now.AddDays(-180)
    
    $Last6Months =  $Date.tostring("MM/dd/yyyy")
    
    
    $o = New-Object -comobject outlook.application
    $n = $o.GetNamespace(“MAPI”)
    
    
    
    $Account = $n.Folders | ? { $_.Name -eq 'jcool@logs.com' };
    $Inbox = $Account.Folders | ? { $_.Name -match 'Inbox' };
    $TargetFolder = $Inbox.Folders.Item('Older Than 6 Months')
    
    
    $Inbox.Items |
    Where-Object -FilterScript {
        $_.senton -ge "$Last6Months"  
    }  |
    ForEach-Object -Process {
        $psitem.Move($TargetFolder)
    }
    
  • #22921
    Profile photo of H Man
    H Man
    Participant

    Hey Tim, When i run the script it moves the email but a windows pop up says ," The custom form cannot be opened , outlook will use an outlook form ". Any way to get rid of that?

  • #22922
    Profile photo of Tim Pringle
    Tim Pringle
    Participant

    Not seen that one before. It's usually a good idea though either not have have the outlook client itself running at the time (otherwise, you're as well to use VBA macros), or if you have to have the client running, to wait for the script start first

  • #22923
    Profile photo of H Man
    H Man
    Participant

    I am actually stoping outlook 1st with this

    if ( [bool](Get-Process OUTLOOK* -EA SilentlyContinue) ) {ps OUTLOOK* | kill -Force ; Start-Sleep -Seconds 10 }

  • #22938
    Profile photo of H Man
    H Man
    Participant

    Hey Tim, i tried it on another computer and it worked fine!. That outlook must be jacked up!

    Thanks Again.. much appreciated!

  • #61447
    Profile photo of Pete
    Pete
    Participant

    Hey all,

    Sorry to post on this old thread – But it's the simplest and closest thing I can find for what I want to achieve. (I haven't actually found anything, however complicated, that achieves exactly what I want).

    Can anyone tell me if this same thing (moving individual mail items between folders based on age) is even possible using powershell without Outlook in the picture at all? Like a direct manipulation of the mailbox on the Exchange server?

  • #61752
    Profile photo of William Wang
    William Wang
    Participant

    Hello thanks for this.

    Tried this out and would like to add:

    1. In my case I had to use "-lt" to identify older emails
    2. For some reason it would skip messages and I had to loop until all identified messages are processed.

    Here's a sample – hopefully will help somebody looking to do something similar:

    start-transcript -path ".\processing.log" -append
    
    $Sent_cutoff = [DateTime]::Now.AddDays(-30)
    $Delete_cutoff = [DateTime]::Now.AddDays(-60)
    
    $Sent_cutoff_mmddyyyy =  $Sent_cutoff.tostring("MM/dd/yyyy")
    $Delete_cutoff_mmddyyyy =  $Delete_cutoff.tostring("MM/dd/yyyy")
    
    $o = New-Object -comobject outlook.application
    $n = $o.GetNamespace(“MAPI”)
    
    $Account = $n.Folders | ? { $_.Name -eq 'address@emaildomain.com' }
    $Sent_Items = $Account.Folders | ? { $_.Name -match 'Sent Items' }
    $Deleted_Items = $Account.Folders | ? { $_.Name -match 'Deleted Items' }
    
    do
    {
        $exitloop = 0
    
        $Sent_Items.Items | % {
            #write-output "before checking for sent items cutoff date"
            if ($_.senton -lt "$Sent_cutoff_mmddyyyy")
            {
                write-output "Before moving a message from Sent Items to Deleted Items_______________________________________________________________________________"
                $message = $_.Move($Deleted_Items)
                write-output "Sender: $(($message).SenderName)"
                write-output "To: $(($message).To)"
                write-output "Subject: $(($message).Subject)"
                write-output "Sent: $(($message).SentOn)"
                write-output "After moving a message from Sent Items to Deleted Items_______________________________________________________________________________`n"
                $exitloop = 1
            }
        }
    
        $Deleted_Items.Items | % {
            #write-output "before checking for Deleted items cutoff date"
            if ($_.senton -lt "$Delete_cutoff_mmddyyyy") 
            { 
                write-output "Before deleting a message from Deleted Items_______________________________________________________________________________"
                write-output "Sender: $($_.SenderName)"
                write-output "To: $($_.To)"
                write-output "Subject: $($_.Subject)"
                write-output "Sent: $($_.SentOn)"
                $_.Delete()
                write-output "After deleting a message from Deleted Items_______________________________________________________________________________`n"
                $exitloop = 1
            }
        }
    } while ($exitloop -ne 0)
    
    stop-transcript
    
    • #65085
      Profile photo of shaps
      shaps
      Participant

      If it helps, we have just written this to move some old email out of an Inbox containing 100,000 emails to another folder.
      Ensure Outlook is closed prior to running:

      $o = New-Object -comobject outlook.application
      $n = $o.GetNamespace(“MAPI”)

      $Account = $n.Folders | ? { $_.Name -eq 'firstname.lastname@domain.com' };
      $Inbox = $Account.Folders | ? { $_.Name -match 'Inbox' };
      $TargetFolder = $Inbox.Folders.Item('2016')

      $sFilter="[SentOn] < '{0:dd/MM/yyyy}'" -f [DateTime]::Now.AddDays(-180) $OldMails = $inbox.Items.Restrict($sfilter) if ($OldMails.count -eq 0) { Write-Host "INFO: No mails found to move" } While ($OldMails.count -ne 0) { Write-Host "INFO:" $OldMails.count "Mails found to move, moving now" foreach ($OldMail in $OldMails) { Write-Host "INFO: Moving item sent"$OldMail.Senton"from sender :"$OldMail.SenderName $moveitem = $OldMail.Move($TargetFolder) } $OldMails = $inbox.Items.Restrict($sfilter) } Write-Host "INFO: move completed"

You must be logged in to reply to this topic.