Using Exchange EWS To Clear Purges Folder


This instalment of EWS fun is brought to you by Daya Patil, a Premier Field Engineer who specialises in Messaging.


Recently one of my customers came across a scenario when migrating from Exchange 2010  to Office 365.  In this issue deleted items were  being moved to the user’s online archive.  This caused significant delay and overhead to the move process since it was happening for several hundred mailboxes.  We found that many of the archive mailboxes were bloated with thousands of deleted items in the purges folder.  Get-MailboxStatistics showed the below results

Get-MailboxStatistics | Format-List

ItemCount : 23894

AssociatedItemCount : 339

DeletedItemCount : 6675

TotalDeletedItemSize : 95.54 MB (100,184,246 bytes)

TotalItemSize : 1.21 GB (1,299,032,376 bytes)

 

Get-MailboxStatistics –archive | Format-List

ItemCount : 122821

AssociatedItemCount : 1

DeletedItemCount : 250910

TotalDeletedItemSize : 1.107 GB (1,188,842,806 bytes)

TotalItemSize : 8.024 GB (8,615,913,596 bytes)

 

 

Migration of these items took a long time, and this customer wanted to remove those mails from archive dumpster.

 

Attempt # 1 – PowerShell

Clearing the Dumpster via PowerShell did not remediate the issue.

Using Exchange Management PowerShell, we tried deleting the mails from dumpster but no luck:

Get-Mailbox –Archive | Search-Mailbox –SearchDumpsterOnly –DeleteContent

 

Attempt #2 – Updated Policy Tag

Next we created a retention policy tag, assigned the retention policy tag to a dedicated retention policy and assigned this new retention policy to the desired mailbox. Unfortunately, disabling single item recovery and forcing Managed Folder Assistant (MFA) for the mailboxes had no effect on the contents of the online archive dumpster.

in Exchange 2010 the dumpster contents are preserved when moving mailboxes so there is no point moving it to a new mailbox database on-premises. 

 

Attempt #3  - MFCMAPI

Using MFCMAPI to delete the content worked. Unfortunately, this solution is inadequate for a bulk amount of several archive mailboxes.

 

Attempt #4 – EWS

Since Exchange Web Services provides a very powerful method to interact with Exchange, can we not use that?  Yes we can! 

EWS worked well to remediate this issue.  The sample code is provided below. 

 

 

EWS Sample Code

Please note that is is sample code.  Use this at your own risk, and must be validated in your test lab prior to executing in production. 

 

 

To use Exchange Web services managed API 2.0  with PowerShell, you need to first download it from here.

## To Load Exchange Web services managed API DLL

Import-module "C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll" 

# Set Exchange Version 

$ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1

$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value

$user = [ADSI]"LDAP://<SID=$sid>"

## Create Exchange Service Object

$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion) 

## CAS URL

$service.AutodiscoverUrl($user.Properties.mail)

# List affected mailbox in a variable. Here you can use a variable to store list of all mailboxes using Get-Content and then use ForEach loop

$mailboxname = "administrator@contoso.com"

# Connecting to Recoverable item folder of Archive mailbox. The list of all folders to which you can connect using EWS is available here.

$rfRootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]:: ArchiveRecoverableItemsRoot,$MailboxName)

$rfRootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$rfRootFolderID)

# Setting scope for EWS to process items

$fvFolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(10000);

$fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep

# Finding Sub folders in Recoverable items root of Archive mailbox (Deleted Items, Purges, Versions)

$ffResponse = $rfRootFolder.FindFolders($fvFolderView)

# Empty each folder

foreach ($folder in $ffResponse.Folders)

{

$Folder.Empty([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete, $true)

}

 

 

Again -- Please test it thoroughly before using it in your production environment.

 

Daya

 



This post is brought to you in a base64 encoded format by MSPFE editor Rhoderick Milne