An Exchange administrator can move user mailboxes between databases on the same server or between remote mailbox servers. In this article we’ll show how to move mailboxes in Exchange Server using the Exchange Admin Center (EAC) and PowerShell. The article is relevant for all supported versions of Exchange 2010/2013/2016/2019 with some differences regarding the Exchange Management GUI.
Typically, corporate mailboxes in an Exchange organization are migrated if a user moved to another site (office) with their own Exchange mailbox servers; when the disk space where the current database is stored runs out; or when you want to perform an offline defragmentation of the database without interrupting the email service for users.Note that moving or deleting a mailbox doesn’t reduce the mailbox database size on a disk, it only frees some space in the database (white space
). This free space can be used to store new mailbox items for other users in the same database. To reduce the size of the Exchange database, you have either to defragment it offline or simply recreate it (move users to other databases in advance).
To move a mailbox from a database to another one, you need to create an Exchange move request. There are three types of move requests:
Using the Exchange Admin Center, you can move one or more user mailboxes.
I don’t use the EAC mailbox moving features, since it is easier and faster to do it with PowerShell.
First of all, you need to get the mailbox database that stores the user’s mailbox. Open the Exchange Management Shell (EMS) and run this command:
Get-Mailbox jkurtin| Format-List Database
In this example, a user’s mailbox is located in the database named DB01.
To create a local request to move a mailbox, the New-MoveRequest cmdlet is used. For example:
New-MoveRequest -Identity jkurtin -TargetDatabase "DB02" –BadItemLimit 10
Besides a username, the following parameters are important:
The cmdlet returns the mailbox and archive sizes (TotalMailboxSize, TotalArchiveSize) and a message that the move request has been queued.
To move all mailboxes from an Exchange database to another one, use the following command:
Get-Mailbox -Database DB01 -ResultSize Unlimited | New-MoveRequest -TargetDatabase DB02
Note that the Arbitration option must be used to move system mailboxes:
Get-Mailbox -Database DB01 -Arbitration | New-MoveRequest -TargetDatabase DB02
You can change mailbox migration settings in the configuration file MSExchangeMailboxReplication.exe.config (C:\Program Files\Microsoft\Exchange Server\V15\Bin). For example, you can increase the number of simultaneous move request operations supported for a mailbox database or a mailbox server. These are the following options: MaxActiveMovesPerSourceMDB
, MaxActiveMovesPerTargetMDB
, MaxActiveMovesPerSourceServer
, MaxActiveMovesPerTargetServer
.
Depending on the mailbox size and the location of a target server, it may take a long time to move a mailbox. To track the mailbox migration status in %, the Get-MoveRequestStatistics cmdlet is used.
Get-MoveRequestStatistics -Identity jkurtin
In this example, the move status is InProgress, and the progress (PercentComplete) is 26%.
You can display the status of all mailbox move requests in the organization:
Get-MoveRequest | Get-MoveRequestStatistics
After the migration is over, the PercentComplete value reaches 100, and the migration status will change to Completed.
You can display statistics on pending move request transfers only:
Get-MoveRequest | where {$_.status -ne "completed"} | Get-MoveRequestStatistics | ft -a displayname,status*,percent
To display all mailboxes that are being moved or queued:
Get-MoveRequest -movestatus inprogress
Get-MoveRequest -movestatus queued
If an error occurred during the mailbox migration, you can display it using this command:
Get-MoveRequest jkurtin | Get-MoveRequestStatistics | fl *failure*, message
To get more detailed information about mailbox migration errors, use the following command:
Get-MoveRequest -resultsize unlimited | Where-Object {$_.status -like “failed”} | Get-MoveRequestStatistics -IncludeReport | select DisplayName, Message, FailureType, FailureSide, FailureTimeStamp, *bad*, *large*, Report, Identity | fl
If you want to cancel a mailbox move, run:
Remove-MoveRequest -Identity jkurtin
To remove successfully completed move requests (you won’t be able to move a mailbox next time without it), run the command:
Get-MoveRequest -MoveStatus Completed | Remove-MoveRequest
To make tracking mailbox migration more convenient, you may use the –BatchName option. For example, to move all mailboxes from a mailbox database to another one in batch mode, run the following command:
Get-Mailbox -Database RO-DB01 | New-MoveRequest -TargetDatabase RO-DB02 -BatchName RODB01toRoDB02Move20210422
Then to get a migration status of all mailboxes in the batch, specify the batch name:
Get-MoveRequest -BatchName RODB01toRoDB02Move20210422| Get-MoveRequestStatistics
Thus, you can make sure that all mailboxes in the task have been successfully moved.
You can suspend a batch mailbox migration:
Get-MoveRequest | ? {$_.Batchname –like “*RODB01toRoDB02Move20210422”}|Set-MoveRequest –SuspendWhenReadytoCompleate
Or resume the migration:
Get-MoveRequest | ? {$_.Batchname –like “*RODB01toRoDB02Move20210422”|Resume-MoveRequest
In Exchange Server 2013, 2016, 2019 and Exchange Online, you can move multiple mailboxes in a batch using the New-MigrationBatch. Make a list of mailboxes to be migrated in a CSV file, and use this command:
New-MigrationBatch -Local -AutoStart -AutoComplete -Name RODB01Move20210422 -CSVData ([System.IO.File]::ReadAllBytes("C:\PS\RODB01Move20210422.csv")) -TargetDatabases RO-DB03 -BadItemLimit 10
To move only the primary mailbox, use the PrimaryOnly
option; to move an archive mailbox, use ArchiveOnly
.