An interesting topic again, debating whether the free native tools that are available to migrate the Exchange Online workload in Microsoft 365 are good enough to use. Should we be using a ‘paid’ migration tool to perform the work. Well this totally depends on how much effort you want to put in to controlling the migration. What I have created here is a full end to end migration video showing exactly how you would perform this migration using nothing but the tools that Microsoft provide. Plus a load of PowerShell to make it all work.
UPDATE : 17 March 2023
Very pleased to tell you that the ‘edited’ video is now available on the You Tube channel. All the PII data has been blurred out which takes care of the violation. Thank you to everybody that has emailed regarding this, I appreciate all your supportive comments. The new link is in the article below.
UPDATE : 12 March 2023
My apologies that the video isn’t currently viewable. It got pinged on the weekend as violating Cyber Bullying and Harassment policies! That was because it had PII (Personal Identifiable Information) in the video. Yes, all the dummy/test user accounts that I use were picked up by the Google AI as violating that policy! I am working on a replacement that has all the information blurred out to satisfy Google requirements. I will post an update here when this is all done. I do fully support Google for making sure all videos adhere to the correct community guidelines and clearly cyber bullying and harassment is a very real problem on the internet. Please drop me a note to mark@thecloudgeezer.com in the meantime if you had any questions to ask.
From this you can decide which path you want to go down for your Microsoft 365 migration.
What is covered in the video though is;
- Setup of the Security Group needed to scope the migration
- Configuration of the App Registrations required in the Tenants to allow the connections
- Organization Relationship setup
- Creation of Mail Users to prepare the target
- Stamping of the objects with the Exchange GUID’s to bind the identities
- Creation of the migration batches
- Syncing and Completing the migration batches
- Forwarding and Mail Routing for both source/target accounts pre/post migration
- Moving the underlying domain name from one tenant to another
- Adding aliases to the new tenant
As you would expect in the content, I don’t edit out any of the errors that may occur but I choose to fix them in front of you so you can see what really happens in these situations. This is a real world migration extending the series I have using the planeium.com tenant. In this episode they have purchased another company, zeotrobe.com, and have chosen to consume the Exchange Online workload into the Planeium tenant rather than try and manage two. This scenario is common and although I only have a small number of users, the process can be used for hundreds or thousands if necessary.
Please remember to subscribe to the channel, I very much appreciate it.
https://youtube.com/thecloudgeezer?sub_confirmation=1
Here is the video, then read down further as I copy/paste all the PowerShell commands I used in the recording to make it easy for you to reuse it.
Mark – The Cloud Geezer
PowerShell from the Video
All these commands I have listed are meant as a ‘companion guide’ to the video. Don’t just go and run them all in your tenant without watching the context that you need them in the video. I put them here so they are easy to copy/paste and modify in your own system.
Make sure that you have the ability to run the commands by having Organization Customization turned on in both the source and destination tenants.
Enable-OrganizationCustomization
Create the EXO Migration EndPoint in Target Tenant – Replace AppID, Client Secret and Remote Tenant name with your own.
$AppId = "**APPLICATION ID FROM APP REGISTRATION IN TARGET TENANT**"
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AppId, (ConvertTo-SecureString -String "**CLIENT SECRET**" -AsPlainText -Force)
New-MigrationEndpoint -RemoteServer outlook.office.com -RemoteTenant "XXXXXXX.onmicrosoft.com" -Credentials $Credential -ExchangeRemoteMove:$true -Name "Migration Endpoint 1" -ApplicationId $AppId
Create the Organization Relationship in Target Tenant – Replace the Source Tenant ID with the Tenant ID of your trusted Source Tenant.
$sourceTenantId="SOURCE TENANT ID"
$orgrels=Get-OrganizationRelationship
$existingOrgRel = $orgrels | ?{$_.DomainNames -like $sourceTenantId}
If ($null -ne $existingOrgRel)
{
Set-OrganizationRelationship $existingOrgRel.Name -Enabled:$true -MailboxMoveEnabled:$true -MailboxMoveCapability Inbound
}
If ($null -eq $existingOrgRel)
{
New-OrganizationRelationship "ORG RELATIONSHIP NAME" -Enabled:$true -MailboxMoveEnabled:$true -MailboxMoveCapability Inbound -DomainNames $sourceTenantId
}
Give rights to the App Registration that you created. This is performed in the Source Tenant. Login, then edit/paste this link to navigate to in the browser. Replace APPID with the Application ID from the Target Tenant.
https://login.microsoftonline.com/sourcetenant.onmicrosoft.com/adminconsent?client_id=APPID&redirect_uri=https://office.com
In the Source Tenant, create the Organizational Relationship. Replace Target Tenant ID, APPID, Email Address of Mail Enabled Security Group and Org Relationship Name with the values from your tenants.
$targetTenantId="TARGET TENANT ID"
$appId="APPID"
$scope="EMAIL ADDRESS OF MAIL ENABLED SECURITY GROUP"
$existingOrgRel = $orgrels | ?{$_.DomainNames -like $targetTenantId}
If ($null -ne $existingOrgRel)
{
Set-OrganizationRelationship $existingOrgRel.Name -Enabled:$true -MailboxMoveEnabled:$true -MailboxMoveCapability RemoteOutbound -OAuthApplicationId $appId -MailboxMovePublishedScopes $scope
}
If ($null -eq $existingOrgRel)
{
New-OrganizationRelationship "ORG RELATIONSHIP NAME" -Enabled:$true -MailboxMoveEnabled:$true -MailboxMoveCapability RemoteOutbound -DomainNames $targetTenantId -OAuthApplicationId $appId -MailboxMovePublishedScopes $scope
}
PowerShell notes around creating and modifying the Mail User objects in the Target Tenant. These are just for references as the values are going to need to be changed completely for your tenant situation, but they serve as a good reference for the syntax you need to get these to work.
get-mailbox -identity peter.gibbons@zeotrobe.com | fl name, exchangeguid, legacyexchangedn
set-mailuser -identity peter.gibbons@planeium.com -ExchangeGuid 3d50b00e-b7e3-4377-9f85-c630482b1d1b
set-mailuser -identity peter.gibbons@planeium.com -EmailAddresses @{add="x500:/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=ea419a5745f04213ac40ec667e944209-5497bab4-4c"}
new-mailuser -FirstName Bill -LastName Lumbergh -Alias Bill.Lumbergh -ExternalEmailAddress bill.lumbergh@marktest88.onmicrosoft.com -DisplayName "Bill Lumbergh" -PrimarySmtpAddress bill.lumbergh@planeium.com -name "Bill.Lumbergh" -MicrosoftOnlineServicesID bill.lumbergh@planeium.com -Password $(ConvertTo-SecureString -String 'QWE12345!' -AsPlainText -Force)
new-mailuser -FirstName Michael -LastName Bolton -Alias Michael.Bolton -ExternalEmailAddress michael.bolton@marktest88.onmicrosoft.com -DisplayName "Michael Bolton" -PrimarySmtpAddress michael.bolton@planeium.com -name "Michael.Bolton" -MicrosoftOnlineServicesID michael.bolton@planeium.com -Password $(ConvertTo-SecureString -String 'QWE12345!' -AsPlainText -Force)
set-mailuser -identity bill.lumbergh@planeium.com -ExchangeGuid ea43b297-6153-47a7-8bd2-54d25dbb57ae
set-mailuser -identity bill.lumbergh@planeium.com -EmailAddresses @{add="x500:/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=0c274a7f9db248478a9a9794aa4e81e7-8fed86c6-09"}
set-mailuser -identity michael.bolton@planeium.com -ExchangeGuid f5af830b-5dd1-4eb8-a031-013012954ff6
set-mailuser -identity michael.bolton@planeium.com -EmailAddresses @{add="x500:/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=3eae3e6700a443f9a083460f626484a3-7c940314-8a"}
set-mailbox -identity peter.gibbons@planeium.com -EmailAddresses @{add="smtp:peter.gibbons@zeotrobe.com"}
set-mailbox -identity bill.lumbergh@planeium.com -EmailAddresses @{add="smtp:bill.lumbergh@zeotrobe.com"}
set-mailbox -identity michael.bolton@planeium.com -EmailAddresses @{add="smtp:michael.bolton@zeotrobe.com"}