Getting item/folder retention policy with EWS

This post is provoked by a question over at the TechNet Exchange forums. I’ve always known that you can get the retention tag associated with particular mail item or folder using the EWS, and I have bookmarked some great articles on the subject (for example this one and this one), but I’ve never actually gotten to implement it in a script. The reason behind this are several, but most importantly, in order to get this information for another user’s items/folder, you need to either have Full Access permissions or use Impersonation. Both offer direct access to users’ company and private information, and being the good compliant IT guy I try to avoid those as much as possible.

Anyway, here are the ingredients needed for such a script. First, you will obviously need to connect PowerShell to the Exchange Online EWS endpoint. I have a separate script that does that for me, which I can call from within other script where necessary, but for the sake of completeness, here are the important bits (without any error handling and stuff):

Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll" #loads the EWS API

$global:exchangeService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013)

$exchangeService.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $creds.UserName, $creds.GetNetworkCredential().password

$exchangeService.Url = ""

Once connected, we create a folder view and get a listing of all the folders in the mailbox:

$FPageSize = 100
$FOffset = 0
$folderView = new-object Microsoft.Exchange.WebServices.Data.FolderView($FPageSize,$FOffset,[Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning)
$folderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$oFindFolders = $exchangeService.FindFolders([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$null,$folderView)

The list will then be saved in the $oFindFolders variable, and we can easily generate a CSV file containing all the needed information:

$oFindFolders | select DisplayName,*tag | Export-Csv -nti retentiontags.csv

You will probably be disappointed that the tag information is referenced as GUID instead of its DisplayName. But we can quickly fix that by getting the list of all available tags and creating a helper function:

$RetentionTags = $exchangeService.GetUserRetentionPolicyTags()

function GetTagName($tagGUID) {
if (!$tagGUID) { return ($RetentionTags.RetentionPolicyTags | ? {$_.Type -eq "All"}).DisplayName }
foreach ($tag in $RetentionTags.RetentionPolicyTags) {
if ($tag.RetentionId -eq $tagGUID) { return $tag.DisplayName }

Now we can regenerate the CSV file with a human readable information:

$oFindFolders | select DisplayName, @{n="PolicyTag";e={GetTagName $_.PolicyTag.RetentionId}}, @{n="ArchiveTag";e={GetTagName $_.ArchiveTag.RetentionId}} | Export-Csv -nti retentiontags.csv

The empty entries correspond to the ‘use parent folder’/default tag scenario.

Hope this helps!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.