Exchange 2013 Local Mailbox Moves (Part 3)

If you would like to read the other parts of this article series please go to:

Batch Move Request – Shell

In the first part of this article series, we saw how to use the New-MoveRequest cmdlet to move one or more mailboxes, just like in Exchange 2010. Now, let’s look at the new New-MigrationBatch cmdlet which is used to submit a new migration request for a batch of mailboxes. This cmdlet can be used to perform Local, Cross-Forest or Remote mailbox moves as discussed previously.

Once the request is created, the migration batch must be started manually by running the Start-MigrationBatch cmdlet or by using the EAC. Another alternative is to use the -AutoStart parameter to start it immediately. This allows administrators to create batch of moves during the day that they can easily start during the night. Obviously this can be achieved using the New-MoveRequest, but the new cmdlet makes the process a little bit easier.

Unlike the New-MoveRequest cmdlet which uses the TargetDatabase and TargetArchiveDatabase parameters, the New-MigrationBatch uses TargetDatabases and TargetArchiveDatabases which allows us to specify more than one database to move mailboxes to. If these parameters are not used, Exchange will use the automatic mailbox distribution logic to select target databases, just like with the New-MoveRequest cmdlet.

This is a good improvement as it allows administrators to use the mailbox provisioning load balancer with selected databases without having to first exclude from provisioning databases they do not wish to be used.

Besides these two parameters and the usual PrimaryOnly and ArchiveOnly which allows us to move the primary and archive mailboxes together or separately, there are also other important ones to consider:

  • AutoStart specifies whether to immediately start processing the new migration batch. If you don’t use the AutoStart parameter, you have to manually start the migration batch by using the Start-MigrationBatch cmdlet or the EAC;
  • AutoComplete specifies whether to force the finalization of the individual mailboxes in a migration batch when the initial synchronization for a mailbox is successfully completed. If you don’t use this parameter, you have to run the Complete-MigrationBatch cmdlet afterwards, or use the EAC, in order to finalize the migration batch. Note that this parameter can only be used for local moves and remote move migrations;
  • AllowIncrementalSyncs allows for incremental synchronization, during which the source and target mailboxes are synchronized every 24 hours. Any new messages sent to the source mailbox are copied to the corresponding target mailbox. This is enabled by default;
  • AutoRetryCount specifies the number of attempts to restart the migration batch to migrate mailboxes that encountered errors;
  • Local specifies a local move where mailboxes are moved to a different database within the same forest;
  • NotificationEmails specifies one or more email addresses that the migration status report is sent to;
  • CSVData specifies the CSV file that contains the mailboxes to be moved or migrated. For a local move, the CSV file must have a header named EmailAddress. Use the following format for the value of this parameter: ([System.IO.File]::ReadAllBytes(<CSV file path>)).

The CSVData parameter is mandatory! This means you cannot use the same methods as with New-MoveRequest cmdlet to move multiple mailboxes in one command…

So let’s move a few mailboxes! For this test I decided to move 600 mailboxes from one database to two other databases with a total of almost 7GB of data. In this group of mailboxes, the average mailbox size is 11.5MB; the smallest is 7MB in size with 500 e-mails; and the biggest is 136MB with 1500 e-mails.

First, we create the CSV file with the EmailAddress header and with the e-mail addresses of all the mailboxes we want to move:    

Figure 3.1: Mailboxes to Move – CSV File

Next we create the migration batch. In this case I am moving mailboxes to two databases, automatically starting and completing the move, retrying 3 times any failed mailbox moves and setting the locale to English so we don’t get the final report in Portuguese 🙂

Figure 3.2:
New Migration Batch

If for some reason we need to stop the migration batch, this can be done using the Stop-MigrationBatch cmdlet. In the example below we see that the migration batch is running (status of Syncing); once it is in the Stopped state, it can be removed:

Figure 3.3:
Stopping and Removing Migration Batch

If we don’t stop it and proceed with the move, we can keep an eye on its progress using several cmdlets. Two of them are the Get-MigrationUser and Get-MigrationUserStatistics, which gives us details regarding the move and migration requests. We can also use them to get details on failed moves. At this stage, mailboxes are not being moved yet.

Figure 3.4:
Migration Statistics (1)

After Exchange validates a mailbox can be moved, a move request for each mailbox is created. Once this happens, we can use the usual Get-MoveRequest and Get-MoveRequestStatistics cmdlets to get further details on the actual move process. On the screen below we can see another useful cmdlet, the Get-MigrationStatistics which shows the overall progress of the whole batch move:

Figure 3.5:
Migration Statistics (2)

Similar to what we have seen a couple of times before, we can also track all the progress of the move using the EAC:

Figure 3.6:
Migration Statistics – EAC

Note that the reason why there are no mailboxes under SYNCED is because we used the AutoComplete parameter and, therefore, Exchange finishes the mailbox move as soon as all its data has been copied across. If the AutoComplete parameter had not been used, then mailboxes would remain in the SYNCED state until we issued the Complete-MigrationBatch cmdlet or completed the migration through the EAC.

We can also check how far in the queue a mailbox is from starting to get moved. To check this, we use the Get-MoveRequestStatistics cmdlet:

Figure 3.7:
Mailbox Queue Position

Unfortunately simply creating a batch move will not establish to which database each mailbox will be moved, this is only determined when the actual move request command is issued. Therefore, we can only check this after the batch has started and mailboxes passed the Validating state:

Figure 3.8:
Mailbox Distribution

After the move is finally complete, a few statistics regarding the target databases show that Exchange did a good job spreading the mailboxes across both databases. Although there is a 20% difference in the database size, the number of users and number of items is close (note that Exchange picks a random database, it doesn’t look at the number of items or mailbox size):

Figure 3.9:
Mailbox Database Statistics


To be honest, for local mailbox moves, the new New-MigrationBatch cmdlet doesn’t bring many benefits. Sure it can make it slightly easier to pre-stage moves without actually performing them, but I never had any problem scheduling mailbox moves to run in the middle of the night in Exchange 2007 or 2010. The new migration report is a great addition but, as we saw, still has a lot of room for improvement.

Where this feature brings most of its benefits is in moving mailbox data to/from Exchange Online or to perform an IMAP migration, making these migrations much easier.

In this article we talked about how to perform local mailbox moves in Exchange 2013 and the improvements made to these.

If you would like to read the other parts of this article series please go to:


About The Author

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top