Insane PowerShell One-Liner to Return the Name of Users with Quarantined Mailboxes in Exchange 2010

Have you ever had any mailboxes on your Exchange 2010 server marked as being quarantined? According to this Microsoft article, Exchange will isolate or quarantine any mailboxes that it detects as being poisoned. That TechNet article goes on to tell you how you can drill down in the registry on the Exchange Server to locate the GUID of the quarantined mailboxes. I don't know about you but using the GUI to dig around in the registry is not what I call fun so I decided to use PowerShell to accomplish that task.

If you're not running this from the Exchange Management Shell, you'll first need to load the Exchange 2010 PowerShell Snapin:

1Add-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue

Here's an insane PowerShell one liner that will do that dirty work for you and translate the GUID's that are contained in the registry to the actual name of the user's mailbox:

1Get-ChildItem -Path HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeIS\$env:COMPUTERNAME\ |
2Where-Object {$_.pschildname -ne 'logstate' -and $_.pschildname -notlike 'public*'} |
3Select-Object -ExpandProperty pschildname |
4ForEach-Object {
5    Get-ChildItem -Path HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeIS\$Env:COMPUTERNAME\$_\QuarantinedMailboxes |
6    Select-Object -ExpandProperty pschildname |
7    Get-Mailbox |
8    Select-Object -Property name
9}

quarantined-mailbox-oneliner.png

As the previously referenced Microsoft article states, these mailboxes are quarantined for a certain amount of time so these registry keys will only contain a value for a specific amount of time (six hours by default or whatever MailboxQuarantineDurationInSeconds is set to).

If the one liner is too insane for you, here's a PowerShell script that does the same thing except it sends an email to you with the results if there are any:

 1Add-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue
 2
 3$databases = Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeIS\$env:COMPUTERNAME\ |
 4             Where-Object {$_.pschildname -ne 'logstate' -and $_.pschildname -notlike 'public*'} |
 5             Select-Object -ExpandProperty pschildname
 6
 7$corruptmailboxes = @()
 8
 9foreach ($database in $databases) {
10    $corruptmailboxes += Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeIS\$Env:COMPUTERNAME\$database\QuarantinedMailboxes |
11                         Select-Object -ExpandProperty pschildname |
12                         Get-Mailbox |
13                         Select-Object -ExpandProperty name
14}
15
16if ($corruptmailboxes -ne $null) {
17    Send-MailMessage -Body ($corruptmailboxes | Out-String) -Subject "Quarantined Mailbox Report via PowerShell" -From exchange@mikefrobbins.local -To me@mikefrobbins.local -SmtpServer mail.mikefrobbins.local
18}

µ