Exchange 2016 Migration to Exchange 2019

KB ID 0001472

Exchange 2019 Migration

If Exchange 2016 was Exchange 2013 in a pretty dress, then with Exchange 2019 it’s simply added a hat. In the past, every third Exchange release was a major rebuild, but Exchange 2016 is simply Exchange version 15.1 (Exchange 2013 was 15.0 and Exchange 2016 is version 15.1).

So the Migration to Exchange 2019 is pretty much the same as it was from 2013 > 2016, or even 2016 > 2016. 

  •  There should be NO Exchange 2010 servers in existence before deploying Exchange 2019. You would need to upgrade to 2013/2016 first.
  • There’s no Unified Comms Role with Exchange any more! If you need to upgrade look at Skype for Business 2019.
  • Edge Server Role is still supported.
  • Windows Server Core (2016) is now supported with Exchange 2019.
  • Windows Server 2019 (Standard or Datacenter) are supported host Operating systems.


As with all Exchange migrations make sure your Active Directory Domain/DNS/Existing Exchange organisation is healthy before you start. Then upgrade the existing Exchange to the latest cumulative update.

Exchange 2016 Upgrade

Exchange 2019 Prerequisites

You will need your Server 2012R2 or Server 2016 server fully updated and added to your domain, then to add the required roles and services use the following Powershell commands for Server 2012, 2016 and 2019;

Server 2016 / 2012 R2

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, RSAT-ADDS

Server 2019

Install-WindowsFeature 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, RSAT-ADDS

Exchange 2019 Prerequisites

Note: Not Required on Server 2019: You will need to install .Net 4.7.2 (link), on Server 2016 and 2012.

Install Net 4 7 1

You need to install the MS Unified Communications API 4.0 (link).

Install Unified Communication API

You will also need to install Microsoft Visual C++ (link)

Exchange 2019 Install Visual C++

Either download the Exchange 2019 install media, or insert the Exchange 2019 DVD, and launch setup.exe > Next > Next > Files will be copied over.

Don’t I need to extend the schema, forest or domain? The setup does all this for you, you don’t need to do this manually anymore, (yes you can manually do this before installing, if you want to, but unless your schema master is in a different root domain, or you’re not a schema admin, then I don’t see the point!)

Setup Exchange 2019 Server

Introduction Page > Next > At the EULA tick “I Accept…” > Next > Tick “Use Recommended settings” > Next.

Migrate To Exchange 2019 Server

Select ‘Mailbox role’, and ‘Automatically install Windows Server roles and features…” > Next > Select the install directory, Note: In production you probably DON’T want this on the Windows System drive > Next > Unless you have a reason to disable Malware scanning then select ‘No’ > Next.

Migrate To Exchange 2019 Prerequisites

Readiness Checks > Fix and Errors and heed any warnings > Install > The product will install, this will take a long time!

Install Microsoft Exchange 2019

Finish > Reboot the server.

Install Exchange 2019

An there’s our new Exchange 2019 Server.

Show Exchange 2019

Exchange 2019 EnterProduct Key

Servers > Servers > Select the 2019 Exchange Server > Enter Product Key  > Save

Note: On the pre-release version of Exchange 2019, the Exchange 2016 keys worked fine.

Exchange 2019 Product Key

At the warning click OK.

Exchange 2019 Information Store Licence Warning

As directed Restart the ‘Microsoft Exchange Information Store’ service.

Restart-Service MSExchangeIS

Restart Information Store Service

Transfer Exchange Certificate to Exchange 2019

I’m using a wildcard certificate so I want to export the cert form my Exchange 2016 server and import it onto my new Exchange 2019 Server. You will want to do the same if you have a certificate with your public domain name on it and this will be your ‘internet facing’ Exchange server. Servers > Certificates > Select the Exchange 2016 Server, in the drop down menu > Select The Certificate > Click the ellipses (three dots) > Export Exchange Certificate > Supply a UNC path and password > OK.

Export Exchange Certificate

Change the Dropdown to the Exchange 2019 Server > Click the ellipsis > Import Exchange Certificate > Supply the UNC path and password you used (above) > Next.

Import Exchange Certificate

Add in the Exchange 2019 Server > Finish.

Import Exchange 2019 Certificate

Exchange 2019 Assign Services to Certificate

Select the newly imported certificate> Edit > Services > Select the services > Save > Note: Here I’m selecting SMTP and IIS. (You cant use a wildcard cert for IMAP,POP).

Assign Services Exchange 2019 Certificate

Exchange 2019 Rename Mailbox Database

Servers > Databases > Exchange always gives databases annoying names > Select the Database on the 2019 Exchange Server > Edit > Rename it  > Save.

Note: The path to the Database retains the original name (we will fix that in the next step).

Rename Exchange 2019 Database

Exchange 2019 Move Mailbox Database

I’m pretty old school, I like my Exchange databases on their own drive/partition, and I like the logs on another drive/partition. To move both the Database and the Logs;

Move-DatabasePath -Identity Database-Name -EdbFilePath X:\Folder\Database\Database-Name.edb -LogFolderPath L:\Folder\Log-Folder\

Move Exchange 2019 Database and Logs

Add Exchange 2019 to the Send Connector

Mail Flow > Send Connectors > Select your mail SMTP connector(s) > Edit > Scoping > Source Server section > Add > Add in the new server > OK > Save.

Note: The Exchange server will now need to have TCP port 25 (SMTP) open outbound on your corporate firewall.

Exchange 2019 Send Connector

Decommission Exchange 2016

From this point forward we are going to start getting rid of our Exchange 2016 server, they can of course coexist, (if you wanted to wait a while).

For that reason I change the ‘mail flow’ on the firewall to point to the new Exchange server at this point, and the HTTP access for OWA, Outlook Anywhere,  and Phone/Tablet access

Exchange 2019 Mailbox Migration

Yes you can do this in the EAC, but I prefer to do this in PowerShell. But If I don’t put this here, I’ll get emails! Recipients > Migration  > Add > Move to a different Database > Add in the mailboxes/users > Next.

Exchange 2019 Migrate Mailboxes

Give the ‘Batch’ a name > Select to move Archive mailboxes (if you have them) > Select the destination (Exchange 2019) Database > Again if using archive mailboxes, select the target archive mailbox database > Set the bad Item limit to 99 > Next > Select Automatically Start > Select Automatically Finish > New. 

Exchange 2019 Mailbox Migration

From this point, this is where I don’t like the EAC it takes AGES to update with progress! From the Exchange Shell you can get an up to date view of that is going on!

Get-MoveRequest | Get-MoveRequestStatistics

Exchange 2019 Mailbox Migration Progress

For a better list of commands for moving user mailboxes, and monitoring the migration, and removing the move requests when you are finished, see the following article;

Exchange: PowerShell Commands

Migrating Exchange System Mailboxes

Before you start issue the following command;

Set-AdServerSettings -ViewEntireForest $true

In addition to the user mailboxes there are a multitude of different ‘System mailboxes’ that might be hanging around, before we can get rid of the Exchange 2016 Database we need to migrate those.

Firstly AuditLog Mailboxes

Get-Mailbox -AuditLog -Database “Mailbox-Database-2016

If there are any!

Get-Mailbox -AuditLog -Database “Mailbox-Database-2016” | New-MoveRequest -TargetDatabase “Mailbox-Database-2019

Exchange Move AuditLog Mailbox

Then Arbitration Mailboxes

Get-Mailbox -AuditLog -Database “Mailbox-Database-2016” -Arbitration

If there are any!

Get-Mailbox -AuditLog -Database “Mailbox-Database-2016” -Arbitration | New-MoveRequest -TargetDatabase “Mailbox-Database-2019

Exchange Move Arbitration Mailbox

Then Monitoring Mailboxes

Get-Mailbox -Monitoring -Server “Mail-2016

If there are any!

Get-Mailbox -Monitoring -Server “Mail-2016” | New-MoveRequest -TargetDatabase “Mailbox-Database-2019

Exchange Move Monitoring Mailbox

Make sure there are no archive mailboxes;

Get-Mailbox -Auditlog -Database “Database-Name” -Archive

If there are, move them, (as above.)

Also move any  Discovery mailboxes, and move them to 2019;

Get-Mailbox DiscoverySearchMailbox* | New-MoveRequest -TargetDatabase “Mailbox-Database-2019

Delete Exchange 2016 Database(s)

When you are 100% sure theres nothing left on the old database(s) remove them;

Get-MailboxDatabase -Identity “Mailbox-Database-2016” | Remove-MailboxDatabase

Exchange 2016 Delete Mailbox Database

Uninstall Exchange 2016

Your install directory may not be on the C: drive so change your path accordingly;

cd “C:\Program Files\Microsoft\Exchange Server\V15\Bin

setup.exe /mode:uninstall

Uninstall Exchange Command Line

At this point make sure your backup/replication software is pointed to the new Exchange 2019 Server.

Related Articles, References, Credits, or External Links


Author: PeteLong

Share This Post On


  1. Nice Article and well explained

    Post a Reply
    • Has anyone had any issues with users being unable to view ‘Free/Busy’ of users who have been migrated? This is not the initial issue of not being able to see free/busy after migration unless you restart the App Pools. This is users who have not been migrated not being able to view the migrated users even after full server reboots.

      We have been searching everywhere and have not been able to find a resolution. I guess there are not many people who have done the migration yet, but would be interested if anyone has experienced the same issue and if they found the resolution.

      At the moment we are having to suggest to users to change their default calendar permissions to reviewer during the migration period which is not ideal.

      Post a Reply
      • We are having the same issue and Exchange 2016 users are unable to see the free/busy of Exchange 2019 test users. Typically, this direction of free/busy works, but for some reason there is something that is not right. Been troubleshooting for a few weeks but have not found the resolution yet.

        I notice this post is a few months old. Has there been resolution to the free/busy issues you have been having?

        Post a Reply
        • We are having the same issue. Users still on Exchange 2016 could not see free/busy on the migrated user (to Exchange 2019). Change default calender permission to reviewer works but is no good solution. Very interested in a solution for that.

          Post a Reply
      • I also came across the free/busy issue with 2019 when migrating a customer on 2016. Exchange 2019 / Server 2019 has TLS 1.2 enabled by default. This is the issue with the free/busy info not displaying for 2019 mailbox users. To resolve this, you have to add/merge in some registry entries and then restart the 2016 servers to enable TLS 1.2. The only other workarounds are to lower TLS to 1.1 on the 2019 servers (less secure) or, as a previous poster mentioned, add Reviewer rights to the default calendar permissions on the mailboxes. TLS 1.2 is the way to go.

        Post a Reply
  2. Great write up, thanks very much!

    One thing I’d add is to remember to check your Public Folder mailbox and migrate that before deleting the old servers’ database.

    Post a Reply
  3. For the step about the Monitoring Mailboxes (Get-Mailbox -Monitoring -Server “Mail-2016”), I’ve got several HealthMailbox items that are taking forever to migrate.

    I thought those were server- or database-specific.

    Do those really even need to be migrated, or can they just be removed or ignored?

    Post a Reply
    • You can delete them (if the old server is being retired) they are auto created 🙂


      Post a Reply
  4. What about setting all the URL’s / URI’s?

    I’d suggest running this PS script to check them all then updating where needed.

    Start-Transcript log0.txt
    Get-OabVirtualDirectory | fl server, Name, *URL*, *auth*
    Get-WebServicesVirtualDirectory | fl server, Name, *URL*, *auth*
    Get-EcpVirtualDirectory | fl server, Name, *URL*, *auth*
    Get-ActiveSyncVirtualDirectory | fl server, Name, *URL*, *auth*
    Get-OutlookAnywhere | fl server, Name, *URL*, *hostname*, *auth*
    Get-OwaVirtualDirectory | fl server, Name, *URL*, *auth*
    Get-ClientAccessServer | fl Name, OutlookAnywhereEnabled, AutodiscoverServiceInternalUri
    Get-ExchangeCertificate | fl FriendlyName, Subject, CertificateDomains, Thumbprint, Services, Issuer, *not*
    Get-MapiVirtualDirectory | fl server, Name, *URL*, *auth*
    Get-ClientAccessArray | fl
    Get-ExchangeServer | fl *version*
    Get-OrganizationConfig | fl *mapi*

    Post a Reply
  5. What is best practice (or best timing I guess) for keeping existing server name and IP. For example if 2016 is currently MailServ.domain.local with, then I add 2019 server of MailServ01.domain.local with Once 2016 is decommissioned can I just change ip and name, reboot, and bobs your uncle?

    Post a Reply
    • Hi Matt, The server name is not really important. as long at the service URLs are the same (of have been repointed) I’ve never needed to retain an Exchange host name?

      Post a Reply
  6. Thank you! This guide is very helpful! I just have one question.

    Is this for installing Exchange 2019 ON TOP OF a CURRENT Exchange 2016 server, or is this for deploying a brand new server into the environment?

    Post a Reply
    • New Server – it’s always the best way with Exchange 🙂

      Post a Reply
  7. Excellent article, thank you!
    We are currently running Exchange Server 2013 CU16.
    Do we need to upgrade Exchange to the latest 2013 version CU22, before migrating to Exchange 2019 ?

    Post a Reply
    • ALWAYS, bring the oldest Exchange up to the latest CU before deploying the new version 🙂


      Post a Reply
  8. Great write up – thank you!
    What considerations are added if I have a three server DAG that I’m looking to upgrade from 2013 to 2019?
    I’m guessing that I need to remove the DAG and reduce to one server first, but wanted to make sure.

    Post a Reply
    • I’ve not done one (from 2013 to 2019), but I’ll throw this up for anyone else to comment.

      Post a Reply
  9. Hi,

    Great article! Thanks for the write-up.

    Based on the mailbox movement and design of Exchange 2016 and 2019, do mailbox moves between 2016 and 2019 cause Outlook to need to be restarted, or does it quietly and automatically shift to the new server in a stateless way? Based on what I’ve read about the architecture of the ClientAccessServices on Exchange 2016 for fail-over / DAG — a mailbox move should be stateless, but I’ve seen nothing to confirm or deny that.


    Post a Reply
    • I agree, it should not matter, the worst that’ll happen is, the user will gets a “an administrator has made changes to your mailbox, that require you to restart Outlook’ popup.



      Post a Reply
  10. Hi,

    Im currently migration Exchange 2013 CU22 to Exchange 2019. After the installation of Exchange 2019 i cant transfer/check te certificates via ECP. The following message appears
    The Exchange Certificate operation has failed with an exception on server SV-EX01. The error message is: Access is denied.

    When i type Get-ExchangeCertificates in the management powershell i do see the certificates
    Im logging in with the built-in Administrator account in ECP. Any1 has a clue what is going on?

    Post a Reply
    • Found the solution.
      Adding Exchange Trusted Subsystem to the local administrator group on the new Exchangeserver fixed it.

      Post a Reply
  11. Hello guys
    I´m gonna to migrate all users from Exchange 2013 to Exchange 2019 but I have issue with one mailbox when i run commando “new-moverequest user -targetdatabase DB1” and there is culture not supported. I checked Adsiedit and attribute msexchuserculture is correct en-US but i still get error:
    The call to ‘net.tcp:// (15.0.1395.0 caps:0400001F7FFFFFCB07FFFF)’ failed. Error details: Culture is not supported.
    Parameter name: culture
    4096 (0x1000) is an invalid culture identifier..
    + CategoryInfo : NotSpecified: (:) [New-MoveRequest], RemoteTransientException
    + FullyQualifiedErrorId : [Server=exch2019,RequestId=597c38e1-4490-47e4-8fbf-bef40c251031,TimeStamp=13/08/2019 12
    :43:36] [FailureCategory=Cmdlet-RemoteTransientException] D0F6239B,Microsoft.Exchange.Management.Migration.Mailbox
    + PSComputerName: exch2019,
    Can someone help me please? Thanks for perfekt article btw!!!
    Regards Darko

    Post a Reply
  12. This is a beautiful migration plan, thank you very very much!!!!
    It worked great for my 2013 to 2019 migration

    In case others encounter this, when using the Exchange Admin Center from the new Exchange 2019 server it is necessary to append the version to the URL to insure you are getting the right features and functionality during the co-existence:


    This drove me crazy for days until I ran across another person having other issues.

    Post a Reply

Submit a Comment

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