Use PowerShell to move mailboxes
You can use PowerShell to move mailboxes, in addition to the Exchange Admin Center (EAC).
Move on-premises mailboxes to an Exchange Online organization
To move an on-premises mailbox to Exchange Online using PowerShell, perform the following steps:
Connect to Exchange Online PowerShell: Start PowerShell as administrator and Connect to Exchange Online PowerShell by running the following command:
PS C:\> Connect-ExchangeOnline
Find migration endpoint remote server URL: Get the remote server URL by using the Get-MigrationEndpoint cmdlet.
Get-MigrationEndpoint | Format-List Identity, RemoteServer
The following output appears:
PS C:\> Get-MigrationEndpoint | Format-List Identity, RemoteServer Identity : Hybrid Migration Endpoint - EWS (Default Web Site) RemoteServer : <GUID>.resource.mailboxmigration.his.msappproxy.net
Note
The RemoteServer value in the preceding command syntax output is generated by running Hybrid Configuration Wizard (HCW).
Copy the RemoteServer value as you need it in the next part.
Note
The value for the RemoteServer displayed in the preceding output command-syntax is generated when the user selects Use Exchange Modern Hybrid Topology in the Hybrid Topology page.
Create a new move request to move primary and archive mailboxes to Exchange Online using PowerShell
Fill in the following details to create a new move request to move the primary mailbox and archive mailbox to Exchange Online:
- Identity: Mailbox name or email address.
- RemoteHostName: The remote server that you copied in Step 2.
- TargetDeliveryDomain: Primary SMTP domain used for the Exchange Online organization mailboxes.
- RemoteCredential: On-premises administrator account with privileges.
After running the command, a credential sign-in request shows up.
New-MoveRequest -Identity "Maisha.Lee@contoso.com" -Remote -RemoteHostName "mail.contoso.com" -TargetDeliveryDomain "<domain>.mail.onmicrosoft.com" -RemoteCredential (Get-Credential)
Fill in the password of the on-premises credentials (RemoteCredential).
Move multiple mailboxes to Exchange Online using PowerShell
Create a CSV file named Users.csv and place it in the directory C:\migration.
Open the CSV file, name the header column EmailAddress, and fill in all the mailboxes that you like to move to Exchange Online.
Copy the following script and change the first 3 lines. After that, run the script.
$Mailboxes = Import-Csv "C:\Migration\Users.csv" $RemoteHostName = "mail.contoso.com" $TargetDeliveryDomain = "<domain>.mail.onmicrosoft.com" $OnPremCred = (Get-Credential) # Move mailboxes in CSV file to Exchange Online foreach ($Mailbox in $Mailboxes) { $params = @{ Identity = $mailbox.EmailAddress Remote = $true RemoteHostName = $RemoteHostName TargetDeliveryDomain = $TargetDeliveryDomain RemoteCredential = $OnPremCred } New-MoveRequest @params }
Move primary mailbox only to Exchange Online using PowerShell
There's a scenario wherein the archive mailbox location is in Exchange Online and the primary mailbox location is in Exchange on-premises, and you run the following command:
$Mailboxes = Import-Csv "C:\Migration\Users.csv" $RemoteHostName = "mail.contoso.com" $TargetDeliveryDomain = "<domain>.mail.onmicrosoft.com" $OnPremCred = (Get-Credential) # Move mailboxes in CSV file to Exchange Online foreach ($Mailbox in $Mailboxes) { $params = @{ Identity = $mailbox.EmailAddress Remote = $true RemoteHostName = $RemoteHostName TargetDeliveryDomain = $TargetDeliveryDomain RemoteCredential = $OnPremCred } New-MoveRequest @params }
The result is that you receive the following error message which is part of the bigger command syntax that is shown after the error message:
You must specify the PrimaryOnly parameter Target user ‘XXXXXX’ already has an archive mailbox.
PS C:\> New-MoveRequest -Identity "Maisha.Lee@contoso.com" -Remote -RemoteHostName "mail.contoso.com" -TargetDeliveryDomain "<domain>.mail.onmicrosoft.com" -RemoteCredential (Get-Credential) You must specify the PrimaryOnly parameter. Target user 'Maisha Lee' already has an archive mailbox. + CategoryInfo : NotSpecified: (:) [New-MoveRequest], MailboxReplicationPermanentException + FullyQualifiedErrorId : [Server=PAXP190MB1743,RequestId=3f8179c3-aa93-453f-9e14-d824968f34c4,TimeStamp=5/28/2022 7:19:13 AM] [FailureCategory=Cmdlet-MailboxReplicationPermanentException] FE8B9422,Microsoft.Exchange.Management. Migration.MailboxReplication.MoveRequest.NewModernMoveRequest + PSComputerName : outlook.office365.com
Once you see the error message, perform the following steps:
Add the
-PrimaryOnly
parameter to the preceding command syntax to resolve the error when you create a new move request to move the primary mailbox only to Exchange Online.Fill in the following details:
- Identity: Mailbox name or email address.
- RemoteHostName: The remote server that you copied in Step 2.
- PrimaryOnly: Keep value empty.
- TargetDeliveryDomain: Primary SMTP domain used for the Exchange Online organization mailboxes.
- RemoteCredential: On-premises administrator account with privileges.
After running the command for a new move request, a credential sign-in request shows up as shown in the following command syntax:
New-MoveRequest -Identity "Maisha.Lee@contoso.com" -Remote -RemoteHostName "mail.contoso.com" -PrimaryOnly -TargetDeliveryDomain "<domain>.mail.onmicrosoft.com" -RemoteCredential (Get-Credential)
Fill in the password of the on-premises credentials (RemoteCredential).
Move only archive mailbox to Exchange Online using PowerShell
PS C:\> New-MoveRequest -Identity "Maisha.Lee@contoso.com" -Remote -RemoteHostName "mail.contoso.com" -TargetDeliveryDomain "<domain>.mail.onmicrosoft.com" -RemoteCredential (Get-Credential) You must specify the PrimaryOnly parameter. Target user 'Maisha Lee' already has an archive mailbox. + CategoryInfo : NotSpecified: (:) [New-MoveRequest], MailboxReplicationPermanentException + FullyQualifiedErrorId : [Server=PAXP190MB1743,RequestId=3f8179c3-aa93-453f-9e14-d824968f34c4,TimeStamp=5/28/2022 7:19:13 AM] [FailureCategory=Cmdlet-MailboxReplicationPermanentException] FE8B9422,Microsoft.Exchange.Management. Migration.MailboxReplication.MoveRequest.NewModernMoveRequest + PSComputerName : outlook.office365.com
- Add the
ArchiveOnly
parameter to the preceding command syntax to resolve the error when you create a new move request to move the archive mailbox only to Exchange Online. - Fill in the following details:
- Identity: Mailbox name or email address.
- RemoteHostName: The remote server that you copied in Step 2.
- ArchiveOnly: Keep value empty.
- TargetDeliveryDomain: Primary SMTP domain used for the Exchange Online organization mailboxes.
- RemoteCredential: On-premises administrator account with privileges.
After running the command for a new move request, a credential sign-in request shows up, as shown in the following command syntax:
New-MoveRequest -Identity "Maisha.Lee@contoso.com" -Remote -RemoteHostName "mail.contoso.com" -ArchiveOnly -TargetDeliveryDomain "<domain>.mail.onmicrosoft.com" -RemoteCredential (Get-Credential)
Fill in the password of the on-premises credentials (RemoteCredential).
- Add the
Get mailbox move status
Get the status of the mailbox move request by using the Get-MoveRequest cmdlet.
Get-MoveRequest -Identity "Maisha.Lee@contoso.com" | Get-MoveRequestStatistics
Run the following command to get all the mailbox move requests:
Get-MoveRequest | Get-MoveRequestStatistics
The output shows the mailbox move status as Completed status, as shown in the following screenshot:
If that isn't the case and you can't complete the mailbox move request, you can suspend and resume the move request.
Move Exchange Online mailboxes to an on-premises organization
To move an Exchange Online mailbox to the on-premises organization using PowerShell, perform the following steps:
Connect to Exchange Online PowerShell: Start PowerShell as administrator and Connect to Exchange Online PowerShell by running the following command:
PS C:\> Connect-ExchangeOnline
Note
You aren't pulling the Exchange Online mailbox to on-premises. In fact, you are pushing the Exchange Online mailbox to on-premises. That's why you need to connect to Exchange Online and run the commands from Exchange Online PowerShell.
Find migration endpoint remote server URL: Get the remote server URL by using the Get-MigrationEndpoint cmdlet.
Get-MigrationEndpoint | Format-List Identity, RemoteServer
The following output appears:
Identity : Hybrid Migration Endpoint - EWS (Default Web Site) RemoteServer : mail.contoso.com
Note
The RemoteServer value in the preceding command syntax output is generated by running Hybrid Configuration Wizard (HCW).
Copy the RemoteServer URL value as you need it in the next part.
Create a new move request to move primary and archive mailboxes from Exchange Online using PowerShell
Fill in the following details as part of creating a new move request to move the primary mailbox and archive mailbox from Exchange Online:
- Identity: Mailbox name or email address.
- RemoteTargetDatabase: Exchange on-premises mailbox database.
- RemoteHostName: The remote server that you copied in Step 2.
- TargetDeliveryDomain: Primary SMTP domain used for the Exchange Online organization mailboxes.
- RemoteCredential: On-premises administrator account with privileges.
The command to run to create a new move request is:
New-MoveRequest -OutBound -RemoteTargetDatabase "DB01" -RemoteHostName "mail.contoso.com" -TargetDeliveryDomain "contoso.com" -RemoteCredential (Get-Credential)
Fill in the password of the on-premises credentials (RemoteCredential) for the credential sign-in request that displays as shown in the following command syntax once the command is run:
PS C:\> Get-Mailbox -Identity "Jordy.Twin@contoso.com" | New-MoveRequest -OutBound -RemoteTargetDatabase "DB01" -RemoteHostName "mail.contoso.com" -TargetDeliveryDomain "contoso.com" -RemoteCredential (Get-Credential exoip\administrator) DisplayName Status TargetDatabase ----------- ------ -------------- Jordy Twin Queued
After running the preceding command that includes the password of the on-premises credentials, you can get the following errors:
- Cannot find a recipient that has mailbox GUID
- The archive GUIDs on source and target recipients don't match
Move only primary mailbox from Exchange Online using PowerShell
If the primary mailbox and archive mailbox locations are in Exchange Online, and you want to move the primary mailbox only, add
-PrimaryOnly
and-ArchiveDomain
parameters to the command that you run to create a new move, and in the command syntax, fill in the following details:- Identity: Mailbox name or email address.
- OutBound: Keep value empty.
- RemoteTargetDatabase: Exchange on-premises mailbox database.
- RemoteHostName: The remote server that you copied in Step 2.
- PrimaryOnly: Keep value empty.
- ArchiveDomain: Primary SMTP domain used for the Exchange Online organization mailboxes.
- TargetDeliveryDomain: Primary SMTP domain used for the Exchange Online organization mailboxes.
- RemoteCredential: On-premises administrator account with privileges.
The command to run to create a new move request is:
New-MoveRequest -OutBound -RemoteTargetDatabase "DB01" -RemoteHostName "mail.contoso.com" -PrimaryOnly -ArchiveDomain "<domain>.mail.onmicrosoft.com" -TargetDeliveryDomain "contoso.com" -RemoteCredential (Get-Credential)
After running the command, a credential sign-in request displays as shown in the following command syntax:
PS C:\> Get-Mailbox -Identity "Jordy.Twin@contoso.com" | New-MoveRequest -OutBound -RemoteTargetDatabase "DB01" -RemoteHostName "mail.contoso.com" -PrimaryOnly -ArchiveDomain "<domain>.mail.onmicrosoft.com" -TargetDeliveryDomain "contoso.com" -RemoteCredential (Get-Credential exoip\administrator) DisplayName Status TargetDatabase ----------- ------ -------------- Jordy Twin Queued
Fill in the password of the on-premises credentials (RemoteCredential).
Get mailbox move status
Get the status of the mailbox move request by using the Get-MoveRequest cmdlet.
PS C:\> Get-MoveRequest -Identity "Jordy.Twin@contoso.com" | Get-MoveRequestStatistics | ft DisplayName,StatusDetail,TotalMailboxSize,TotalArchiveSize,PercentComplete DisplayName StatusDetail TotalMailboxSize TotalArchiveSize PercentComplete ----------- ------------ ---------------- ---------------- --------------- Jordy Twin Completed 231.6 MB (242,877,775 bytes) 0 B (0 bytes) 100
The mailbox move completes. If that isn't the case and you can't complete the mailbox move request, you can suspend and resume the move request.
To implement the next step of removing the completed migrated batches, see Remove completed migration batches.