Powershell – Identifying mailboxes with corruption Exchange 2013

exchange-2013microsoft-office-365powershell

We're preparing to rid ourselves of Exchange on-premise and are migrating from an outsourced hosting provider to go to Office 365. We're running a fully patched version of Exchange 2013, atop Server 2012, also fully patched.

During the migration of test mailboxes we found that many mailboxes across multiple databases are corrupted. More information about the cause can be found HERE. Essentially: the SAN which stores our Exchange VM is oversubscribed and routinely has I/O wait in excess of 5 seconds, and sustained read speeds rarely pass 500KBps.

The slow speeds would be enough to cause significant wasted time during the migration, but when mailboxes with corruption are encountered, migrating 1GB of data goes from a 2-3 hour affair to a 10-20 hour one. Each of the mailboxes that have issues (that I've found so far) give messages similar to the below when checked against get-mailboxstatistics:

WARNING: The object <GUID> has been corrupted, and it's in an inconsistent state. The following validation errors happened:
WARNING: Cannot extract the property value of 'DeletedItemCount'. Source: PropTag(DeletedMsgCount), PropType(Int), RawValue(-2), RawValueType(System.Int32). Target:
Type(System.Nullable`1[System.UInt32]), IsMultiValued(False). Error Details: <n/a>

Running New-MailboxRepairRequest against all databases identified some corruption and repaired it, but not all of it. I can't seem to find a way to get Get-MailboxStatistics to log the fact that there is something broken in each of these mailboxes, though I'm sure there is one. Moving mailboxes from one database to another seems to fix the problem. We've got ~50 DBs, and about 50 users per DB, so going through this manually is out.

What I want to do is, via PowerShell (excuse lazy pseudo code please):

foreach ($mailbox in $database){
    if get-mailboxstatisics -eq $corrupted {
        move $mailbox to $otherdb
        wait
        move $mailbox back to $database}
    }

However, I can't figure out how to catch the "Warning: this is broken" text from Get-MailboxStatistics, and the resultant object returned doesn't have anything in it that shows it's broken.

Do I just need to catch the warning and assume everything that complains about inconsistencies can be fixed this way, then go back and check the list of mailboxes that actually have an issue after they've been moved out and back to see if things are still broken? Is there a better way to do what I need to do?

Replacing the SAN is out of the realm of possibilities, so is fixing any other underlying causes.

Best Answer

To isolate the messages from existing PowerShell cmdlets you can use

Warning Variable Most default cmdlets have the -WarningVariable parameter available, you can combine this with -WarningAction SilentlyContinue to suppress the warning and store it's output into the variable, which can then be manipulated or displayed however you like. So you could run this

$mailbox | Get-MailboxStatistics -WarningAction SilentlyContinue -WarningVariable MyWarning;
if($MyWarning -like '*corrupted*'){
  Write-Host "possible corruption";
}

I tried to replicate a warning event to doulbe check the above but could not thru the MailboxStats cmdlet. Above should work - but it's untested in this context.

Related Topic