Yes, this is similar to the script in my previous post but is also different in the following ways:
I would suggest you read my previous post as it covers some fundamental used in this post.
To summarize what the script below does:
Straight to code now. Create a .PS1 file with the code below:
# The script requires the EWS managed API, which can be downloaded here:# http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=c3342fb3-fbcc-4127-becf-872c746840e1# This also requires PowerShell 2.0# Make sure the Import-Module command below matches the DLL location of the API.# This path must match the install location of the EWS managed API. Change it if needed.[string]$info = "White" # Color for informational messages[string]$warning = "Yellow" # Color for warning messages[string]$error = "Red" # Color for error messages[string]$LogFile = "C:\Temp\Log.txt" # Path of the Log Filefunction SearchFolders($MailboxName){ Write-host "Searching folders in Mailbox Name:" $MailboxName -foregroundcolor $info Add-Content $LogFile ("Searching folders in Mailbox Name:" + $MailboxName) #Change the user to Impersonate $service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$MailboxName); #Number of Items to Get $FpageSize =50 $FOffset = 0 $MoreFolders =$true while ($MoreFolders) { #Setup the View to get a limited number of Items at one time $folderView = new-object Microsoft.Exchange.WebServices.Data.FolderView($FpageSize,$FOffset,[Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning) $folderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep $folderView.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet( [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly, [Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, [Microsoft.Exchange.WebServices.Data.FolderSchema]::FolderClass); #Create the Search Filter. $FoSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::FolderClass, "IPF.Note") $oFindFolders = $service.FindFolders([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$FoSearchFilter,$folderView) foreach ($folder in $oFindFolders.Folders) { Write-host "Begining to stamp policy on Items in folder:" $folder.DisplayName -foregroundcolor $info; Add-Content $LogFile ("Begining to stamp policy on Items in folder:" + $folder.DisplayName); &{ StampPolicyOnItems($folder.Id.UniqueId) Write-host "Retention policy stamped on Items in folder:" $folder.DisplayName -foregroundcolor $info Add-Content $LogFile ("Retention policy stamped on Items in folder:" + $folder.DisplayName) } trap [System.Exception] { $IsFailure = $true; Write-host ("Error in StampPolicyOnItems: " + $_.Exception.Message) -foregroundcolor $error; Add-Content $LogFile ("Error in StampPolicyOnItems: " + $_.Exception.Message); Write-host "Failure in stamping Retention policy on Items in folder:" $folder.DisplayName -foregroundcolor $info Add-Content $LogFile ("Failure in stamping Retention policy on Items in folder:" + $folder.DisplayName) continue; } } if ($oFindFolders.MoreAvailable -eq $false) {$MoreFolders = $false} if ($MoreFolders) {$FOffset += $FpageSize} } Write-host "Finished with Mailbox Name:" $MailboxName "Done!" -foregroundcolor $info Write-host "-------------------------------------------------" -foregroundcolor $info Add-Content $LogFile ("Done!") Add-Content $LogFile ("-------------------------------------------------" ) $service.ImpersonatedUserId = $null}function StampPolicyOnItems($fId){ #Number of Items to Get $pageSize =100 $Offset = 0 $MoreItems =$true $ItemCount=0 #PR_POLICY_TAG 0x3019 $PolicyTag = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x3019,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary); #PR_RETENTION_PERIOD 0x301A $RetentionPeriod = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x301A,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer); while ($MoreItems) { #Setup the View to get a limited number of Items at one time $itemView = new-object Microsoft.Exchange.WebServices.Data.ItemView($pageSize,$Offset,[Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning) $itemView.Traversal = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Shallow $itemView.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet( [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly, [Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::ItemClass, [Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject); #Create the Search Filter. $oSearchFilters = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection( [Microsoft.Exchange.WebServices.Data.LogicalOperator]::And) $oSearchFilterEA1 = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::ItemClass, "IPM.My-ARCHIVE") $oSearchFilterEA2 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+Not(New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+Exists($PolicyTag)) $oSearchFilters.add($oSearchFilterEA1) $oSearchFilters.add($oSearchFilterEA2) $uniqueId = new-object Microsoft.Exchange.WebServices.Data.FolderId($fId); $oFindItems = $service.FindItems($uniqueId,$oSearchFilters,$itemView) foreach ($Item in $oFindItems.Items) { $ItemCount++ Write-host "Item Number:" $ItemCount Write-host "Message Class:" $Item.ItemClass Write-host "Subject:" $Item.Subject #Same as that on the policy $Item.SetExtendedProperty($RetentionPeriod, 1095) #Change the GUID based on your policy tag $PolicyTagGUID = new-Object Guid("{92186ff7-7f4d-4efa-a09b-bbdc5aee3908}"); $Item.SetExtendedProperty($PolicyTag, $PolicyTagGUID.ToByteArray()) $Item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite) Write-host "Retention policy stamped on " $Item.ID -foregroundcolor $info Add-Content $LogFile ("Retention policy stamped on " + $Item.ID) } if ($oFindItems.MoreAvailable -eq $false) {$MoreItems = $false} if ($MoreItems) {$Offset += $pageSize} }}Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll"$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)# Set the Credentials$service.Credentials = new-object Microsoft.Exchange.WebServices.Data.WebCredentials("serviceAccount","Password","domain")# Change the URL to point to your cas server$service.Url= new-object Uri("http://YOUR-CAS/EWS/Exchange.asmx")# Set $UseAutoDiscover to $true if you want to use AutoDiscover else it will use the URL set above$UseAutoDiscover = $false#Read data from the UserAccounts.txtimport-csv UserAccounts.txt | foreach-object { $WindowsEmailAddress = $_.WindowsEmailAddress.ToString() if ($UseAutoDiscover -eq $true) { Write-host "Autodiscovering.." -foregroundcolor $info $UseAutoDiscover = $false $service.AutodiscoverUrl($WindowsEmailAddress) Write-host "Autodiscovering Done!" -foregroundcolor $info Write-host "EWS URL set to :" $service.Url -foregroundcolor $info } #To catch the Exceptions generated trap [System.Exception] { Write-host ("Error: " + $_.Exception.Message) -foregroundcolor $error; Add-Content $LogFile ("Error: " + $_.Exception.Message); continue; } SearchFolders($WindowsEmailAddress)}
# The script requires the EWS managed API, which can be downloaded here:# http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=c3342fb3-fbcc-4127-becf-872c746840e1# This also requires PowerShell 2.0# Make sure the Import-Module command below matches the DLL location of the API.# This path must match the install location of the EWS managed API. Change it if needed.
[string]$info = "White" # Color for informational messages[string]$warning = "Yellow" # Color for warning messages[string]$error = "Red" # Color for error messages[string]$LogFile = "C:\Temp\Log.txt" # Path of the Log File
function SearchFolders($MailboxName){ Write-host "Searching folders in Mailbox Name:" $MailboxName -foregroundcolor $info Add-Content $LogFile ("Searching folders in Mailbox Name:" + $MailboxName)
#Change the user to Impersonate $service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$MailboxName);
#Number of Items to Get $FpageSize =50 $FOffset = 0 $MoreFolders =$true while ($MoreFolders) { #Setup the View to get a limited number of Items at one time $folderView = new-object Microsoft.Exchange.WebServices.Data.FolderView($FpageSize,$FOffset,[Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning) $folderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep $folderView.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet( [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly, [Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, [Microsoft.Exchange.WebServices.Data.FolderSchema]::FolderClass);
#Create the Search Filter. $FoSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::FolderClass, "IPF.Note") $oFindFolders = $service.FindFolders([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$FoSearchFilter,$folderView) foreach ($folder in $oFindFolders.Folders) { Write-host "Begining to stamp policy on Items in folder:" $folder.DisplayName -foregroundcolor $info; Add-Content $LogFile ("Begining to stamp policy on Items in folder:" + $folder.DisplayName); &{ StampPolicyOnItems($folder.Id.UniqueId)
Write-host "Retention policy stamped on Items in folder:" $folder.DisplayName -foregroundcolor $info Add-Content $LogFile ("Retention policy stamped on Items in folder:" + $folder.DisplayName) } trap [System.Exception] { $IsFailure = $true; Write-host ("Error in StampPolicyOnItems: " + $_.Exception.Message) -foregroundcolor $error; Add-Content $LogFile ("Error in StampPolicyOnItems: " + $_.Exception.Message); Write-host "Failure in stamping Retention policy on Items in folder:" $folder.DisplayName -foregroundcolor $info Add-Content $LogFile ("Failure in stamping Retention policy on Items in folder:" + $folder.DisplayName) continue; } } if ($oFindFolders.MoreAvailable -eq $false) {$MoreFolders = $false} if ($MoreFolders) {$FOffset += $FpageSize} }
Write-host "Finished with Mailbox Name:" $MailboxName "Done!" -foregroundcolor $info Write-host "-------------------------------------------------" -foregroundcolor $info Add-Content $LogFile ("Done!") Add-Content $LogFile ("-------------------------------------------------" ) $service.ImpersonatedUserId = $null}function StampPolicyOnItems($fId){ #Number of Items to Get $pageSize =100 $Offset = 0 $MoreItems =$true $ItemCount=0
#PR_POLICY_TAG 0x3019 $PolicyTag = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x3019,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary);
#PR_RETENTION_PERIOD 0x301A $RetentionPeriod = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x301A,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer);
while ($MoreItems) { #Setup the View to get a limited number of Items at one time $itemView = new-object Microsoft.Exchange.WebServices.Data.ItemView($pageSize,$Offset,[Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning) $itemView.Traversal = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Shallow $itemView.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet( [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly, [Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::ItemClass, [Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject); #Create the Search Filter. $oSearchFilters = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection( [Microsoft.Exchange.WebServices.Data.LogicalOperator]::And) $oSearchFilterEA1 = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::ItemClass, "IPM.My-ARCHIVE") $oSearchFilterEA2 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+Not(New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+Exists($PolicyTag))
$oSearchFilters.add($oSearchFilterEA1) $oSearchFilters.add($oSearchFilterEA2) $uniqueId = new-object Microsoft.Exchange.WebServices.Data.FolderId($fId); $oFindItems = $service.FindItems($uniqueId,$oSearchFilters,$itemView) foreach ($Item in $oFindItems.Items) { $ItemCount++ Write-host "Item Number:" $ItemCount Write-host "Message Class:" $Item.ItemClass Write-host "Subject:" $Item.Subject #Same as that on the policy $Item.SetExtendedProperty($RetentionPeriod, 1095)
#Change the GUID based on your policy tag $PolicyTagGUID = new-Object Guid("{92186ff7-7f4d-4efa-a09b-bbdc5aee3908}");
$Item.SetExtendedProperty($PolicyTag, $PolicyTagGUID.ToByteArray()) $Item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite) Write-host "Retention policy stamped on " $Item.ID -foregroundcolor $info Add-Content $LogFile ("Retention policy stamped on " + $Item.ID) } if ($oFindItems.MoreAvailable -eq $false) {$MoreItems = $false} if ($MoreItems) {$Offset += $pageSize} }}Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll"$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
# Set the Credentials$service.Credentials = new-object Microsoft.Exchange.WebServices.Data.WebCredentials("serviceAccount","Password","domain")
# Change the URL to point to your cas server$service.Url= new-object Uri("http://YOUR-CAS/EWS/Exchange.asmx")
# Set $UseAutoDiscover to $true if you want to use AutoDiscover else it will use the URL set above$UseAutoDiscover = $false
#Read data from the UserAccounts.txtimport-csv UserAccounts.txt | foreach-object { $WindowsEmailAddress = $_.WindowsEmailAddress.ToString() if ($UseAutoDiscover -eq $true) { Write-host "Autodiscovering.." -foregroundcolor $info $UseAutoDiscover = $false $service.AutodiscoverUrl($WindowsEmailAddress) Write-host "Autodiscovering Done!" -foregroundcolor $info Write-host "EWS URL set to :" $service.Url -foregroundcolor $info } #To catch the Exceptions generated trap [System.Exception] { Write-host ("Error: " + $_.Exception.Message) -foregroundcolor $error; Add-Content $LogFile ("Error: " + $_.Exception.Message); continue; } SearchFolders($WindowsEmailAddress)}
UserAccounts.txt contains the list of the users mailboxes in which the items needs to be stamped. This file should exist in the same directory as the .PS1 file.The First row denotes the Field Names. Format of the text file is as below:
WindowsEmailAddressakasha@contoso.comakashb@contoso.comakashc@contoso.com
Enjoy!