Code Blog

Displaying 1-1 of 1 result.
2017/05/27 Windows Server

Recently I had to dig into a crashed Exchange 2010 server and try to restore the mailboxes. Luckily the local Active Directory was still working fine, as this helps a lot because Exchange stores a lot of data in AD (database schema, mailbox settings, mailbox accounts etc). After installing Exchange and have it join the local domain, all the settings from the old Exchange installation are fetched from AD.

For restoring the mailboxes I had a copy of the Exchange database file (the .edb file) but as Exchange 2010 writes log files for each transaction it means that a server crash most likely results in a "dirty state", and this was true for my copy as well. The first thing to do is to use a command line tool (ESEUTIL) to check the state and write the logs to the database and put it in a "clean shutdown" state if necessary. However, even after putting it in a clean state, a .edb-file can't be mounted directly to another exchange-installation. It has to be mounted as a temporary "recovery database" and then the mailboxes can be transfered over to the new .edb-database of the exchange server. This turned out to be quite difficult. The transfers throw a lot of errors (had to set the "BadItemLimit" parameter very high) and some still just completely refused to be moved across.

I had errors such as "MapiExceptionInvalidParameter: Unable to modify table." etc. This only happened for some mailboxes (I think about half failed) and other posts online said that this may be caused by some users creating non-standard rules and folders for how to seperate incoming email. One solution is to only recover i.e. "Inbox" folder and skip the rest. Didn't seem like the ideal solution to me.

Here are some examples of restoring from the recovery database (RDB) to the new Exchange database:

New-MailboxRestoreRequest -SourceDatabase "RDB" -SourceStoreMailbox "Username" -TargetMailbox "Username" -AllowLegacyDNMismatch -ExcludeDumpster -BadItemLimit 100 -AcceptLargeDataLoss -AssociatedMessagesCopyOption copy -IncludeFolders "#Inbox#"
New-MailboxRestoreRequest -SourceDatabase "RDB" -SourceStoreMailbox "Firstname Lastname" -TargetMailbox [email protected]

Maybe because of some changes done in AD I had to use the "AllowLegacyDNMismatch" flag for it to work. 

Next step was to try to use the "Restore-Mailbox" command instead of "New-MailboxRestoreRequest". "Restore-Mailbox" is actually an older command that has been replaced by "New-MailboxRestoreRequest". 

Restore-Mailbox -Identity Username -RecoveryDatabase RDB -RecoveryMailbox Username -TargetFolder Recovered

The "Restore-Mailbox" worked better than "New-MailboxRestoreRequest" but I could still not restore all mailboxes (finally I had 5 mailboxes still not restored). In the end the best solution was to do a hardware repair of the old server, boot it up, export all mailboxes via command line to .pst files, and then transfer them over to the new Exchange and import them into user mailboxes. This worked for all mailboxes. The only problem was a quota restriction that I had to adjust for some mailboxes (they were bigger than the max allowed size).

Import from .pst file to a user mailbox and check progress status:

New-MailboxImportRequest -FilePath \\exchange\pst\username.pst -Mailbox [email protected]
Get-MailboxImportRequest | Get-MailboxImportRequestStatistics

Remove finished requests from the queue:

Get-MailboxImportRequest -status Completed | Remove-MailboxImportRequest

Here's a good article I found online about Exchange mailbox recovery: 

One way to prevent this type of problems in the future are to run several Exchange servers in a database availability group (DAG). The Exchange database will be continuously replicated among the servers. Another tip is to create several .edb databases and limit the amount of users for each database. In this way, if (or rather when) a database becomes corrupt, it will make the workload much more managable for restoring mailboxes from a backup.