There are a multitude of different scenarios involving migrations to Exchange Online. Some are straightforward while other are painfully complex. Today we will be looking at a particular scenario where a customer has two Active Directory (AD) Forests, let us call them ForestA and ForestB:
- ForestA has Exchange installed (does not matter which version) and the customer wants to set up an Exchange Hybrid deployment to coexist/migrate with Exchange Online (well, let us assume it is not Exchange 5.5);
- ForestB has a 3rd party messaging solution and the customer wants to migrate those mailboxes directly to Office 365 but migrate the AD accounts into ForestA so that ForestB can be decommissioned.
The problem with this scenario is that, typically, the migration tool used in ForestB migrates the mailboxes to Office 365 just fine, but creates the AD accounts in ForestA as “normal” users, meaning the Exchange Hybrid has no knowledge that those users actually have a mailbox in Office 365.
As such, the customer is not able to use the Hybrid server to manage any of the objects migrated from ForestB, only those that already existed in ForestA and were “properly” migrated.
One of the reasons to leave at least one Hybrid server on-premises even after all mailboxes have been migrated to Office 365, is so that administrators can easily manage mailboxes from a single and well-known console. Remember that since the source of authority is the on-premises AD (because of AADSync or DirSync), all changes need to be made on-premises. If there is no longer an Exchange server to manage/update mail attributes, administrators have to turn to 3rd party tools or ADSI Edit for example.
Not being able to manage half of the migrated objects is obviously not good for the customer, or the consultant doing the work for that matter! 🙂
To overcome this, we need to make a few changes to those AD accounts so that the on-premises Exchange recognizes them so we can manage them. Let us look at an example of a user called “Cloud Only” which has a mailbox in Office 365. As you can see, it is not being synchronized by AADSync (or DirSync):
Figure 1: User display in Office 365 Admin Portal
In the on-premises AD, there is an account with the same UPN but no mail attributes at all:
Figure 2: On-premises Active Directory account
In some cases, it is likely that the migration tool will also copy (migrate) the mail attributes for the users from ForestB to ForestA. However, in this case we are assuming the worst case scenario where no mail attributes were copied.
Before placing the account under AADSync scope, we use the Exchange cmdlet Enable-MailUser to convert the account to a mail-enabled user so that Exchange recognizes it. For this cmdlet we use the user’s primary SMTP address:
Enable-MailUser cloud.only –ExternalEmailAddress cloud.only@nunomota.pt
Figure 3: Enable-MailUser using EMS
Once this is done, the user will appear under contacts in the Exchange Admin Center (EAC). This is because it now has all the required attributes to be recognized as a mail user:
Figure 4: Mail User now visible in the EAC
As this Exchange environment has already been configured as a Hybrid environment, the Default Email Address Policy will automatically add an additional address of alias@.mail.onmicrosoft.com to all recipients for correct mail flow. This means we do not need to update any of the user’s email addresses unless:
- The user had additional SMTP addresses in the source forest that are still needed in Office 365;
- We need to add the LegacyExchangeDN as X500 addresses (if at the source this was an Exchange environment).
For this scenario, I am assuming none of these are required, so we already have all the addresses we need:
Figure 5: User’s proxyAddresses attribute
However, we do not want this user to be just a MailUser but a RemoteMailbox instead. If we look at the msExchRecipientTypeDetails attribute in AD, we see that it is set to 128:
Figure 6: User’s msExchRecipientTypeDetails attribute
According to the msExchangeRecipientTypeDetails Active Directory Values tip published a few months ago on MSExchange.org, 128 refers to a MailUser.
So how do we change it to be RemoteMailbox? To do so, we update this attribute to 214748364 instead, which is the value for RemoteMailbox. However, we also need to update two other attributes. We can do this using ADSI Edit, Attribute Editor or PowerShell:
Set-ADUser cloud.only –Replace @{msExchRecipientDisplayType = “-2147483642”}
Set-ADUser cloud.only –Replace @{msExchRecipientTypeDetails = “2147483648”}
Set-ADUser cloud.only –Replace @{msExchRemoteRecipientType = “4”}
Figure 7: Update attributes using PowerShell
Using Attribute Editor we can check that these attributes were all set correctly:
Figure 8: Checking attributes were set correctly
Just some explanation on why we set msExchRemoteRecipientType to 4. An msExchRemoteRecipientType of 4 represents a Migrated mailbox when a move request is used. This attribute can have other values such as 100 which is used for shared mailboxes, or for example 1 which represents a Provisioned mailbox when the New/Enable-RemoteMailbox cmdlets are used.
Both values of 1 and 4 represent a mailbox in Office 365 with a corresponding user on-premises. So why are we using 4 and not 1? These two values separate out two code paths: new employee provisioning and existing on-premises user being moved to the cloud.
At the end of an on-boarding move, the Mailbox Replication Service Proxy (MRS Proxy) converts the on-premises mailbox into a RemoteMailbox (with msExchRemoteRecipientType of 4 “Migrated”), and the cloud MailUser into a Mailbox.
When administrators want to provision a new Mailbox in the cloud they can:
- Run the New-RemoteMailbox cmdlet on-premises which creates a mail-enabled user in the on-premises AD (with msExchRemoteRecipientType of 1 “Transitioned”) and an associated mailbox in Office 365;
- Or the Enable-RemoteMailbox cmdlet to mail-enable an existing on-premises user (with msExchRemoteRecipientType of 1 “Transitioned”) and create an associated mailbox in Office 365. After the user is mail-enabled, directory synchronization synchronizes the mail-enabled user to the service and the associated mailbox is created.
As in our scenario mailboxes have been migrated (just not through the normal remote move migration process), we are setting msExchRemoteRecipientType to 4 to keep it consistent and clear that they are migrated users. Under normal circumstances, we can very well set it to 1 instead.
If we now go back to the EAC the user will be listed as an Office 365 mailbox type under mailboxes!
Figure 9: Mailbox displayed in EAC
We can also double-check this using the Shell to confirm it is actually a RemoteMailbox by running Get-RemoteMailbox cloud.only:
Figure 10: Checking RemoteMailbox using the EMS
But we are not done yet... If we check the user’s properties, the routing address is set to the user’s primary SMTP address:
Figure 11: Mailbox properties in the EAC
As we know, this should be the user’s @.mail.onmicrosoft.com address so that emails are correctly forwarded to the mailbox in Office 365. Otherwise emails will just get rejected as the user does not have a mailbox on-premises.
We can correct this using several methods, all leading to the same outcome. Two of these methods include directly setting the user’s targetAddress AD attribute using ADSI Edit or the following PowerShell cmdlet:
Set-ADUser cloud.only –Replace @{targetAddress = “SMTP:cloud.only@nunomota.mail.onmicrosoft.com”}
Or we can correct this through the Exchange Shell:
Set-RemoteMailbox cloud.only –RemoteRoutingAddress “SMTP:cloud.only@nunomota.mail.onmicrosoft.com”
Figure 12: Updating mail routing address
Now all there is left to do is place the user under AADSync scope, wait for a synchronization to happen (or manually trigger one) and check that everything is ok in Office 365:
Figure 13: User display in Office 365 Admin Portal
Job done!
The reason why I used PowerShell for all the changes is that it makes it possible to easily perform this for many users in one go. If we have the users’ details in a CSV file, for example, we can put all these cmdlets into a script and go through the entire CSV and update all users in a matter of seconds!
Please note: at this stage you will not be able to migrate the mailbox back on-premises! This is because the ExchangeGUID attribute is not set on-premises. To fix this, get the ExchangeGUID from the mailbox in Office 365:
Get-Mailbox cloud.only | Select ExchangeGUID
Back on-premises, update the ExchangeGUID for the remote mailbox (obviously updating with the value you got from the first step):
Set-RemoteMailbox cloud.only -ExchangeGUID “4e4f00b7-ee3f-4182-aaad-448dbe4c82c9”