Problem
Sometimes the “Sync Issues\Conflicts” folder for a user's email box accumulates hundreds of emails. In one case I found almost a thousand such emails that took up 5 GB. The only way I've found to delete items in a folder is to run a ComplianceSearch specifying a folderID and then run a Purge ComplianceSearchAction. Which is all fine and dandy except that Microsoft limits the number you can delete to only 10 at a time.
Solution
Keep running searches & purges against those searches (loop) so you can whittle away 10 at a time until you finally get rid of them all. You can't simply blindly iterate these or many might pile on top of each other without getting executed. So, for both the search and delete, keep checking to make sure each step is completed before proceeding to the next. We check every second and normally each search or purge takes 10 seconds. I think it takes longer if you have more items. The 10-second time is good for about 100 items in the folder. And sometimes this time can vary quite a bit; a search can take several minutes.
To use
This assume's you've already determined the "folderID" of the folder you want to clear out. see folder ID, find for every folder in a user's mailbox
$Timeout
=
"180"
# 3 minutes
$passes
=
10
# 10 passes translates into 100 items (10 passes x 10 deletes for each pass)
$startTime
= $(Get-Date)
for ($j=1;
$j
-le
$passes;
$j++)
{
"Begin pass $j
of
$passes"
$search = "folderid:5B836D697C629B4A788E989FE960E36900000050F84F0000"
$date = Get-Date -format "yyyy-MM-dd HH.mm.ss"
$person
=
"Some User"
$complianceSearchName = "$person $date"
New-ComplianceSearch -Name $complianceSearchName -ExchangeLocation all -ContentMatchQuery "$search"
Start-ComplianceSearch $complianceSearchName
# wait for the results
$searchCompleted
=
$false
$i
=
0
for
($i=0; $i
-le
$timeout
$i++) {
$theSearch
=
Get-ComplianceSearch
-Identity
"$complianceSearchName"
|
Format-List
-Property Status |
Out-String
$searchProgress
=
$theSearch
|
Select-String
-pattern&
"Completed"
if
($searchProgress.length
-gt
0) {
$searchCompleted
=
$true
$itemsFound
=(Get-ComplianceSearch
$complianceSearchName).Items
Write-Host
"The search returned
$itemsFound
items during search number
$j
of
$passes
in
$i
seconds."
if
((Get-ComplianceSearch
$complianceSearchName).Items -eq
0) {
"0 items found. Cleaning up and exiting..."
Remove-ComplianceSearch
-Identity
$complianceSearchName
-Confirm:$false
Exit
}
break
}
Sleep 1
"$i
seconds elapsed so far for search #$j
of
$passes"
}
if
($searchCompleted
-eq
$false) {
"Error: the search timed out"
Remove-ComplianceSearch
-Identity
$complianceSearchName
-Confirm:$false
Exit
}
# delete the emails
$purgeProgress
=
$null
New-ComplianceSearchAction
-SearchName
"$complianceSearchName"
-Purge& -PurgeType HardDelete |
Out-String
$ComplianceSearchActions
=
Get-ComplianceSearchAction
|
Out-String
$purgeProgress
=
$ComplianceSearchActions
|
Select-String
-Pattern
$complianceSearchName
# wait for the deletion results and delete the search if it is finished
for
($i=0;
$i
-le
$timeout
;
$i++) {
$thePurge
=
Get-ComplianceSearchAction
-Identity
$complianceSearchName"_Purge"
|
Out-String
$purgeProgress
=
$thePurge
|
Select-String
-Pattern
"Completed"
if
($purgeProgress.length
-gt
0) {
Write-Host
"Deletion $j
of
$passes
complete after
$i
seconds"
Remove-ComplianceSearch -Identity $complianceSearchName -Confirm:$false
Break
}
Sleep 1
"$i
seconds elapsed so far for deletion #$j
of
$passes
- working on
$itemsFound
items"
}
$elapsedTime
=
New-TimeSpan
$startTime
$(Get-Date)
Write-Host "Time elapsed (from beginning) for pass $j of $($passes): $($elapsedTime.ToString("hh\:mm\:ss")) - working on $itemsFound items" -ForegroundColor Green
}