Outlook - Move Old Mail out of Inbox to Folder

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
  
}


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)
}

As always Thanks Tim Ill give this a try

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)
}

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?

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

I am actually stoping outlook 1st with this

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

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

Thanks Again… much appreciated!

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?

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

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"