Tuesday, May 24, 2022

Migrate from Exchange 2010 to Exchange 2016

Abstract: In that short example we will walk true the needed steps, which will upgrade/migrate a Exchange 2010 environment to Exchange 2016.

As there are different options how to move users from Exchange 2010 to Exchange 2016, this here is only ONE example so it might not fully fit your environment. Many steps here could also apply to a Exchange 2013 to Exchange 2016 migration. However that’s not the focus form this HowTo.


Our current environment looks like the following:

– exhub01 / exhub02 -> Exchange 2010 Hubserver (as round robin for incoming and outgoing SMTP connection)

– excas01 / excas02 -> Exchange 2010 CAS Server (as CAS Array)

– exmail01 / exmail02 -> Exchange 2010 Mail Server (as DAG)

– The new Exchange 2016 environment one will contain only two server (as its no longer possible to split the roles)

– The old exchange hubserver have a round robin for incoming and outgoing SMTP connection

– No public folder are used

– A hardware LoadBalancer is in front of Outlook Anywhere (OAW), Outlook WebAccess (OWA) and Mapi (Note: There is only MapiOverHTTP in Exchange 2016). But if you do not have one most of the steps will work for DNS load-balancing as well.

– Only Outlook 2010,2013 and 2016 is used on the PCs. Some of the users are using a mobile device (e.g. iOS, Android, …)

– Exchange 2010 and Exchange 2016 are in the same AD site / datacenter

– eMails are coming from a Postfix environment (which also acts as smarthost) which is doing AntiSpam and some Antivirus

– Exchange 2010 CAS name is the same as the OWA name (more infos here)



– Exchange 2013 is the last version which supports native MAPI (e.g. MAPI over RPC), in Exchange 2016 we will will have only MAPI over HTTP. Therefore a a BlackBerry 5.0.x didn´t support Exchange 2016. So you need to remove all these 5 year “old” devices. However many companies might have already switched to an newer BlackBerry 10.x server (ans also to BlackBerry 10.x devices) so this might not be a big deal.

– As Exchange 20106 do no longer separate CAS, HUB and Mailbox roles, we need to install all Exchange roles on one server, so we will prepare the following:

* exch01 -> A Windows 2012 R2 OS for Exchange 2016 (Enterprise Edition)

* exch02 -> A Windows 2012 R2 OS for Exchange 2016 (Enterprise Edition)

– On both our new Microsoft Exchange 2016 server, created a new high performance power plan to avoid any performance issues

– Set the same date & time format (for all users) on both server so that it fits your needs

– Make sure all needed firewall connections are in place (see here and here)

– Make sure that (if you use a 3rd party SMTP Gateway), that your SMTP Gateway accepts emails from the new Microsoft Exchange server

– Add two NICs to the Exchange Server

* assign IPs to the Server (one NIC will be the normal access [we rename it to “mail”], the other will be used for the DAG replication [we rename it to “replication”]. The replication network might be a direct server to server network.)

* Inside NIC Adapter and Bindings change the network order so that the “mail” and not the “replication” is the first one

* Allow the “Register in DNS” option for only the “mail” nic! -> For more infos see here.

* On the replication NIC disable the following “Client for Microsoft Networks” and “File and Printer Sharing for Microsoft Networks”

* On the replication NIC on the DNS tab, make sure that the option “register this connection in DNS” is not selected

(* You might wish to disable IPv6 if needed)

– The best setup is to use two drives/disks. One will be used for the OS (formated with NTFS) and the other one will be used for the DBs & logs formatted with ReFS  (see http://exchangeserverpro.com/refs-exchange-server-volumes/)

– Make sure you have the needed licenses and (for this howto) a Exchange 2016 Enterprise key


Migration steps:

1.) The first step is to prepare the active directory for the new schema.

1a.) To do that download the Exchange 2016 ISO from the Microsoft download portal or better download it from the Microsoft website (this will includes any further updates e.g. a possible service pack).

1b.) Login into one your domain controllers (=DCs). In our example we will use our primary root DC. Make sure that this user has the “Schema Admins” role.

Keep noted that this role should only be assigned to that user during the schema update, you should remove that later one.

1c.) Copy the download to an easily accessible folder (for example C:\Exch2016\download). 

1d.) Run the downloaded file in order to extract the installation files, extract them to c:\Exch2016

1e.) Now we need to run (at least in the environment for this howto):

setup.exe /PrepareSchema /IAcceptExchangeServerLicenseTerms

and then

setup.exe /PrepareAD /IAcceptExchangeServerLicenseTerms

In our environment we need to run as well the following:

Setup.exe /PrepareAllDomains /IAcceptExchangeServerLicenseTerms

1f.) Monitor and wait until the change is replicated across your AD environment. You can then logoff from your DC.

2.) Configure a web proxy (as mentioned here) on both new exchange 2016 server. Patch them fully but do NOT yet install .net framework 4.6.1 yet as mentioned here. The best might be to save the following to a .reg file and apply that to the exchange server (more infos here):

Windows Registry Editor Version 5.00


3.) Install the prerequisites on the new Exchange 2016 server as mentioned here and reboot the server:

Install-WindowsFeature AS-HTTP-Activation, Desktop-Experience, NET-Framework-45-Features, RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, RSAT-Clustering-Mgmt, RSAT-Clustering-PowerShell, Web-Mgmt-Console, WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI, Windows-Identity-Foundation

4.) Once done re-scan for windows updates and install all pending updates again due to the reason that we installed a lot of new features.

5.) You can do some basic hardening now if you wish:

– Disable SSL 2.0 / SSL 3.0

Disable disable triple DES 168

– Enable TLS 1.2

– Disable “Enable LMHOSTS lookup”

– Disable NetBIOS over TCP/IP

– Disable printer spooler service

– Disable the NtfsDisable8dot3NameCreation

Disable the “X-AspNet-Version” header

– …

As this is a new server you might consider to disable TLS 1.0 as well due to PCI DSS 3.1

6.) Now you can mount the ISO and run the Exchange 2016 setup

6a.) Once installed we need directly change the Service Connection Point (SCP) from the default https://exch01.contoso.com/autodiscover/autodiscover.xml (which is your new server). To the old Exchange 2010 server. This can be done via (on one Exchange 2016):

Set-ClientAccessService -Identity “exch01” -AutoDiscoverServiceInternalUri “https://mbx01.contoso.com/autodiscover/autodiscover.xml”

Set-ClientAccessService -Identity “exch02” -AutoDiscoverServiceInternalUri “https://mbx01.contoso.com/autodiscover/autodiscover.xml”

Keep noted that you need an running Exchange 2016 to use the powershell above. So if you use a administration workstation you need to install at first the exchange 2016 management tools there.

If you do not perform this step, then you run into risk that Outlook clients will pick up the new installed Exchange 2016 server via Autodiscover and will get at least an SSL error. So to avoid issues, change that directly after the Exchange 2016 installation!

6b.) Now fully patch the server via windows updates and give him a reboot

6c.) Now its time to set the exchange license key via:

Set-ExchangeServer exch01 -ProductKey XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

Set-ExchangeServer exch02 -ProductKey XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

6d.) As we do not use IMAP or POP3 (in that migration howto) disable the windows POP3 and IMAP services now (they are currently not running and on the manual state). This is to avoid side effects if they start somehow and somebody start using them.

7.) Now RDP into your first new exchange 2016 server (if not already done) and start a exchange management powershell on that OS (run as admin) as we need to configure the server via powershell now.

9.) Optional: To move the workload (which our new exchange server will cause) onto two separate domain controller only for Exchange 2016 we will use the following powershell command now:

to set the StaticDomainControllers:

Set-ExchangeServer -Identity <server_name> -StaticDomainControllers DC-01.dc.local,DC-02.dc.local

to set the StaticGlobalCatalogs:

Set-ExchangeServer -Identity <server_name> -StaticGlobalCatalogs DC-01.dc.local,DC-02.dc.local

You should define at least two different server to avoid issues if one is down!

10.) Now we can configure the exchange directories. The names here will be the same namespace which is currently used on our “old Exchange 2010” environment, as we will change the name space later one to Exchange 2016.

10a.) The first step is to configure the ECP directory:

Set-EcpVirtualDirectory -Identity “exch01\ecp (Default Web site)” -InternalUrl https://exchange.contoso.internal/ecp -ExternalUrl https://owa.contoso.com/ecp

Set-EcpVirtualDirectory -Identity “exch02\ecp (Default Web site)” -InternalUrl https://exchange.contoso.internal/ecp -ExternalUrl https://owa.contoso.com/ecp

10b.) Now we need to configure the web services virtual directory via:

Set-WebServicesVirtualDirectory -Identity “EXCH01\EWS (Default Web Site)” -ExternalUrl https://oaw.contoso.com/EWS/Exchange.asmx -InternalUrl https://excashlb.int.contos.com/EWS/exchange.asmx
Set-WebServicesVirtualDirectory -Identity “EXCH02\EWS (Default Web Site)” -ExternalUrl https://oaw.contoso.com/EWS/Exchange.asmx -InternalUrl https://excashlb.int.contoso.com/EWS/exchange.asmx

We will also set our internal bypass url via (might not be needed in every case):

Set-WebServicesVirtualDirectory -Identity “EXCH01\EWS (Default Web Site)” -InternalNLBBypassUrl https://exch01.int.contoso.com/ews/exchange.asmx
Set-WebServicesVirtualDirectory -Identity “EXCH02\EWS (Default Web Site)” -InternalNLBBypassUrl https://exch02.int.contoso.com/ews/exchange.asmx

10c.) The next step is to configure our ActiveSync directory. We can check our old Exchange 2010 config via:

Get-ActiveSyncVirtualDirectory -Identity “excas01\Microsoft-Server-ActiveSync (Default Web Site)” | fl

And then apply the same hostnames to the new server via:

Set-ActiveSyncVirtualDirectory -Identity “exch01\Microsoft-Server-ActiveSync (Default Web Site)” -ActiveSyncServer https://ews.contoso.com/Microsoft-Server-Activesync -InternalUrl https://excashlb.int.contoso.com/Microsoft-Server-ActiveSync -ExternalUrl https://ews.contoso.com/Microsoft-Server-Activesync

Set-ActiveSyncVirtualDirectory -Identity “exch02\Microsoft-Server-ActiveSync (Default Web Site)” -ActiveSyncServer https://ews.contoso.com/Microsoft-Server-Activesync -InternalUrl https://excashlb.int.contoso.com/Microsoft-Server-ActiveSync -ExternalUrl https://ews.contoso.com/Microsoft-Server-Activesync

10d.) After that we can configure our offline address book (OAB) virtual directories. We can check our old config via:

 Get-OabVirtualDirectory “excas01\OAB (Default Web Site)” | fl

And then apply the same hostnames to the new server via:
Set-OabVirtualDirectory “exch01\OAB (Default Web Site)” -InternalUrl https://excashlb.int.contoso.com/OAB -ExternalUrl https://oaw.contoso.com/OAB
Set-OabVirtualDirectory “exch02\OAB (Default Web Site)” -InternalUrl https://excashlb.int.contoso.com/OAB -ExternalUrl https://oaw.contoso.com/OAB

10e.) After that we can configure our Office Web Access (OWA) virtual directories. We can check our old config via:

Get-OwaVirtualDirectory -Identity “excas01\owa (default Web site)” | fl

and then apply the hostnames via:

Set-OwaVirtualDirectory -Identity “exch01\owa (default Web site)” -InternalUrl https://excashlb.int.contoso.com/owa -ExternalUrl https://owa.contoso.com/owa

Set-OwaVirtualDirectory -Identity “exch01\owa (default Web site)” -InternalUrl https://excashlb.int.contoso.com/owa -ExternalUrl https://owa.contoso.com/owa

10f.) Optional: After that we will configure our powershell directories.  We can check our old config via:

Get-PowerShellVirtualDirectory -Server deffmexcas01 | fl

and then apply the hostnames via:


As we do not use this feature in this tutorial we will skip that here.

10g.) The next step is to configure the MAPI virtual directory via:

Set-MapiVirtualDirectory -Identity “exch01\mapi (Default Web Site)” -InternalUrl https://excashlb.int.contoso.com/mapi -ExternalUrl https://oaw.contoso.com/mapi

Set-MapiVirtualDirectory -Identity “exch02\mapi (Default Web Site)” -InternalUrl https://excashlb.int.contoso.com/mapi -ExternalUrl https://oaw.contoso.com/mapi

We also will now enable MAPI over http in our organization via:

Set-OrganizationConfig -MapiHttpEnabled $true

Once done we could validate the steps via the following browser URL:


10h.) The next step is to configure the same AutoDiscovery server on Exchange 2016 as we have on our Exchange 2010 server. So we can check the current config via:

Get-AutodiscoverVirtualDirectory -server “excas01” | fl

And then set it via:

Set-AutodiscoverVirtualDirectory -Identity “exch01\Autodiscover (Default Web Site)” -InternalUrl https://excashlb.int.contoso.com/autodiscover/autodiscover.xml -ExternalUrl https://oaw.contoso.com/autodiscover/autodiscover.xml

Set-AutodiscoverVirtualDirectory -Identity “exch02\Autodiscover (Default Web Site)” -InternalUrl https://excashlb.int.contoso.com/autodiscover/autodiscover.xml -ExternalUrl https://oaw.contoso.com/autodiscover/autodiscover.xml

10i.) The next configuration we need to change is for OWA. Again we could check the old config via:

Get-OutlookAnywhere -Server excas01 | fl

and then set the same hostnames (and other configuration if needed) via:

Set-OutlookAnywhere -Identity “exch01\Rpc (Default Web site)” -InternalHostname excashlb.int.contoso.com -InternalClientsRequireSsl $true -ExternalClientsRequireSsl $true -SSLOffloading $false

12.) Exchange 2016 comes with a build in Antivirus Engine, which should be configured now.

12a.) Per default the build in Exchange antivirus didn´t scan emails which are scanned by another engine (e.g. Exchange Online Protection). To add a additional layer of security we will now enforce the build in Exchange engine via:

Set-MalwareFilteringServer exch01 -ForceRescan $True

Set-MalwareFilteringServer exch02 -ForceRescan $True

12b.) Due to the reason that we do not have a Exchange Edge Server in that migration project here (we get our emails from a 3rd party server), we need to mark them as internal via (as also described here):

Set-TransportConfig -InternalSMTPServers <IP>

If we do not wish to overwrite the current config we can use the following:

Set-TransportConfig -InternalSMTPServers @{Add=”<ip address1>”,”<ip address2>”…}

12c.) To ensure the engine is up to date we could run the following:

Add-PsSnapin Microsoft.Forefront.Filtering.Management.Powershell


Which should show something like:

Engine            : Microsoft
LastChecked       : 05-06-2016 10:57:18 PM +02:00
LastUpdated       : 05-06-2016 07:57:24 PM +02:00
EngineVersion     : 1.1.12706.0
SignatureVersion  : 1.219.878.0
SignatureDateTime : 05-05-2016 10:44:18 PM +02:00
UpdateVersion     : 1605060001
UpdateStatus      : UpdateAttemptNoUpdate

If you wish to submit a new unknown virus to Microsoft you can either use Virustotal.com or directly via the Microsoft Malware Protection Center.

As these updates are not delivered via the normal windows update. Currently Microsoft provides them via http://forefrontdl.microsoft.com & http://ctldl.windowsupdate.com so you need to use a local proxy (as mentioned here) as most exchange server will not have direct access to the internet. In rare situations a proxy must be set via Set-ProxySettings for Exchange if the first way isn´t working:

Set-ExchangeServer -Identity “exch01” -InternetWebProxy http://proxyrr.int.contoso.com:3128

13.) The next step is to create our new DAG. We will use two Exchange 2016 nodes in the same side and will place the file share witness onto a 3rd stand alone file server.

13a.) At first create a folder on the 3rd server in the root, name it “WitnessDirectory” (or something like that). After that create a new folder inside that with the name from our DAG which we will create, so in the end it will look like the following:


13b.) On that 3rd server make sure you add the “Exchange Trusted Subsystem” to the local administrator group

13c.) As we use ReFS on the 2nd HD on our Exchange 2016 server we will create the dag now via:

New-DatabaseAvailabilityGroup -Name EXCHDAG01 -WitnessServer exfilesrv01.contoso.com -FileSystem ReFS -WitnessDirectory C:\WitnessDirectory\ms-exchange-dag-witness

If you get an error 0x800706BA, delete the DAG and check the following website for a solution. After you solved that issues re-create the DAG.

In Exchange 2010 and maybe in 2013 as well you build a DAG with a special IP address, in Exchange 2016 a IP less DAG is the default, so we will not use a IP [as Administrative Access Point (AAP)] here, but keep noted that your backup environment must support that configuration!

13d.) Now we need to add our members to the DAG via:

Add-DatabaseAvailabilityGroupServer -Identity EXCHDAG01 -MailboxServer exch01
Add-DatabaseAvailabilityGroupServer -Identity EXCHDAG01 -MailboxServer exch02

This might take some time, due to the reason that this command will change the configuration on both server!

Once completed check the witness directory, it should contain some folder and files now!

13e.) The next step is to check our DAG now via:

Get-DatabaseAvailabilityGroup EXCHDAG01 | fl

Get-DatabaseAvailabilityGroup EXCHDAG01 -Status | fl *witness*

13f.) If everything is fine, we can now setup the DAG replication network. Keep noted here, that our two Exchange 2016 server will use a direct connection with each other (e.g. crosslink) which is only used for the replication. So if we now run a:

Get-DatabaseAvailabilityGroupNetwork -Identity EXCHDAG01

We can see that there automatically exists two Database Availability Group Networks for our new DAG. Both are configured to be used for the replication. However we wish to enforce the replication over the replication connection rather then the IPs which are used to connect to the Exchange server. So we will pick out the network which will not be used for the replication and change that (as mentioned here) via:

Set-DatabaseAvailabilityGroup EXCHDAG01 -ManualDagNetworkConfiguration:$true

Set-DatabaseAvailabilityGroupNetwork -Identity “EXCHDAG01\MapiDagNetwork” -ReplicationEnabled:$false -IgnoreNetwork:$true

We should check our config now via:

Get-DatabaseAvailabilityGroupNetwork -Identity EXCHDAG01

13g.) The next step from our DAG configuration is now to configure the DAC-Mode (Datacenter Activation Coordination) via:

Set-DatabaseAvailabilityGroup EXCHDAG01 -DatacenterActivationMode DagOnly

13h.) In our migration scenario the replication is done via a dedicate network connection between two exchange server in two different server roomes, so we will disable compression and encryption (to save CPU as the network isn´t a bootleg here).

Set-DatabaseAvailabilityGroup -Identity EXCHDAG01 -NetworkEncryption Disabled -NetworkCompression Disabled

13i.) The next point is to change the auto mount points to drive D as we will use C only for the OS

Set-DatabaseAvailabilityGroup -Identity EXCHDAG01 -AutoDagVolumesRootFolderPath C:\ExchangeVolumes -AutoDagDatabasesRootFolderPath D:\ExchangeVolumes

13j.) for the migration we will disable the AutoDagAutoReseed via:

Set-DatabaseAvailabilityGroup -Identity EXCHDAG01 -AutoDagAutoReseedEnabled:$false

It can be later enabled / configured if needed in your environment.

13k.) Depending on your Backup environment and how you loadBalance the DBs inside the DAG you might need to allow that the backup software can backup ALL DBs on one server (if they where mounted or not). To allow that set the EnableVSSWriter DWord regestry entry created in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\V15\Replay\Parameters to “0” as explained for example here. After that you need to restart the “Microsoft Exchange Replication service” or better both Exchange server. Check the backup documentation here!

14.) The next step is to configure the SSL certificates. Due to the reason that the loadbalancer is in front of the environment and acts as primary access point for our users, we do not need to take over the “old” certificates. We can therefore create new certificates which will allow us later also to add a testuser to the environment and use the hostfile to point the old name to the new server for a short internal test. But if needed the old certificates could be taken over as well.

As the hardware loadbalancer is sitting in front of the Exchange environment this server also does the external SSL handling. So we need to add the external names later one only for the initial testing on our new Exchange certificate.

If your internal CA is still running SHA-1 instead of SHA-2 you might consider using a new CA here for security reasons!

14a.) Via the following command (might be only valid for the current howto; adjust that to your needs) we will create a new certificate request which we later one will sign with our internal CA:

New-ExchangeCertificate –DomainName excashlb.int.contoso.com,exch01.int.contoso.com,exch02.int.contoso.com,exchrr.int.contoso.com,exchdag01.int.contoso.com,owa.contoso.com,oaw.contoso.com,autodiscover.contoso.com,localhost –FriendlyName excashlb.int.contoso.com –GenerateRequest –PrivateKeyExportable $true –RequestFile “C:\00Install\SSL_Certs\certreq.txt” –Server deffmexch01 –SubjectName “cn=excashlb.int.contoso.com”

The parameter are the following:

-Server (specifies the server where we wish to generate the request)
-GenerateRequest (will prepare a 3rd party certificate request instead self-signed)
-FriendlyName(specifies what you see under the name column in the GUI)
-PrivateKeyExportable (allows you to export/import the certificate to other Exchange servers.)
-SubjectName (is the primary FQDN for the certificate)
-DomainName (are the subject alternate names for the certificate, separated via “,” without any space)
-RequestFile (specifies the export file for the certificate request)

So as we wish to use the same DNS name as currently used on the LoadBalancer which points to exchange 2010, keep noted to add these names as well. So for this howto that means we will add:

– RoundRobin (rr) entry which will contain both Exchange 2016 -> we will use them for email routing

– localhost -> To ensure we do not get a error message if we use the ECP on the local exchange server

– OWA / OAW / Autodiscover -> As we will use hostfiles later one to point directly to our new Exchange server for the test, we need the hostnames which are normally hosted on our HardwareLoadbalancer (e.g. DNS round robin) as well in the certificate

– DAG -> We will also include the Exchange DAG name inside our hostfile

– exch01/02 -> To ensure we do not get an error message when we wish to perform tests with only one Exchange server, we will include the Exchange hostnames as well

14b.) Now submit the certificate request to your internal Microsoft CA (use a website template) and once you got back the certificate store it as exchange.cer in C:\00Install\SSL_Certs

14c.) We need to complete the certificate request now and will import that certificate via:

Import-ExchangeCertificate -FileData ([Byte[]]$(Get-Content -Path C:\00Install\SSL_Certs\exchange.cer -Encoding byte -ReadCount 0))

This will show the thumbprint, you need that later one when assigning that cert to the services in the next step.

14d.) We will assign that certificate now to our exchange services. In our

Enable-ExchangeCertificate -Services IIS,IMAP,POP,SMT -Thumbprint <ID> -NetworkServiceAllowed

Note: Replace the <ID> with the thumbprint you got. You might also find that via Get-ExchangeCertificate

Enable-ExchangeCertificate -Services IIS,IMAP,POP,SMTP -Thumbprint 6C941FA21EA47AA280C54C3233F4027D7C7C32BF -NetworkServiceAllowed

Note: You are asked to replace the default SMTP certificate which we accept!

We have POP3 and IMAP disabled, but will assign the cert here so if we need to use it, its already configured by a certificate.

14e.) Now we will check our work if we open the following URLs via a web Browser the SSL cert should be fine on that server:


14f.) The next step is now to export this certificate (to import hat on our 2nd exchange server) so on our 1st server we run:

Export-ExchangeCertificate -Thumbprint 6C941FA21EA47AA280C54C3233F4027D7C7C32BF -FileName “C:\00Install\SSL_Certs\Exchange_Cert.pfx” -BinaryEncoded -Password (ConvertTo-SecureString -String ‘P@ssw0rd1’ -AsPlainText -Force)

14g.) On the 2nd exchange server place the exported certs from the 1st exchange server to C:\00Install\SSL_Certs\ then run:

Import-ExchangeCertificate -FileData ([Byte[]]$(Get-Content -Path “C:\00Install\SSL_Certs\Exchange_Cert.pfx” -Encoding byte -ReadCount 0)) -Password (ConvertTo-SecureString -String ‘P@ssw0rd1’ -AsPlainText -Force)

14h.) And then assign the same services as we have done on 01 to that cert. As the thumbprint is the same, we can run exactly the same commands as already for 01:

Enable-ExchangeCertificate -Services IIS,IMAP,POP,SMT -Thumbprint <ID> -NetworkServiceAllowed

Enable-ExchangeCertificate -Services IIS,IMAP,POP,SMTP -Thumbprint 6C941FA21EA47AA280C54C3233F4027D7C7C32BF -NetworkServiceAllowed

15.) We will now configure the OWA directory. To do that we will check our old Exchange 2010 configuration via:

Get-OwaVirtualDirectory “excas01\owa (default Web site)” | fl

and then apply the same to the new server.

15a.) The first we will do is to configure the OWA features (e.g. default domain, the logon format, …) via:

Set-OwaVirtualDirectory “exch01\owa (default Web site)” -DefaultDomain EMEA -LogonFormat UserName -LogonPagePublicPrivateSelectionEnabled $true -LogonPageLightSelectionEnabled $true -LogonAndErrorLanguage 1033 -IRMEnabled $false -ThemeSelectionEnabled $false -PublicFoldersEnabled $false -TextMessagingEnabled $false -AnonymousFeaturesEnabled $false -AllowOfflineOn NoComputers

Set-OwaVirtualDirectory “exch02\owa (default Web site)” -DefaultDomain EMEA -LogonFormat UserName -LogonPagePublicPrivateSelectionEnabled $true -LogonPageLightSelectionEnabled $true -LogonAndErrorLanguage 1033 -IRMEnabled $false -ThemeSelectionEnabled $false -PublicFoldersEnabled $false -TextMessagingEnabled $false -AnonymousFeaturesEnabled $false -AllowOfflineOn NoComputers

Adjust so that it fits your requirements!

15b.) The next step is to configure the OWA authentication options. This is done via:

Set-OwaVirtualDirectory “exch01\owa (default Web site)” -WindowsAuthentication $true

Set-OwaVirtualDirectory “exch02\owa (default Web site)” -WindowsAuthentication $true

16.) The next step is to configure the ECP directory.

16a.) Set the same authentication options we enabled already for OWA:

Set-EcpVirtualDirectory -Identity “exch01\ecp (Default Web site)” -WindowsAuthentication $true

Set-EcpVirtualDirectory -Identity “exch02\ecp (Default Web site)” -WindowsAuthentication $true

16b.) To finish that we need to restart the IIS now on both exchange server.

17.) Now its the first time we can login into our console (https://<Exchange2016MailboxServer>/ecp) keep noted, that if you get a ‘500 Unexpected Error’ or end up with the 2010 or 2013 version of the ECP try to use the URL https://<Exchange2016MailboxServer>/ecp?ExchClientVer=15.1 (as mentioned here). If that works you can follow the next steps outlined below.

18.) We will now create our fist MailDatabase in our DAG. This can be done via:

New-MailboxDatabase -Server exch01 -Name “EXCHMB1-DE-5GB” -EdbFilePath D:\MailboxDatabases\EXCHMB1-DE-5GB\MEXCHMB1-DE-5GB.edb -LogFolderPath D:\MailboxLogs\MEXCHMB1-DE-5GB

After that we need to restart the “Microsoft Exchange Information Store” service on our 1st Exchange 2016 server via:

Restart-Service MSExchangeIS

After that we can mount the MailDB via:

Mount-Database -Identity “exch01.int.contoso.com\EXCHMB1-DE-5GB”

We need to wait now some time until our new MailDB object (AD object) is replicated, once done we can add it to our DAG via:

Add-MailboxDatabaseCopy -Identity EXCHMB1-DE-5GB -MailboxServer exch02

Then we need to restart the “Microsoft Exchange Information Store” service on our 2nd Exchange 2016 server via:

Restart-Service MSExchangeIS

Now check if the DB is healthy on both server. If the DB didn´t come up correctly (Content index state = FailedAndSuspended ) you can run a:

Update-MailboxDatabaseCopy -Identity EXCHMB1-DE-5GB\exch02 -CatalogOnly

19.) As we have now DAG mailboxes, the next step is to move our default databased from the default created DBs on 01 and 02.

19a.) At first make sure you can see system (e.g. Arbitration) mailboxes, which are created on the root domain by default. So include out whole domain via:

Set-AdServerSettings -ViewEntireForest $True

19b.) Then check the default Mailbox Datbases (e.g. Mailbox Database <NUMBER>) for DBs you need to move via:

Get-Mailbox -Database <Database ID>

Move also all “system” mailboxes via that approach as explained here and here.

20c.) After that is done we can remove the default created MailDBs (one per Exchange) via:

Remove-MailboxDatabase -Identity “Mailbox Database 1641375995”

Remove-MailboxDatabase -Identity “Mailbox Database 1314096048”

If you get a error message according the monitoring databases you can check here for more infos.

After that cleanup the folder “C:\ProgramFiles\Microsoft\Exchange Server\V15\Mailbox\” on both new Exchange server (create a backup from and then delete the files).

20.) In the next step we will configure the Offline Addressbook (OBA), as Exchange 2016 created a new default Offline Addressbook for the whole organization as seen via:

Get-OfflineAddressBook | FT Name,IsDefault,ExchangeVersion

For our environment we will configure one from scratch.

20a.) Create a new Exchange Addressbook that uses Web-based distribution for Microsoft Outlook by using the default virtual directory via

New-OfflineAddressBook -Name “EMEA Default Offline Address Book” -AddressLists “\Default Global Address List” -VirtualDirectories “exch01\OAB (Default Web Site)”

20b.) As we run a cluster we need to add our 2nd Server as well via:

$Ex2016OABServer = @(“exch01\OAB (Default Web Site)”,”exch02\OAB (Default Web Site)”)
Set-OfflineAddressBook -Identity “EMEA Default Offline Address Book” -VirtualDirectories $Ex2016OABServer

20C.) Optional: If you wish to use lists, you can add them via the following way:

$Ex2016AddresLists = @(“\Default Global Address List”)

Set-OfflineAddressBook -Identity “EMEA Default Offline Address Book” -AddressLists $Ex2016AddresLists

20d.) Per default an arbitration mailbox with Persisted Capability “OrganizationCapabilityOABGen” is responsible for OAB generation. This mailbox can be found via:

Set-ADServerSettings -ViewEntireForest $true


Get-Mailbox -Arbitration | where {$_.PersistedCapabilities -like “*oab*”} | ft name,servername


Get-Mailbox -Arbitration | where {$_.PersistedCapabilities -like “*oab*”} | ft name,database

depending on your environment (as explained here). If you wish to use another dedicated mailbox (e.g. in a different region) you need to create one (as explained here). Create at first a new AD account (disable the account), then run:

Enable-Mailbox -Arbitration -Identity EMEA\exoabmbox.1 -Database EXCHMB1-DE-5GB

Once done you can check the details via:

get-mailbox -Arbitration -Identity “EMEA Exchange OAB Mailbox” | fl

and Enable OABGen capability via:

Set-Mailbox -Identity “contoso.com/Administration/Taskuser/EMEA Exchange OAB Mailbox” -Arbitration -OABGen $true

The last step is to configure the OAB created above to use this new mailbox via:

$mbx = get-mailbox -Identity “emea.tpg.ads/Administration/Taskuser/EMEA Exchange OAB Mailbox” -arbitration
Set-OfflineAddressBook “EMEA Default Offline Address Book” -GeneratingMailbox $mbx.Identity

19e.) By default, a new OAB is generated every 8 hours in Exchange Server 2016 (as written here). To change that (e.g. to every 5 hours) the following can be used:

New-SettingOverride -Name “EMEA OAB Generation Override” -Component MailboxAssistants -Section OABGeneratorAssistant -Parameters @(“WorkCycle=05:00:00”) -Reason “Generate OAB every 5 hours” -Server exch01

As we have two server we need to configure it to use both exchange 2016 server via:

$Ex2016OABSRV = @(“exch01″,”exch02”)

Set-SettingOverride -Identity “EMEA OAB Generation Override” -Server $Ex2016OABSRV

Which build a setting override only on the two new exchange server. Additional to that we will set the OAB values (OABGeneratorWorkCycle & OABGeneratorWorkCycleCheckpoint) for the exchange server. The OABGeneratorWorkCycle tells Exchange that the OAB generation cycle should be completed within that time period. The OABGeneratorWorkCycleCheckpoint tells Exchange how often he need to check for anything new to do.

Note: “Set-OfflineAddressBook ‘EMEA Default Offline Address Book’ -Schedule ‘Mo.02:00-Mo.22:00′” nor “Set-MailboxServer -Identity deffmexch01 -OABGeneratorWorkCycle 02:00:00 -OABGeneratorWorkCycleCheckpoint 04:00:00” worked for me! As this part from Exchange 2016 is missing in the official documentation its not totally clear if the approach above is the correct way!

 20f.) Update the addressbook via

Update-OfflineAddressbook -Identity “EMEA Default Offline Address Book”

20g.) Now assign the new Adressbook to every Exchange 2016 MailDB (per GUI) or via Powershell:

Get-MailboxDatabase -Server exch01 | Set-MailboxDatabase -OfflineAddressBook “EMEA Default Offline Address Book”

21.)The next step is to setup the SMTP option.

21a.) At first set the “Maximum receive message size” to the value we already use on our Exchange 2010 environment. To do that go the the ECP and click on “mail flow” then on “receive connectors” open the config from our new created servers, and adjust the “Maximum receive message size”.

21b.) Configure now the receiver connectors. In our scenario we didn´t use the receiver connectors which are configured on the Exchange 2016 server for the role “FrontendTransport”. So we will disable that via GUI.

21c.) Make also sure you configured the send connectors on both Exchange 2016 server correctly.

22.) Now make sure that no user had mapi over HTTP disabled. You can find such users via:

Get-CASMailbox -ResultSize Unlimited | where { $_.MAPIBlockoutlookRpcHttp -eq ‘True’}

Keep noted that in big szenarios this might take longer and you might wish to pipe that to a text file. If you wish to unblock all users you can also use:

Get-CASMailbox -ResultSize Unlimited | where { $_.MAPIBlockoutlookRpcHttp -eq ‘True’} | Set-CASMailbox -MAPIBlockoutlookRpcHttp $False

23.) The last step is now to perform some connection tests via:


Test-OutlookConnectivity -RunFromServerId exch01 -ProbeIdentity OutlookMapiHttpSelfTestProbe


24.) As our Exchange 2016 Server is nor ready, you should run Jetstress against the server (to simulate some workload) and can use some hostfiles to test the connection. So setup an test computer with Office (fully patched).

24a.) Then use the hostfile to point the current Exchange namespace towards the exchange 2016 environment (you can check here: http://exchangeserverpro.com/testing-connectivity-and-dns-changes-with-a-hosts-file/). Test also to backup a mailfile and restore a mailfile!

24b.) Test if the Exchange 2010 user can successfully fetch emails via the Exchange 2016 environment which will act as an proxy. You can also create a new user on Exchange 2016 to test if newly created users can access the environment. You should at least test an Outlook and an OWA connection. If you see connection issues here check the following article.

25.) Once you are happy with the setup you can switch the namespace from Exchange 2010 towards Exchange 2016. It should start to proxy connections now via the Exchange 2016 environment towards the Exchange 2010 environment.

26.) Optional: Now use https://exchangeanalyzer.com/ to check the server

27.) When you are happy with the setup you can start moving the Exchange 2010 mailboxes to Exchange 2016 as explained here. Keep noted that Exchange (if not changed) cache the old connection for arround 12 hours. You need to recycle an pool as mentioned here.

28.) Optional: To move public folder (which we didn´t covered here) check the following technet article.

29.) Optional you could enable folder compression (as explained here) for the IIS log folder:



Other useful resources:

Client Connectivity in an Exchange 2016 Coexistence Environment with Exchange 2010

Exchange Server Deployment Assistant

– Troubleshooting Client access (German)


After the installation finished, you might check the following blog postings:

– “Could not load file or assembly AntiXSSLibrary” on Exchange 2016

– “Microsoft Exchange Notifications Broker” as stopped and giving a red error in the dashboard

– Failed to detect the bitlocker state for EDS log drive

– Exchange 2013/2016 hub transport “Mail.que” file large in size

Related Articles


Please enter your comment!
Please enter your name here

Stay Connected

- Advertisement -

Latest Articles