Moving Items into their own folder by a date range using the EWS Managed API and Powershell (attempting to reduce mailbox clutter)
Most people these days are on track to endless mailbox clutter based on an exponentially increasing number of email items that arrive every day. Also Shared mailboxes can soon become an administrative nightmare if mailbox content isn’t actively maintained and archived. One small way of trying to claw back some of this affect is to write a script that can organize messages into their own folder based on certain parameters. In Exchange 2007 (and now 2010) you can use the EWS Managed API to do this reasonably easy. You just need to split this up into some easy chunks of functionality that you can logically splice together.
The first chunk is some code that will find the objects in question that you want to move in the EWS Managed API this involves setting up an appropriate search filter.
Because I want to use a date range this means I need two search criteria meaning you have to use a searchfiltercollection with an AND logical operator. Sounds a little complicated but not really first we need to create the collection
$sfCollection = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
Next we need to create two searchfilter objects that will cover the date ranges when want to include in the search (I’ve defined the date as the previous day eg.)
$StartDate = [system.DateTime]::Today.AddDays(-1)
$EndDate = [system.DateTime]::Today
$Sfgt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $StartDate)
$Sflt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $EndDate)
Then all you need to do is add these objects to the serachcollection
$sfCollection.add($Sfgt)
$sfCollection.add($Sflt)
The next thing we need to do is create a folder for the item to go into which is pretty easy Im just going to save it as a sub folder of the inbox and name it after the current date
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = $EndDate.ToString("yyyy-MM-dd")
$NewFolder.Save($InboxFolder.Id.UniqueId)
Now it just a matter of going through the items in the result set and move these to the folder we just created
foreach ($miMailItems in $frFolderResult.Items){
$miMailItems.Subject.ToString()
$miMailItems.Move($NewFolder.Id.UniqueId)
}
I put a download of this code here the complete script itself looks like the following it basically uses the currently logged on user to access the mailbox configured via the email address.
$MailboxName = "user@domain.com"
$StartDate = [system.DateTime]::Today.AddDays(-1)
$EndDate = [system.DateTime]::Today
$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind
$service.AutodiscoverUrl($aceuser.mail.ToString())
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
$Sfgt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $StartDate)
$Sflt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $EndDate)
$sfCollection = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
$sfCollection.add($Sfgt)
$sfCollection.add($Sflt)
$view = new-object Microsoft.Exchange.WebServices.Data.ItemView(2000)
$frFolderResult = $InboxFolder.FindItems($sfCollection,$view)
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = $EndDate.ToString("yyyy-MM-dd")
$NewFolder.Save($InboxFolder.Id.UniqueId)
foreach ($miMailItems in $frFolderResult.Items){
"Moving" + $miMailItems.Subject.ToString()
[VOID]$miMailItems.Move($NewFolder.Id.UniqueId)
}
The first chunk is some code that will find the objects in question that you want to move in the EWS Managed API this involves setting up an appropriate search filter.
Because I want to use a date range this means I need two search criteria meaning you have to use a searchfiltercollection with an AND logical operator. Sounds a little complicated but not really first we need to create the collection
$sfCollection = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
Next we need to create two searchfilter objects that will cover the date ranges when want to include in the search (I’ve defined the date as the previous day eg.)
$StartDate = [system.DateTime]::Today.AddDays(-1)
$EndDate = [system.DateTime]::Today
$Sfgt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $StartDate)
$Sflt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $EndDate)
Then all you need to do is add these objects to the serachcollection
$sfCollection.add($Sfgt)
$sfCollection.add($Sflt)
The next thing we need to do is create a folder for the item to go into which is pretty easy Im just going to save it as a sub folder of the inbox and name it after the current date
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = $EndDate.ToString("yyyy-MM-dd")
$NewFolder.Save($InboxFolder.Id.UniqueId)
Now it just a matter of going through the items in the result set and move these to the folder we just created
foreach ($miMailItems in $frFolderResult.Items){
$miMailItems.Subject.ToString()
$miMailItems.Move($NewFolder.Id.UniqueId)
}
I put a download of this code here the complete script itself looks like the following it basically uses the currently logged on user to access the mailbox configured via the email address.
$MailboxName = "user@domain.com"
$StartDate = [system.DateTime]::Today.AddDays(-1)
$EndDate = [system.DateTime]::Today
$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind
$service.AutodiscoverUrl($aceuser.mail.ToString())
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
$Sfgt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $StartDate)
$Sflt = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, $EndDate)
$sfCollection = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
$sfCollection.add($Sfgt)
$sfCollection.add($Sflt)
$view = new-object Microsoft.Exchange.WebServices.Data.ItemView(2000)
$frFolderResult = $InboxFolder.FindItems($sfCollection,$view)
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = $EndDate.ToString("yyyy-MM-dd")
$NewFolder.Save($InboxFolder.Id.UniqueId)
foreach ($miMailItems in $frFolderResult.Items){
"Moving" + $miMailItems.Subject.ToString()
[VOID]$miMailItems.Move($NewFolder.Id.UniqueId)
}