PowerShell – auxiliary script to populate CustomAttribute10 with a Purged Items FolderID

Originally this script ( New-ComplianceSearch script ) would search through Purged Items. That was the downside of it comparing to a “classic” Search-Mailbox you can find here ( Search-Mailbox script ).

So imagine you run the script the 1st time, find target messages, and then delete them – the found results make sense. However, should you run the script the 2nd time with the same search criteria, it would find those already purged messages again. That creates some confusion.

So it would be great to exclude Purged Items folders from the search. Now, it is possible to do so on the fly ( https://docs.microsoft.com/en-us/microsoft-365/compliance/use-content-search-for-targeted-collections ) but it is very time consuming and takes about 1-3 seconds for each mailbox which stacks up pretty fast.

So I came up with a script to take care of this issue by storing a Purged Items FolderID in a CustomAttribute10 of each mailbox.

So this script does the following:

  • finds all mailboxes;
  • filters those where CustomAttribute10 is blank;
  • calculates and populates CustomAttribute10;
  • does it for both AD synced and Cloud mailboxes / users.

This script must ‘Run As’ an account that has access to edit AD.

$elapsed = [System.Diagnostics.Stopwatch]::StartNew()

$allmailboxes = get-mailbox -ResultSize unlimited

$syncedmailboxes = $allmailboxes | Where-Object {$_.IsDirSynced -eq $true -and $_.CustomAttribute10 -eq ""} 

$cloudmailboxes = $allmailboxes | Where-Object {$_.IsDirSynced -eq $false -and $_.CustomAttribute10 -eq ""}

If ($cloudmailboxes.Length -ne 0) {
	Write-Host "Adding 'Purged Items' FolderID to CustomAttribute10 to these 'Cloud Accounts':" -ForegroundColor Green
}

Else {
	Write-Host "There are no 'Cloud Accounts' without prepopulated CustomAttribute10" -ForegroundColor Yellow
}

foreach ($cloudmailbox in $cloudmailboxes) {
	
	$folderStatistic = get-mailbox -Identity $cloudmailbox.PrimarySMTPAddress | Get-MailboxFolderStatistics | Where-Object {$_.Name -eq "Purges"}
	$folderId = $folderStatistic.FolderId;
	$encoding= [System.Text.Encoding]::GetEncoding("us-ascii")
	$nibbler= $encoding.GetBytes("0123456789ABCDEF");
	$folderIdBytes = [Convert]::FromBase64String($folderId);
	$indexIdBytes = New-Object byte[] 48;
	$indexIdIdx=0;
	$folderIdBytes | select -skip 23 -First 24 | %{$indexIdBytes[$indexIdIdx++]=$nibbler[$_ -shr 4];$indexIdBytes[$indexIdIdx++]=$nibbler[$_ -band 0xF]}
	$folderQuery = "folderid:$($encoding.GetString($indexIdBytes))";
	$folderStat = New-Object PSObject
	Add-Member -InputObject $folderStat -MemberType NoteProperty -Name Name -Value $cloudmailbox.DisplayName
	Add-Member -InputObject $folderStat -MemberType NoteProperty -Name Email -Value $cloudmailbox.PrimarySmtpAddress
	Add-Member -InputObject $folderStat -MemberType NoteProperty -Name ShortName -Value $cloudmailbox.PrimarySmtpAddress.Substring(0,$cloudmailbox.PrimarySmtpAddress.IndexOf("@"))
	$folderStat
	Set-Mailbox -Identity $folderStat.Email -CustomAttribute10 $folderQuery
}

Write-Host `n

If ($syncedmailboxes.Length -ne 0) {
	Write-Host "Adding 'Purged Items' FolderID to CustomAttribute10 to these 'Synced to AD Accounts':" -ForegroundColor Green
}

Else {
	Write-Host "There are no 'Synced to AD Accounts' without prepopulated CustomAttribute10" -ForegroundColor Yellow
}

foreach ($syncedmailbox in $syncedmailboxes) {
	
	$folderStatistic = get-mailbox -Identity $syncedmailbox.PrimarySMTPAddress | Get-MailboxFolderStatistics | Where-Object {$_.Name -eq "Purges"}
	$folderId = $folderStatistic.FolderId;
	$encoding= [System.Text.Encoding]::GetEncoding("us-ascii")
	$nibbler= $encoding.GetBytes("0123456789ABCDEF");
	$folderIdBytes = [Convert]::FromBase64String($folderId);
	$indexIdBytes = New-Object byte[] 48;
	$indexIdIdx=0;
	$folderIdBytes | select -skip 23 -First 24 | %{$indexIdBytes[$indexIdIdx++]=$nibbler[$_ -shr 4];$indexIdBytes[$indexIdIdx++]=$nibbler[$_ -band 0xF]}
	$folderQuery = "folderid:$($encoding.GetString($indexIdBytes))";
	$folderStat = New-Object PSObject
	Add-Member -InputObject $folderStat -MemberType NoteProperty -Name Name -Value $syncedmailbox.DisplayName
	Add-Member -InputObject $folderStat -MemberType NoteProperty -Name Email -Value $syncedmailbox.PrimarySmtpAddress
	Add-Member -InputObject $folderStat -MemberType NoteProperty -Name ShortName -Value $syncedmailbox.PrimarySmtpAddress.Substring(0,$syncedmailbox.PrimarySmtpAddress.IndexOf("@"))
	$folderStat
	Set-ADUser -Identity $folderStat.ShortName -Replace @{ExtensionAttribute10=$folderQuery}
}

Write-Host "Total Time: $($elapsed.Elapsed.ToString())"

Leave a Reply