If you are moving mailboxes to Office 365 from Exchange Server via Hybrid, then you should be following a tried and tested approach:
- Create a migration batch with the users you wish to migrate
- Start the migration batch, but don’t allow it to complete automatically
- Allow the batch to synchronize in advance of the migration date
- When the migration date arrives, complete the migration batch
Variations of this approach include setting the date and time to complete the batches, but ultimately this achieves two goals:
- Remove bandwidth challenges associated with trying to migrate batches of mailboxes from start to finish within a set migration window
- Remove uncertainty regarding when migrations will complete, especially with batches with a mix of mailbox sizes
Detaching the dependency on planning how many mailboxes you can move per night – and the worry (and reality) that mailbox moves will not always begin the moment you start a migration batch takes is crucial. Mailbox moves don’t necessarily all progress at the same rate or complete in the same duration. Influencing factors include not only the mailbox size, but the number of mailbox items, available bandwidth during the move and the load on Exchange Server and Exchange Online.
Additionally, because mailbox moves via Exchange Hybrid are performed as Online Moves, there is no user impact by pre-migrating mailboxes in advance. If you synchronize mailboxes a week before the date you plan to switch users to Exchange Online, then the only point that users will see any change is the point that you complete the migration batch. The initial sync and subsequent delta syncs are all performed in the background, and because Exchange processes move requests at low priority, mailbox moves in the background don’t affect user performance.
The challenge with completing mailbox batches synced in advance
Of course, things aren’t always as simple as scheduling a batch of mailboxes to synchronize two weeks before the completion date and then completing the batch.
You might, for example, find that some users need to be re-scheduled. Or, you might need to provide VIP support to executives and complete their mailbox moves at a time that suits them, not you.
This can present challenges with the number of batches you might need to create, as described in Mirela Buruiana’s post on the Exchange Team Blog.
Traditionally Exchange administrators who know Exchange well have by-passed this issue by using the *-MoveRequest cmdlets to manually complete mailboxes within Migration Batches. However, Migration Batches are not designed with this scenario in mind.
There is a better way – described in the above blog post – for moving synchronized mailboxes from one batch to another. This allows you to create a large batch for synchronization, and then complete smaller batches on-demand.
Creating larger migration batches for initial synchronization
Rather than wait until you face the challenge of having too many Migration Batches, create a number of large Migration Batches containing mailboxes you wish to pre-sync.
In our example, we’ll access the Exchange Admin Center and navigate to the Migration tab within Recipients. We’ll then choose the Add button and create a new migration batch in the normal manner – for simplicity, we’ll assume that Exchange Hybrid is setup correctly and a Migration Endpoint is present.
How to Migrate Exchange to Office 365: Step by Step
When we reach the page of the New Migration Batch wizard, we’ll ensure we choose the option Manually complete the batch:
This is because we don’t intend to complete this particular batch – or at the very least, we’ll expect to move some mailboxes out of the batch and complete them ahead of finalizing this batch.
As you’ll expect, some time will need to pass for your migration of mailboxes to complete. Once all mailboxes have synchronized, the status of the batch will update to Synced. You’ll see in the example below we’ve synced a large number (nearly 500) in our Pre-sync Mailboxes batch below:
Moving mailboxes to smaller batches for completion
If we now want to complete the migration for some of the mailboxes, we’ll need to connect to Exchange Online using PowerShell to create our smaller batch and move synchronized mailboxes into it.
We’ll need to know the Email Addresses of each mailbox we want to move, and then use the New-MigrationBatch cmdlet to achieve this. We’ll use a simple version of the New-MigrationBatch cmdlet using the following options:
New-MigrationBatch -Name <Batch Name> -UserIds <Comma-seperated list of email addresses> -DisableOnCopy -AutoStart
In our example, we’ll move TestMailbox10 to TestMailbox14 to our VIP Users 01 batch:
New-MigrationBatch -Name "VIP Users 01" -UserIds TestMailbox10@exchangelabs.co.uk,TestMailbox11@exchangelabs.co.uk,TestMailbox12@exchangelabs.co.uk,TestMailbox13@exchangelabs.co.uk,TestMailbox13@exchangelabs.co.uk,TestMailbox14@exchangelabs.co.uk -DisableOnCopy -AutoStart
You’ll see this in action below:
After creating the new Migration Batch, it will initiate a delta synchronization after copying mailbox identities into the batch.
If we revisit the Exchange Admin Center, we’ll see that we now have two Migration Batches.
The simplest approach now if you are using the Exchange Admin Center will be to choose Complete this migration batch:
And of course, we can use Exchange Online PowerShell to accomplish the same result:
Complete-MigrationBatch -Identity "VIP Users 01"
One issue you might notice is that in the original batch we now see failures:
We can examine the failures by selecting the batch and choosing View details. When we examine the failures, we’ll see this harmless error:
MigrationUserMovedToAnotherBatchException: The user was moved to a new batch
Whilst you can choose to safely ignore the error, you might want to clean up the batch by removing the mailboxes from this batch. To do so, select the mailboxes and then choose the Trash button, as shown below:
Large numbers of Migration Batches can be troublesome to manage, and often you will wish to complete particular mailbox moves at a different time to others within a synchronized batch. Use the approach here to plan for larger numbers of mailboxes in a smaller number of batches for initial synchronizations, then move mailboxes to smaller batches for a final delta sync and completion.
If you found this article useful, you may also be interested in Steve’s guide ‘How to Migrate Exchange to Office 365: Step by Step‘
I also had the error “A unique batch must be used when copying users from one batch to another.” going back to the Exchange blog article ( https://techcommunity.microsoft.com/t5/exchange-team-blog/the-100-migration-batches-limit-and-how-to-not-run-into-it/ba-p/609393 ) Mirela explains the users can only come from ONE pre-existing batch (plus users in no batch at all)
Aug 20 2019 08:37 AM
…. The error for the unique batch is because you were trying to combine batches, you can’t make users from different batches go into the same batch because we cannot copy settings from different source batches and make them into one target batch. In the blog example, I mentioned single, larger batch Batch_1 containing users A, B, C (all from the same batch).
Thank you for this post. I know I used this article this year. but when I tried this today i am getting the error below. do i need to add any other switches?
New-MigrationBatch -Name mig09222021-B -UserIds PERSON@DOMAIN.com -DisableOnCopy -AutoStart
Parameter set cannot be resolved using the specified named parameters.
+ CategoryInfo : InvalidArgument: (:) [New-MigrationBatch], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,New-MigrationBatch
+ PSComputerName : outlook.office365.com
Is it possible to migrate mailboxes from O365 to on-prem using the PowerShell ‘NewMoveRequest’ commands? I need to pull these back down to on-prem before disconnecting for migration to other organisations. I know i can do this in the Exchange Admin Center, but need to be able to do it from a PS1 script so I can share with other admins.
I am about to begin a new migration. I have done several before but didn’t know about this or even thought outside of the box if this was possible. I am going to definitely try it with my Pilot group first and if successful move on from there. I absolutely love the idea of syncing large batches days/weeks in advance to get that out of the way. Then focus on smaller batches when you know 95% of their mail has been copied over and a delta sync just to occur. Thanks for the information an I will report back in few weeks when I am in the meat of my migration to let you know how it goes. Thank you for being a valued MSP to the community. – Ron
So I am near the completion of my migration and this process definitely helped out, however like Todd experienced, I could not extract out more than one user into a batch? If I attempted more than 1 it would error with “A unique batch must be used when copying users from one batch to another”.
So it was nice to extract out users from large batches that had already synced, however I had to create single new batches for each users. Not exactly that difficult, but obviously more time consuming and cycles spent to do that. With that said, I will keep this one in the tool bag as it is great to sync up large batches days/weeks in advance then when ready to actually migrate mailboxes in smaller batches based on clustering of shared mailboxes/users, shared calendars, etc. to migrate at the same time if applicable.
All in all, appreciate the article and will definitely use this trick going forward!
In the testing phase I did not receive this error – And I was able to move multiple users from one batch to another. Now I am getting this error. Did Microsoft change something do you know? I have a Premier case open so I’ll see what they say. Makes no sense, it worked before!!!
Just ran in to this recently and did not see an answer posted, so I thought I would share.
If you have more than one source batch, you can only move mailboxes from one batch to a new batch. So you need to separate the move lists by source batch. I had 4 batches so I had to go through the process 4 times to hold the mailboxes that could not be moved on my planned completion day.
Thanks for this article!
Is there a way to create the new, smaller batches, using a list instead of entering each mailbox name one by one?
I followed your guide and moved 5 of our IT Service Desk users to a priority batch.
All these users seem to have a problem, their deleted mail items keep reappearing in their inbox at around 16:30 each day.
This problem isn’t evident for users who have been moved over in their main batch.
Have you any idea what could be going on ? We deleted the affected batch after completion and ensured that those users were removed from their original batch. We’ve contacted MS support but have come up empty so far.
I’ve run some powershell and confirmed that these users are no longer migration users.
Is there a way to identify mailboxes that need to be resynchronized and have already been removed from migration batches?
If a mailbox is synced, can it be deleted from it’s current batch and then added to a new unsynced batch of mailboxes?
Currently we copy synced users to a new batch for completion. Just wanted to delete them instead and then add them a new migration batch with unsynced users.
Hope that makes sense.
Does completing a batch perform a delta sync before actually cutover the mailbox? (Let’s say batch is synced to weeks ago, and now we want to complete it)
Yes, it will perform a delta sync every day and then when you complete the migration it will lock the mailbox briefly and perform a final delta sync.
Any way I can increase the rate of delta sync from once every 24 hours?
No, it isn’t customizable
Can mailboxes which have failed to synchronize successfully be completed without re-mediating the corruptfolderACL item.
I believe you’ll need to restart the migration for the mailbox but you can remove single mailboxes from the batch
Gold, thank you Steve!
Re the other guff.. ITs all so connected.. where does one stop.. am just so glad to know these commands work to move mailboxes between batches.. and that generally, you’ve had good mileage with them in the field. Thanks for sharing!
A great article, thanks.
I am wondering what the issue is with using autocomplete? Is it just the convenience of narrowing down the time to complete the migration? I am guessing it is only the VIP list that want to be hand held to reattach Email to their phones?
Would you use autocomplete for standard users, calendars, and shared mailboxes? Won’t Exchange just auto complete each mailbox in the migration batch after it is synced. If we set a migration limit of say 20, it will keep migrating up to 20 at one time until the whole batch is finished, will it not? For a user on a PC, as their mailbox completes Outlook just pops up a message asking them close and reopen Outlook.
I would always recommend keeping user disruption to a minimum, so if we can choose when migrations complete, rather than they simply complete when they are ready we will have a better experience.
There are factors like ensuring that people who share calendars with each other move at the same time and so on which are important for the way people use Exchange and in general we want to move people who share together at the same time.
I would personally suggest switching out of hours for big batches of users so that they simply launch Outlook and (with Modern Auth, modern clients etc) everything continues to work; and their colleagues are moved at the same time.
What we can do is schedule the completion though / use CompleteAfter – in that case we can say – let’s wait until the batch is done, then complete the batch automatically at say, 3AM. That should give the best of both worlds.
If I’ve read this few years ago, I would have saved myself a few hundred migration batches!!
Great article, and very timely too! Thanks 🙂
Though I appreciate this article for what it outlines as a possible “godsend”, I have experienced nothing but frustration with attempting to implement.
First… I am unable to segregate more than one (and if lucky two) email addresses to a new batch for isolated completion. More than one or two email addresses ends up throwing an error. Attempts to use CSVData doesn’t work either.
Second… Why this way? Are we only looking to provide a way to send a notification?
Third… Using “Set-MoveRequest” or “Set-MigrationUser” with the “CompleteAfter” switch has been far more reliable. Though I don’t receive completion notifications, that’s really not all that important to me when I can monitor completions via PowerShell.
Steve, I appreciate all you do for the community, but this article has not been vetted and is a hard pass for me.
I appreciate you messaged me because you wanted to use a variation of the technique for an in-progress migration you were struggling with.
However, I do disagree that it “has not been vetted” – the purpose of this article is primarily to draw attention to a technique disclosed in the Microsoft Exchange Team Blog, which I’ve linked to in the article.
Unfortunately as it’s not documented widely using variations of the technique are unlikely to be supported.
And, using Set-MoveRequest as you mentioned above *is* unsupported and therefore whilst it is known to work, can’t be recommended.
What I’ve posted about here is a technique that is supported by Microsoft and therefore can be recommended. Not only that, I’ve tested it myself (and provided updates to Microsoft to update the original article) before posting it here.
I know you have insider connections, but I spoke with several engineers at MS as well (albeit in support) about this recently and while they feel your article in theory would work, it simply does not beyond isolating 1 or at most 2 mailboxes from an existing batch to a new batch.
I’ve made attempts to work through this article daily for a week and could not get your solution to work reliably or effectively or efficiently.
Which “technique disclosed in the Microsoft Exchange Team Blog, which I’ve linked to in the article” are you referring to? The one about the max number of batches or the one about how to connect to EXO via PowerShell or the one that is a non-MS source ?
Regarding the “unsupported” comment for Set-MoveRequest, please provide the MS reference that states this.
While I do not doubt your solution works in a small and canned environment, this doesn’t seem to work for a production environment with 8000+ global mailboxes synced over 40 batches. But not that it should matter, right?
And while I would like to believe synced mailboxes “Remove bandwidth challenges”, this simply isn’t an accurate assumption. It is dependent on the time of the daily sync and the amount of changes across every mailbox in the org.
Additionally, your statement in a comment below “we can choose when migrations complete” isn’t accurate either. We can choose when the migrations are scheduled to begin the completion process however, we cannot choose when they complete. That is all dependent on several factors … location of mailbox, size of mailbox, changes to mailbox, connectivity, etc. etc. etc. I know this because there are several mailboxes I have batched that are all the same size, synced, and while some had completed relatively quickly others still took several hours or days to complete.
If there are other caveats or requirements or tricks that are needed for your solution to work as documented please provide details on the environment you had set up.
I don’t disagree with the specifics of some of your points above, but naturally it’s important to get the point across in the fewest number of words so it’s useful to most people.
And, the nature of blogging about solutions is not to solve it for everyone, but instead to share our knowledge of what we’ve used in the real world. Certainly here I am intending to share solutions that are supported by Microsoft.
If you find a better technique, that is supported by Microsoft, please do feel free to share it as an article- we always welcome new writers on the site.
This is a godsend and something I’ve been trying to figure out how to do forever. My only regret is not having this process sooner.