Hybrid migration from Exchange 2016 to Office 365

Tutorial on how to perform Hybrid migration from Exchange 2016 to Office 365

High Level Approach for Hybrid migration from Exchange 2016 to Office 365

  1. Generate Users’ Mailbox usage with PowerShell Script on Exchange 2016 Server to identify which mailbox need to be migrated
  2. Public Accessible User Principle Name (UPN) – YongKW.com, and update all users with the new UPN
  3. Raise Forest & Domain Functional Level to Windows 2008R2 and enable AD Recycle Bin Features – Optional
  4. Associate New Domain Name, YongKW.com
  5. Enable Directory Synchronization in Office 365
  6. Configure Azure AD Connect to sync users, groups & password from Local AD to Office 365

User Principle Name (UPN) in AD Domain

  1. Verify whether is there any UPN configured
PS C:\Users\administrator.MYLAB> Get-ADForest | fl UPNSuffixes

UPNSuffixes : {}
  1. Add a new UPN called YongKW.com
# Add a New UPN called YongKW.com
Get-ADForest | Set-ADForest -UPNSuffixes @{add="yongkw.com"}

# Verify UPN is added successfully
Get-ADForest | fl UPNSuffixes
PNSuffixes : {yongkw.com}
  1. Verify the new UPN is added in Active Directory Domains and Trusts

hybrid migration from exchange 2016 to office 365

Update AD Users’ UPN

Update all AD Users’ UPN who is under organization unit (OU) called "O365" to YongKW.com

Import-module ActiveDirectory

#Update UPN for all users
$OU = "OU=O365, DC=Mylab, DC=Local"
$Users = Get-ADUser -SearchBase $OU -Filter * 

foreach ($User in $Users) { 

    $NewUPN = $user.UserPrincipalName.Replace("mylab.local","YongKW.com")
    $user |  Set-ADuser -UserPrincipalName $NewUPN 


#Verify All users in $OU are updated with new UPN Name
Get-ADUser -SearchBase $OU -Filter * | Select UserPrincipalName

You must enter the old and new UPN exactly by following the output from Get-ADUser -SearchBase $OU -Filter * | Select UserPrincipalName – CASE SENSITIVE

Raise Forest & Domain Functional Level

Verify the Domain Functional Level is Windows 2003 or above

Get-ADDomain | Select-Object domainMode, DistinguishedName 

       domainMode DistinguishedName
       ---------- -----------------
Windows2003Domain DC=mylab,DC=local

Verify the Forest Functional Level is Windows 2003 or above

Get-ADForest | Select-Object forestMode


Raise Forest & Domain Functional Level to Windows 2008R2

#Raise AD Domain & Forest Functional Level to 2008R2 
$ADDomainPDC = Get-ADDomainController -Discover -Service PrimaryDC
$ADForest = Get-ADForest

Set-ADDomainMode -Identity $ADDomainPDC.Domain -Server $ADDomainPDC.HostName[0] -DomainMode Windows2008R2Domain
Set-ADForestMode -Identity $ADForest -Server $ADForest.SchemaMaster -ForestMode Windows2008R2Forest

Active Directory Recycle Bin – Optional

A warning message is prompted during the configuration of Azure AD Connect if AD Recycle Bin feature is NOT enabled and you can just safely ignore the warning message

#Enable AD Recycle Bin Feature
#Run directly on DC or Targeted to DomainNamingMaster
Enable-ADOptionalFeature 'Recycle Bin Feature' -Scope ForestOrConfigurationSet -Server $ADForest.DomainNamingMaster -target $ADDomainPDC.Domain

Associate New Domain Name

Prepare Master Key & Password File

#First time only
$KeyFile = "C:\Scripts\MasterKey.key"
$PasswordFile = "C:\Scripts\Password.txt"

$Key = New-Object Byte[] 32
$Key | out-file $KeyFile

#Enter your username & Password when prompt and save the password you enter to $passwordfile
(get-credential).Password | ConvertFrom-SecureString -key (get-content $KeyFile) | set-content $PasswordFile

Refer to my previous post on how to Connect to Office 365 with PowerShell

# Login to O365
$Password = Get-Content $PasswordFile | ConvertTo-SecureString -Key (Get-Content $KeyFile)
$UserName = "[email protected]"
$credential = New-Object System.Management.Automation.PsCredential($UserName,$Password)

#Login to Office 365
Connect-MsolService -Credential $Credential

Remove all the demo users account to free up some licenses for our lab

#To remove all demo account provisioned 
Get-MsolUser | ? UserPrincipalName -NotLike "[email protected]" | Remove-MsolUser -Force

Add our own Domain, YongKW.com

#New Domain
$Domain = "YongKW.com"
New-MsolDomain -Name $Domain
Get-MsolDomainVerificationDNS -DomainName $Domain

Name       Status     Authentication
----       ------     --------------
YongKW.com Unverified Managed       

CanonicalName : ps.microsoftonline.com
ExtensionData : System.Runtime.Serialization.ExtensionDataObject
Capability    : None
IsOptional    : 
Label         : ms91490600.YongKW.com
ObjectId      : fe8b277b-6665-477a-82a5-13d12093c912
Ttl           : 3600

Copy the value from Label : ms91490600.YongKW.com and add it as TXT record in our DNSMadeEasy Control Panel

Verify the Domain Ownership

Confirm-MsolDomain -DomainName $Domain

        Availability AvailabilityDetails                                         EmailVerifiedInformation
        ------------ -------------------                                         ------------------------
AvailableImmediately The domain has been successfully verified for your account.                         

Set YongKW.com as default Domain

#Set it as default 
Set-MsolDomain -Name $Domain -IsDefault

Get-MsolDomain | Select Name, isDefault

Name                        IsDefault
----                        ---------
M365x521231.onmicrosoft.com     False
YongKW.com                       True

Enable Directory Synchronization

Enable Directory Synchronization for Azure AD Connect to sync local AD users, groups & password to Azure AD.

Get-MsolCompanyInformation | Select-Object DirectorySynchronizationEnabled 


Enable Directory Synchronization

Set-MsolDirSyncEnabled -EnableDirSync $true 

Azure AD Connect for Exchange Hybrid Migration

Refer to my previous post on Azure AD Connect for Exchange Hybrid Migration to setup the Azure AD Connect

Leave a Comment

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

Scroll to Top