Active Directory & Office 365 Reporting Tool

How to – Office 365 to Office 365 Migration (Step by Step). Moving from one Office 365 environment to another demands careful planning and execution to ensure a seamless transition without compromising data integrity. This comprehensive guide outlines the step-by-step process for an Office 365 cross-tenant mailbox migration, emphasizing essential stages. By following these detailed steps, organizations streamline their migration journey and minimize potential disruptions to their daily operations. In this guide we describe the process of migration using the built-in Cross Tenant User Data Migration tool. As well as the other tools, it has its pros (it doesn’t require purchasing of third-party tools) and cons (it doesn’t support public folder migration, requires some PowerShell scripting skills), and works for both small and large enterprises.

Let’s start our article How to – Office 365 to Office 365 Migration.

How to - Office 365 to Office 365 Migration

1. Pre Office 365 to Office 365 Migration Assessment

Firstly, ensure to collect the following information:

  1. Legal hold usage. Mailboxes and OneDrive accounts with a Hold policy applied cannot be migrated to another tenant.
  2. Archive enabled mailboxes. During the attribute matching (shown below during the account preparation), users who has archived mailboxes must have both ExchangeGUID and ArchiveGUID attributes matching in source and target tenants.
  3. Existing delegations of Send on Behalf permission. This permission is not migrated and must be reconfigured after the migration. If you want to use PowerShell script to assess the list of delegations, ensure to convert the Distinguished Name attribute (which cannot be used in the target tenant) to some attribute that remains the same after the migration, for example Display Name. Example of the script that can be used to collect the information is below (to run it, connect to Exchange Online PowerShell module first):
					$delegatedmailboxes = get-mailbox -resultsize unlimited | ?{$_.GrantSendOnBehalfTo -ne $null} | select displayname,GrantSendOnBehalfTo
$FilePath = "C:\output\delegatee.csv" #use your own file path, ensure that folder exists
Add-Content -Value ("Delegator" + "," + "Delegatee") -Path $FilePath 
foreach ($delegatedmailbox in $delegatedmailboxes) {
    $delegatees = $delegatedmailbox.GrantSendOnBehalfTo
    foreach ($delegatee in $delegatees) {
        $delegateeName = get-mailbox $delegatee 
        $delegatedmailbox.Displayname + "," + $delegateeName.Displayname | out-file $FilePath -append 


The script creates a CSV file that contain the information about all the delegations of Send on Behalf permission in the tenant. The file can be used after the migration to recreate the delegations. Note, CSV files use comma as a separator, so if comma is used in DisplayName attribute of users in your company, adjust the script accordingly (e.g. use tabulation as a separator).

  1. Ensure you have necessary permissions in both source and target tenants. Initial configuration requires Organization Administrator role (for the configuration of organization relationship) and the ability to register applications in Azure AD (to register the migration application in the further steps). The movement itself doesn’t require high privilege and could be done by account with Move Mailbox permission.
  2. Ensure you have necessary licenses in both source and target tenants. You need Microsoft 365 licenses and Cross Tenant User Data Migration licenses for all users that are migrated. Ensure Cross Tenant User Data Migration licenses are assigned before the migration. In target tenant, make sure Exchange Online licenses are not assigned before ExchangeGUID attribute and proxy addresses are assigned to the user, as it causes the migration failure (because a mailbox with different GUID are assigned to the mailbox.
  3. Obtain and write down tenant ID for both tenants, as described in Find your Microsoft 365 tenant ID article.

A note to users

Also, notify the end users about the expected impact:

  • Mailbox will be in a read-only mode for a short period during the migration.
  • Users must recreate Outlook profile in desktop and mobile devices after the migration.
  • Microsoft 365 applications may require reactivation.
  • If OneDrive or SharePoint was mapped as a network drive, they will need to be re-mapped.
  • Existing Teams meetings will need to be recreated.
  • Microsoft 365 Groups won’t be migrated.

2. Registration of Migration Application in Microsoft Entra

To allow Microsoft to move the users across two tenants, you need to register the application in Microsoft Entra (for those who missed the update, Entra is how Microsoft calls Azure AD now) of the target tenant and give it the Mailbox.Migration permission. Additionally, the creation of the secret is required, which is used to create the migration endpoint (migration endpoint is a configuration entity that contains settings and credentials to perform external migrations).

  1. Go to Microsoft Entra admin center and login using account that can register applications.
  2. Navigate to Applications > App registrations and select New registration.
  1. In the appeared Register an application window, enter the name (any name would work), select Accounts in any organizational directory (Any Microsoft Entra directory – Multi-tenant) option as supported account types and specify https://office.com as a web redirect URI, then press Register.
  1. Back on the App registrations page, select the created application.
  2. In the opened page, in the Overview tab, find Application (client) ID and write it down for the further use.
  1. Go to API permission tab and press Add a permission.
  1. In the appeared window, navigate to APIs my organization uses tab and select Office 365 Exchange Online.
  1. Navigate to Application Permissions, in the list select Mailbox > Mailbox.Migration and then press Add permissions button.
  1. After permissions are granted, go to Certificates & secrets tab (in the navigation pane of the application page), and in Client secrets section, select New client secret.
  1. Fill both fields and press Add.
  1. Back on the Certificates & secrets page you see the new Secret ID and the password, write down both for the future use.

Try our Active Directory & Office 365 Reporting & Auditing Tools

Try us out for Free.  100’s of reports available to gain control of your IAM.

Improve your AD & Entra ID security & compliance.

3. Preparation of the target Office 365 tenant

On the next step, we grant admin consent to the registered application in the target tenant, and then create the migration endpoint and organization relationship. Organization relationships are used in Exchange Online to provide the external parties some access to the internal resources. The most popular use of this feature is to give read access to the Calendar information to the partner organization (to share availability status), however it can be used for other access types as well. In our case, we provide the mailbox move capability.

  1. In the Microsoft Entra admin center, navigate to Applications > Enterprise applications.
  2. In the application list select the created migration application.
  3. Application page appears, navigate to the Permissions tab, and press Grant admin consent for [your tenant name].
  1. Application page appears, navigate to the Permissions tab, and press Grant admin consent for [your tenant name].
  1. New browser window opens, accept the granting of permissions.
  2. To create the migration endpoint and organization relationship in the target tenant, open PowerShell and connect to Exchange Online module.
  3. Next, check whether your Exchange organization is in the dehydrated state. If it is, no customization of organization settings is possible.
					Get-OrganizationConfig | select isDehydrated 
  1. If the output is False, this step can be ignored, if it is True, run Enable-OrganizationCustomization cmdlet.
  2. Create the migration endpoint:
					$AppId = "[Application ID saved in step 2.5]"
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AppId, `
(ConvertTo-SecureString -String "[secret password saved in step 2.11]" -AsPlainText -Force)
New-MigrationEndpoint -RemoteServer outlook.office.com -RemoteTenant ".onmicrosoft.com" `
-Credentials $Credential -ExchangeRemoteMove:$true -Name "MigrationEndpoint01" -ApplicationId $AppId


Where “<SourceDomain>.onmicrosoft.com” is the domain from which you are going to migrate the users

  1. Create organization relationship (or modify it, if the relationship already exists):
					$sourceTenantId="[ID of the source tenant from step 1.6]"
$existingOrgRel = Get-OrganizationRelationship | ?{$_.DomainNames -like $sourceTenantId}
If ($null -ne $existingOrgRel) {
    Set-OrganizationRelationship $existingOrgRel.Name -Enabled:$true -MailboxMoveEnabled:$true -MailboxMoveCapability Inbound
Else {
    New-OrganizationRelationship "SourceTenant" -Enabled:$true -MailboxMoveEnabled:$true -MailboxMoveCapability Inbound -DomainNames $sourceTenantId


4. Preparation of the source Microsoft 365 tenant

  1. Login to the source tenant Microsoft Entra admin console.
  2. Go to the URL https://login.microsoftonline.com/<TargetTenant>.onmicrosoft.com/adminconsent?client_id=[Application ID]&redirect_uri=https://office.com, where <TargetTenant> replace it with the domain name of the tenant you want to move mailboxes to, and Application ID is the one saved earlier.
  3. In the appeared window, accept granting the permissions to the application.
  1. Connect to Exchange Online PowerShell of the source tenant (If you prepare both tenants from the same computer, you need run Connect-ExchangeOnline again with different UserPrincipalName parameter).
  2. Repeat steps 3.6 and 3.7 from the previous section for the source tenant.
  3. Create a new mail-enabled security group. Used to define users that will be moved:
					$UserGroup="[name of the group]" ; New-DistributionGroup -Type Security -Name $UserGroup
  1. Create organization relationship (or modify it, if the relationship already exists):
					$targetTenantId="[ID of the target tenant saved in step 1.6]"
$AppId="[Application ID]"
$existingOrgRel = Get-OrganizationRelationship | ?{$_.DomainNames -like $targetTenantId}
If ($null -ne $existingOrgRel) {
    Set-OrganizationRelationship $existingOrgRel.Name -Enabled:$true -MailboxMoveEnabled:$true `
    -MailboxMoveCapability RemoteOutbound -OAuthApplicationId $AppId -MailboxMovePublishedScopes $UserGroup
Else {
    New-OrganizationRelationship "TargetTenant" -Enabled:$true -MailboxMoveEnabled:$true -DomainNames $targetTenantId `
    -MailboxMoveCapability RemoteOutbound  -OAuthApplicationId $AppId -MailboxMovePublishedScopes $UserGroup

  1. Move all users planned to be migrated to the group created in step 6. Remember that the usage of nested group is not recommended.

5. Preparation of the user accounts in the target tenant

Cross-tenant movement of mailboxes requires pre-created MailUser objects in the target domain. The objects must have attributes that match the attributes of the source mailbox, more details could be found here. Ensure the EmailAddresses attribute is configured correctly: it must contain the LegacyExchangeDN attribute of the source mailbox as an X500 proxy address. The easiest way to perform attribute matching is to use PowerShell.

  1. In the source tenant PowerShell session run the below script to export user attributes into XML file (in this case XML fits betters than CSV, because some attributes are arrays).
					$UserAttributes = "C:\output\UserAttributes.xml" #use your own file path, ensure that folder exists
Get-DistributionGroupMember -ResultSize Unlimited $UserGroup | ForEach-Object {Get-Mailbox $_.DisplayName}| ` 
Select-Object PrimarySMTPAddress,Alias,SamAccountName,FirstName,LastName,DisplayName,Name,ExchangeGuid,`
ArchiveGuid,LegacyExchangeDn,EmailAddresses | Export-Clixml $UserAttributes

  1. During the creation of MailUser objects, specify the passwords. Therefore, in the target tenant PowerShell session prepare some PowerShell function for password generation. For example, the below function is created based on Get-RandomPassword function available in the PowerShell Gallery.
					$symbols = '!@#$%^&amp;*'.ToCharArray()
$characterList = @([char[]]([char]'a'..[char]'z'), [char[]]([char]'A'..[char]'Z'), [char[]]([char]'0'..[char]'9') + $symbols)
function Get-RandomPassword  {
        [ValidateRange(12, 256)]
        $length = 16
    do {
        $password = -join (0..$length | ForEach-Object { $characterList | Get-Random })
        [int]$hasLowerChar = $password -cmatch '[a-z]'
        [int]$hasUpperChar = $password -cmatch '[A-Z]'
        [int]$hasDigit = $password -match '[0-9]'
        [int]$hasSymbol = $password.IndexOfAny($symbols) -ne -1
    until (($hasLowerChar + $hasUpperChar + $hasDigit + $hasSymbol) -ge 3)
    $password | ConvertTo-SecureString -AsPlainText -Force

  1. In the target tenant PowerShell session, run the following script to create the MailUser objects. Additionally, it creates a CSV file that is used during the creation of the migration batch.
					$MailUsers = Import-Clixml $UserAttributes
$Organization = "@.onmicrosoft.com" #use target tenant name
$CSVData = "C:\output\CSVData.csv" #use your own file path, ensure that folder exists
Add-Content -Value ("EmailAddress") -Path $CSVData 
foreach ($MailUser in $MailUsers) {
    $SMTPAddress = $MailUser.Alias + $Organization
    $SMTPAddress  | out-file $CSVData -append
    $Password = Get-RandomPassword
    $x500 = "x500:" + $MailUser.LegacyExchangeDn
    $UserObject = New-MailUser -MicrosoftOnlineServicesID $SMTPAddress -PrimarySmtpAddress $SMTPAddress `
    -ExternalEmailAddress $MailUser.PrimarySmtpAddress -FirstName $MailUser.FirstName -LastName $MailUser.LastName `
    -Name $MailUser.Name -DisplayName $MailUser.DisplayName -Alias $MailUser.Alias -Password $Password
    $UserObject | Set-MailUser -EmailAddresses @{add = $x500 } -ExchangeGuid $MailUser.ExchangeGuid -ArchiveGuid $MailUser.ArchiveGuid
    $ProxyX500 = $MailUser.EmailAddresses | Where-Object { $_ -match "x500" }
    $ProxyX500 | ForEach-Object { Set-MailUser $MailUser.Alias -EmailAddresses @{add = "$_" } }

  1. When you ensure the proper objects are created in the target tenant, assign Exchange Online licenses to the users.
  2. To validate the configuration, from the source tenant PowerShell session run:
					Test-MigrationServerAvailability -EndPoint "MigrationEndpoint01" -TestMailbox "[primary SMTP address of the target user mailbox]"

6. User accounts movement and migration finalization

During Office 365 to Office 365 cross tenant migrations the mailboxes are moved using the migration batches. Migration batches are the requests to change the location of the listed mailboxes. Batch is created using Exchange Online Admin Center or using New-MigrationBatch  PowerShell cmdlet.

  1. Create the migration batch from the source tenant PowerShell session. Ensure path to the CSV file created earlier is correct.
					New-MigrationBatch -Name Batch01 -SourceEndpoint "MigrationEndpoint01" -CSVData ([System.IO.File]::ReadAllBytes("C:\output\CSVData.csv"))`
-Autostart -TargetDeliveryDomain .onmicrosoft.com

Note, Microsoft doesn’t recommend using batches with more than 2000 users. If you have large number of mailboxes to be moved, create several batches.

  1. Monitor the batch movement progress from either PowerShell (using Get-MigrationStatistics cmdlet) or in Exchange Online admin center (login to https://admin.exchange.microsoft.com/ and navigate to Home> Migration Batches), look for the errors and warnings.
  2. After, use the file with delegation information created earlier to reconfigure Send on Behalf permissions. To do it, run the following in the target tenant PowerShell session:
					$delegateelist = Import-Csv "C:\output\delegatee.csv"
foreach ($mailbox in $delegateelist ) {
    Set-Mailbox $mailbox.Delegator -GrantSendOnBehalfTo $mailbox.delegatee)            


After the completion of all steps, feel free to remove created migration endpoint and organization relationship.

How to - Office 365 to Office 365 Migration Conclusion

Successfully migrating mailboxes between Office 365 environments requires thorough assessment and precise execution of multiple steps. This guide has provided a comprehensive roadmap for IT professionals to navigate through critical considerations, permissions, and migration setup. By adhering to these steps, organizations conduct a smooth and efficient mailbox migration process, ensuring minimal downtime and preserving data integrity.


Try InfraSOS for FREE

Try InfraSOS Active Directory, Azure AD & Office 365 Reporting & Auditing Tool

Marat M

Marat M

System administrator with 14 years of practical experience. Specializes in Microsoft products such as Exchange Server, Active Directory, Microsoft 365 and Azure.

Leave a comment

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