Exchange 2016 Migration Checklist (with PowerShell Examples)

Recently, I have been working on Exchange migration projects and the “70-345 – Designing and Deploying Microsoft Exchange Server 2016” exam. (Yes. I have passed the exam, thankfully, and I am now a certified MCSE of the Productivity track.) I have found video lessons on Pluralsight to be of great help, such as this one. Based on studies, a checklist including PowerShell commands has been crafted in the hopes of easily keeping track of milestones throughout similar projects. Except where noted, the example is for non-HA migration scenario from Exchange 2010 and 2013 to 2016. (This document is also available on GitHub as “exchange-2016-migration-checklist.md”).
Need a Pluralsight referral code? Here's my referral URL: http://referral.pluralsight.com/mQgdSmZ for a discount (up to 50%) in Pluralsight registration(Last updated: 16 April 2020)
Inventorying Existing Environment
- List existing Exchange servers in the environment
- Get-ExchangeServer | ft Name, Edition, AdminDisplayVersion, ProductId, IsExchangeTrialEdition | ft -autosize -wrap
- Get-Command ExSetup | ForEach {$_.FileVersionInfo}
- Have an estimation of how many mailboxes on each existing Exchange server
- Get-Mailbox | Group-Object -Property:Database | Select Name,Count | ft -auto
- Collect AD forest functional level info
- Get-ADForest
- Collect domain controller version in AD
- Get-ADDomainController | Select Name, OperatingSystem
- Client Access Namespace (used by client to connect to Exchange)
- Inventory PowerShell – Collect internal and external domain names for each of the below
- Autodiscover (SCP)
- Get-ClientAccessServer | Select Identity,AutoDiscoverServiceInternalUri
- Outlook Anywhere (RPC over HTTPS)
- Get-OutlookAnywhere -ADPropertiesOnly | Select Server,Internalhostname,Externalhostname
- Get-OutlookAnywhere -ADPropertiesOnly | Select Identity, *Auth* | fl
- OWA
- Get-OWAVirtualDirectory -ADPropertiesOnly | Select Server,InternalURL,ExternalURL
- Get-OWAVirtualDirectory -ADPropertiesOnly | Select Identity,*Auth* | fl
- ECP
- Get-ECPVirtualDirectory -ADPropertiesOnly | Select Server,InternalURL,ExternalURL
- Get-ECPVirtualDirectory -ADPropertiesOnly | Select Identity,*Auth* | fl
- Offline Address Book (OAB)
- Get-OABVirtualDirectory -ADPropertiesOnly | Select Server,InternalURL,ExternalURL
- Get-OABVirtualDirectory -ADPropertiesOnly | Select Identity,*Auth* | fl
- Exchange Web Services (EWS)
- Get-WebServicesVirtualDirectory -ADPropertiesOnly | Select Server,InternalURL,ExternalURL
- Get-WebServicesVirtualDirectory -ADPropertiesOnly | Select Identity,*Auth* | fl
- MAPI/HTTP
- Get-MAPIVirtualDirectory -ADPropertiesOnly | Select Server,InternalURL,ExternalURL
- Get-MAPIVirtualDirectory -ADPropertiesOnly | Select Identity,*Auth* | fl
- ActiveSync
- Get-ActiveSyncVirtualDirectory -ADPropertiesOnly | Select Server,InternalURL,ExternalURL
- Get-ActiveSyncVirtualDirectory -ADPropertiesOnly | Select Identity,*Auth* | fl
- Autodiscover (SCP)
- Inventory PowerShell – Collect internal and external domain names for each of the below
- SSL Certificates
- For Exchange ActiveSync, Outlook Anywhere, Outlook Web App, etc.
- Requirements
- Matches the server name to which clients connect
- Still within validity period
- Issued by a trusted certificate authority
- Reusing existing certificates for new Exchange server is acceptable
- Provided that client connect to an alias address instead of addresses specifying server hostnames (e.g. mail.company.com instead of EXCH13.company.com)
- Inventory PowerShell
- Take note of output with W which are certificates for IIS (not I which are for IMAP)
- Get-ExchangeCertificate
- Take note of CertificateDomains which are covered by the domain, and the validity status
- Get-ExchangeCertificate -Thumprint <From_Above_Command> | fl
- Take note of output with W which are certificates for IIS (not I which are for IMAP)
- Mailbox Storage Quotas
- Beware of default mailbox quota – For Exchange 2016, it is 2GB by default
- Mailbox migration fails if size exceeds target database
- New databases should be configured with same or larger quotas
- Inventory PowerShell (second command supports querying Exchange 2010, if exists, from newer Exchange Management Shell)
- Get-MailboxDatabase | Select Name,*Quota*
- Get-MailboxDatabase -IncludePreExchange2013| Select Name,*Quota*
- Beware of default mailbox quota – For Exchange 2016, it is 2GB by default
- Email Routing Topology and Transport
- Internal mail flow between supported Exchange servers (Exchange 2010 <> 2013 <> 2016) is automatic (no further configuration required)
- Inbound mail flow from the Internet
- Acquire internal DNS MX record:
- Resolve-DnsName -Type MX -Name company.com -Server <internal_DNS>
- Resolve-DnsName -Type A -Name mail.company.com -Server <internal_DNS>
- Alternatively
- nslookup -> server internal_DNS_Server -> set type=MX -> company.com
- nslookup -> server internal_DNS_Server -> set type=A -> mail.company.com
- Acquire external DNS MX and A record (or using www.mxtoolbox.com):
- Resolve-DnsName -Type MX -Name company.com -Server 8.8.8.8
- Resolve-DnsName -Type A -Name mail.company.com -Server 8.8.8.8
- Alternatively
- nslookup -> server 8.8.8.8 -> set type=MX -> company.com
- nslookup -> server 8.8.8.8 -> set type=A -> mail.company.com
- Acquire internal DNS MX record:
- Outbound mail flow to the Internet
- Acquire info of Send Connectors (for Outbound email)
- Get-SendConnector
- Get-SendConnector | fl
- Watch out for SmartHosts and SmartHostsString to check whether there is any use of a smart host (it should be empty if not)
- Watch out for SourceTransportServer to check whether the source transport servers that are currently in use (i.e. existing Exchange servers)
- Acquire info of Send Connectors (for Outbound email)
- Involves any non-Exchange servers? Internal application may send email via relay connectors
- Check devices, services and applications which use SMTP services
- Backup applications which send notifications (e.g. Veeam, Backup Exec)
- Anti-malware or anti-spam (e.g. Symantec Endpoint Protection Manager)
- Virtualization (e.g. vCenter, System Center Virtual Machine Manager)
- Voice or telephony
- SMS or fax gateways
- Acquire info of Receive Connectors (for Relay connectors)
- Get-ReceiveConnector -Server <Server_Name>
- Look for anything other than the below, which probably states "Relay" or something with an address binding or {0.0.0.0:25}
- For Exchange 2010, ignore "Default <Server_Name>" and "Client <Server_Name>"
- For Exchange 2013, ignore "Default <Server_Name>", "Client Proxy <Server_Name>", "Default Frontend <Server_Name>", "Outbound Proxy Frontend <Server_Name>", "Client Frontend <Server_Name>"
- Get-ReceiveConnector -Server <Server_Name>
- Once found out, look for the remote IP Ranges of it (i.e. IP addresses which are allowed to relay email via that Exchange server
- Get-ReceiveConnector "Server_Name\Receive_Connector_Name" | Select RemoteIPRanges
- Once an IP address is acquired, perform PTR DNS lookup using nslookup to find out its hostname/FQDN
- nslookup <IP_address>
- Check devices, services and applications which use SMTP services
- Maximum allowed message size of Receive Connector
- Get-ReceiveConnector | Select Identity,MaxMessageSize
- Public Folders
- Inventorying existing public folders and existing Exchange Server
- Get-PublicFolder -Recurse | Export-Clixml C:\PFMigration\Legacy_PFStructure.xml
- Acquire existing pubic folder statistics
- Get-PublicFolderStatistics | Export-Clixml C:\PFMigration\Legacy_PFStatistics.xml
- Acquire public folder permissions
- Get-PublicFolder -Recurse | Get-PublicFolderClientPermission | Select Identity, User -ExpandProperty AccessRights | Export-Clixml C:\PFMigration\Legacy_PFperms.xml
- Check if existing public folder names have backslash character which is invalid
- Get-PublicFolderStatistics -ResultSize Unlimited | Where {$_.Name -Like "*\*"} } | fl name,identity
- Watch out for existing pubic folder migration job
- Get-OrganizationConfig | fl PublicFoldersLockedforMigration,PublicFolderMigrationComplete
- Inventorying existing public folders and existing Exchange Server
- Other
- Collect information on arbitration mailboxes
- Get-Mailbox -Arbitration | Select name,database
- Check whether Outlook Anywhere is enabled (on all servers)
- Get-ClientAccessServer | Select Name,OutlookAnywhereEnabled
- Check organization config e.g. whether MAPI over HTTP is enabled per Microsoft Docs
- Get-OrganizationConfig
- Get-OrganizationConfig | fl *mapi*
- Check CAS mailbox e.g. whether OWA, ActiveSync, POP3, IMAP, MAPI over HTTP, etc. is enabled per mailbox
- Get-CasMailbox
- Get-CasMailbox | ft name, *mapi*
Basic Health Checking
- Check service health
- Test-ServiceHealth
- Get a count of current email messages in mail queue on Hub Transport servers
- Get-Queue
- Check MAPI Connectivity
- Test-MAPIConnectivity
- Validates that the RPC/HTTP endpoint is able to receive traffic on the Mailbox server
- Test-OutlookConnectivity -ProbeIdentity "OutlookRpcSelfTestProbe"
- Validates that the MAPI/HTTP endpoint is able to receive traffic on the Mailbox server
- Test-OutlookConnectivity -ProbeIdentity "OutlookMapiHttpSelfTestProbe"
- Check replication status of all mailbox databases (for non-standalone, DAG scenario)
- Get-MailboxDatabaseCopyStatus *\*
- Check whether replication status is healthy
- Test-ReplicationHealth
- Check server component state
- Get-ExchangeServer | Get-ServerComponentState
- Run additional third-party health checking scripts as required, for example
- Test-ExchangeServerHealth.ps1 -ReportMode -Log
Exchange 2016 Changes
- Deprecation of Outlook Anywhere (RPC-over-HTTP) with MAPI-over-HTTP (enabled by default – introduced since Exchange 2013 SP1)
- Only Mailbox server role and Edge Transport server role (Exchange 2013 additionally includes Client Access Server, while Exchange 2010 includes Hub Transport and Client Access Server)
- Co-existence: Exchange 2010, 2013 and 2016 can proxy for one another (For Exchange 2010, Outlook Anywhere has to be used)
- Exchange requirements
- Exchange 2010 SP3 with RU11 or later
- Exchange 2013 CU10 or later
- AD requirements
- All domain controllers in the forest must be Windows Server 2008 or later
- Forest functional level of Windows 2008 or higher (2008 R2 or higher if any Windows Server 2016 Domain Controller is in the environment)
- Outlook client requirements (Latest available service packs and updates recommended)
- Windows: Outlook 2016, 2013, and 2010
- Mac OS X: Outlook for Mac for Office 365 / Outlook for Mac 2011
- Introduction of Public Folder mailboxes – no more legacy Public Folders
Installing Exchange
Note: For this section, it is recommended to also check Microsoft Docs for the latest prerequisites.
- Privileges of account used during setup
- Domain Admin, Enterprise Admin and Schema Admin
- Confirm PowerShell v4.0 is available
- Confirm .NET Framework 4.8 is available
- Confirm Windows components and Unified Communications Managed API 4.0 Core Runtime 64-bit are installed
- Acquire the PowerShell command (Install-WindowsFeature…) to install Windows components from https://technet.microsoft.com/en-us/library/bb691354%28v=exchg.160%29.aspx
- Schema extensions
- Prepare Active Directory
- Prepare domains
- Install product key
Avoiding Possible Impacts
- End user
- Offline Address Book
- Confirm existing mailbox databases have an Offline Address Book configured instead of leaving it blank
- Each mailbox database in existing Exchange servers should have an office address book (e.g. the default one) assigned; otherwise, users may face a problem of unknowingly downloading the new OAB in Exchange 2016 which could take a lot of bandwidth
- Confirm existing mailbox databases have an Offline Address Book configured instead of leaving it blank
- Offline Address Book
- Client connectivity
- Autodiscover Service Connection Point (SCP)
- Newly installed Exchange server has a default SCP URI of the server's FQDN (e.g. EXCH16.company.com), which generates certificate errors
- Fix:
- Get-ClientAccessServer -Identity EXCH16 | Select Name,AutoDiscoverServiceInternalUri
- Set-ClientAccessServer -Identity EXCH16 -AutoDiscoverServiceInternalUri https://mail.company.com/Autodiscover/Autodiscover.xml
- Ignore the AutoDiscover virtual directory setting which is not used for AutoDiscover – only SCP is used for AutoDiscover in an internal environment
- Autodiscover Service Connection Point (SCP)
- Mail flow
- Internal to Internal Exchange servers
- Inbound from the Internet
- Outbound to the Internet
- SMTP relay connectors
Exchange Server 2016 Co-existence Tasks - Migrating Client Access
- Note
- Manage object with the matching version of Exchange management tools
- Client connectivity must go to the highest version of Exchange (except for 2013/2016 coexistence)
- Email can route in or out of any version of Exchange
- Internal Exchange to Exchange mail flow is automatic for Exchange 2010, 2013 and 2016 (Outlook Anywhere is leveraged)
- Import the SSL certificate
- Import from existing server to new server
- Enable them for SMTP and IIS
- Enable-ExchangeCertificate -Server <Server_Name> -
Thumbprint <Thumbprint_acquired_from_Get-ExchangeCertificate> -Services SMTP,IIS - Enable them for IMAP and POP3
- Set-IMAPSettings -Server
<Server_Name> -X509CertificateName mail.company.com - Set-POPSettings -Server
<Server_Name> -X509CertificateName mail.company.com - Restart-Service
<MSExchangePOP3> - Restart-Service
<MSExchangeIMAP4> - Enable-ExchangeCertificate -Server <Server_Name>
-Thumbprint <Thumbprint_acquired_from_Get-ExchangeCertificate> -Services POP,IMAP
- Configure the client access namespaces
- Configure each HTTPS service with the same namespace as existing servers (virtual directories)
- Defining variables
- $InternalHostname = "mail.company.com"
- $ExternalHostname = "mail.company.com"
- $Server = "EXCH16"
- Outlook Anywhere
- Get-OutlookAnywhere -Server $Server | Set-OutlookAnywhere -ExternalHostname $ExternalHostname -InternalHostname $InternalHostname -ExternalClientsRequiresSsl $True -InternalClientsRequireSSL $true -DefaultAuthenticationMethod NTLM
- OWA Virtual Directory
- Get-OWAVirtualDirectory -Server $Server | Set-OWAVirtualDirectory -ExternalUrl https://$ExternalHostname/owa -InternalUrl https://$InternalHostname/owa
- ECP Virtual Directory
- Get-EcpVirtualDirectory -Server $Server | Set-EcpVirtualDirectory -ExternalUrl https://$ExternalHostname/ecp -InternalUrl https://$InternalHostname/ecp
- ActiveSync Virtual Directory
- Get-ActiveSyncVirtualDirectory -Server $Server | Set-ActiveSyncVirtualDirectory -ExternalUrl https://$ExternalHostname/Microsoft-Server-ActiveSync -InternalUrl https://$InternalHostname/Microsoft-Server-ActiveSync
- EWS (Exchange Web Services) Virtual Directory
- Get-WebServcesVirtualDirectory -Server $Server | Set-WebServicesVirtualDirectory -ExternalUrl https://$ExternalHostname/EWS/Exchange.asmx -InternalUrl https://$InternalHostname/EWS/Exchange.asmx
- OAB (Offline Address Book) Virtual Directory
- Get-OabVirtualDirectory -Server $Server | Set-OabVirtualDirectory -ExternalUrl https://$ExternalHostname/OAB -InternalUrl https://$InternalHostname/OAB
- MAPI Virtual Directory
- Get-MapiVirtualDirectory -Server $Server | Set-MapiVirtualDirectory -ExternalUrl https://$ExternalHostname/mapi -InternalUrl https://$InternalHostname/mapi
- Note: These changes do not make client connect to new Exchange server immediately; client will still connect to where DNS is resolving the namespace
- Defining variables
- Ensure new Exchange server uses existing authentication (e.g. form-based authentication with the same logon format)
- Special concerns for Exchange 2010
- Outlook Anywhere must be enabled
- Check whether Outlook Anywhere is enabled
- Get-ExchangeServer | Where {($_.AdminDisplayVersion -Like "Version 14*") -And ($_.ServerRole -Like "*ClientAccess*")} | Get-ClientAccessServer | Select Name,OutlookAnywhereEnabled
- IIS authentication must be configured for co-existence
- Enable Outlook Anywhere and configure IIS authentication
- Get-ExchangeServer | Where {($_.AdminDisplayVersion -Like "Version 14*") -And ($_.ServerRole -Like "*ClientAccess*")} | Get-ClientAccessServer | Where {$_.OutlookAnywhereEnabled -Eq $False} | Enable-OutlookAnywhere -ClientAuthenticationMethod Basic -SSLOffloading $False - ExternalHostName $hostname -IISAuthenticationMethods NTLM, Basic
- Enable Outlook Anywhere and configure IIS authentication
- Configure each HTTPS service with the same namespace as existing servers (virtual directories)
- Test the namespaces
- Before DNS change (risky), use a hosts file for testing with a pilot group
- Content of hosts file:
- IP_Address_of_Exchange_2016 mail.company.com
- Content of hosts file:
- Before DNS change (risky), use a hosts file for testing with a pilot group
- Cutover namespaces to Exchange 2016
- Lower DNS TTL to 1 minute (done earlier than what the TTL specifies)
- Make DNS change for internal client (e.g. AD DNS server)
- Make firewall change for external client (NAT settings)
- New Exchange server is in production for client connectivity now
- Test using exrca > Exchange Server > Microsoft Outlook Connectivity Tests > Outlook Connectivity
- Usual to see a few failed Autodiscover items, as long as the overall Autodiscover is successful
Migrating Mail Flow
- Internal mail flow between Exchange servers
- Change required: no need further setup (automatically established between installed Exchange servers)
- Common issue: maximum allowed message size setting differs among Exchange servers
- Compare using PowerShell the MaxMessageSize values among different servers
- Get-ReceiveConnector | Select Identity,MaxMessageSize
- Fix using Set-ReceiveConnector
- Get-ReceiveConnector -Server EXCH16 | Set-ReceiveConnector -MaxMessageSize 45MB
- Test mail flow by sending an email from one internal mailbox to another
- Outlook client: "Request a Delivery Receipt"
- Inbound mail flow from the Internet
- Changes required
- Firewall – by modifying NAT setting from the existing Exchange server to the new one, or
- Email appliance or load balancer – by removing existing Exchange server and adding new one
- Test mail flow using exrca > Exchange Server > Internet Email Tests > Inbound SMTP Email
- Analyze mail routing by pasting email header into exrca > Message Analyzer
- Changes required
- Outbound mail flow to the Internet
- Change required: EAC > Mail Flow > Edit Send Connector > Source Server: Remove existing Exchange server; ensure only new Exchange server is in the list
- Analyze mail routing by pasting email header into exrca > Message Analyzer
- Devices and applications that use SMTP relay
- Change required
- EAC > Mail Flow > New Receive Connector
- General tab
- Name: Provide a name for a new relay connector, e.g. Relay EXCH16
- Role: Frontend Transport
- Type: Custom
- Edit remote network settings by removing default 0.0.0.0-255.255.255.255 and adding IP addresses of devices and applications which send via this relay connector
- Security tab
- Tick "Anonymous users" under permission groups (leave all else unchecked except the first checkbox of TLS authentication)
- General tab
- Allow Exchange relay connector to relay email sent to external recipient
- Get-ReceiveConnector "EXCH16\Relay EXCH16" | Add-ADPermission -User 'NT Authority\Anonymous Logon' -ExtendedRights MS-Exch-SMTP-Accept-Any-Recipient
- Fix existing misconfiguration on devices and applications (if any)
- DNS alias should exist for SMTP, e.g. smtp.company.com
- Devices and applications should be using DNS alias instead of the hostname or IP address of the server
- Take the chance of migration to fix any nonoptimal settings
Migrating Public Folder
- Note
- Public folder mailbox is introduced in Exchange 2016 – no more legacy public folders
- Exchange allows public folder mailboxes up to 100GB in size
- Public folders may be migrated ahead of other mailboxes if they can sometimes be very large in size
- For large environments, public folders may take few hours take time to finalizing cutover
- One-way migration process (can roll back but lose changes since migration)
- Follow Public Folder Batch Migration Guidance on TechNet
- Download Public Folders migration scripts
- https://www.microsoft.com/en-us/download/details.aspx?id=38407
- Use these scripts to migrate public folders from Exchange 2007 or Exchange 2010 to Office 365 and Exchange Online, Exchange 2013, or later.
- Extract scripts to C:\PFMigration
- Create-PublicFolderMailboxesForMigration.ps1
- CreatePublicFolderMailboxesForMigration.strings.psd1
- Export-PublicFolderStatistics.ps1
- Export-PublicFolderStatistics.strings.psd1
- PublicFolderToMailboxMapGenerator.ps1
- PublicFolderToMailboxMapGenerator.strings.psd1
- Inventory existing public folders
- Inventory existing public folders on existing Exchange Server
- Get-PublicFolder -Recurse | Export-Clixml C:\PFMigration\Legacy_PFStructure.xml
- Acquire existing pubic folder statistics
- Get-PublicFolderStatistics | Export-Clixml C:\PFMigration\Legacy_PFStatistics.xml
- Acquire public folder permissions
- Get-PublicFolder -Recurse | Get-PublicFolderClientPermission | Select Identity, User -ExpandProperty AccessRights | Export-Clixml C:\PFMigration\Legacy_PFperms.xml
- Check if existing public folder names have backslash character which is invalid
- Get-PublicFolderStatistics -ResultSize Unlimited | Where {$_.Name -Like "*\*"} } | fl name,identity
- Watch out for existing pubic folder migration job
- Get-OrganizationConfig | fl PublicFoldersLockedforMigration,PublicFolderMigrationComplete
- Inventorying existing public folders and migration jobs on new Exchange Server
- Get-PublicFolderMigrationRequest
- Get-MigrationBatch | Where {$_.MigrationType.ToString() -eq "PublicFolder"}
- Get-Mailbox -PublicFolder
- Inventory existing public folders on existing Exchange Server
- Generate CSV files on existing Exchange server
- Export-PublicFolderStatistics.ps1
- Run PowerShell commands to export public folder size statistics to CSV
- cd C:\PFMigration
- Export-PublicFolderStatistics.ps1 C:\PFMigration\PFSizeMap.csv Old_Exch_Server
- Open CSV output with Excel and review the size. Exchange allows public folder mailboxes up to 100GB in size
- Run PowerShell commands to export public folder size statistics to CSV
- PublicFolderToMailboxMapGenerator.ps1
- Run PowerShell commands to export public folder map to CSV according to size requirements
- e.g. 10GB max for each mailbox; if larger than 10GB, additional public folder mailbox names will be generated
- ps1 10000000 C:\PFMigration\PFSizemap.csv C:\PFMigration\PFMailboxMap.csv
- Open CSV and review. The CSV will be used for migration by New-MigrationBatch.
- Export-PublicFolderStatistics.ps1
- Create public folder mailboxes on new Exchange server
- New-Mailbox -PublicFolder Mailbox1 -HoldForMigration:$true
- Begin migration on new Exchange server
- Creating a new migration batch using the generated PFMailboxMap.CSV
- New-MigrationBatch -Name PFMigration -SourcePublicFolderDatabase (Get-PublicFolderDatabase -Server Old_Exch_Server) -CSVData (Get-Content C:\PFMigration\PFMailboxMap.csv -Encoding Byte) -NotificationEmails recipient@company.com
- Start the migration batch
- Start-MigrationBatch PFMigration
- Acquire migration status
- Get-MigrationUser -BatchId PFMigration
- Optional: check migration status reporting email in the specified notification recipient mailbox
- Creating a new migration batch using the generated PFMailboxMap.CSV
- Lock public folders (outage required) on existing Exchange server
- Set-OrganizationConfig -PublicFoldersLockedForMigration:$true
- Note
- It can take up to several hours for some environments
- Effect of the -PublicFoldersLockedForMigration:$true parameter is pubic folders cannot be accessed (Error: Cannot expand the folder. Outlook cannot access this Public Folder right now. Please try again later.)
- Note
- Set-OrganizationConfig -PublicFoldersLockedForMigration:$true
- Finalize the migration (outage required) on new Exchange server
- Enable public folders as remote
- Set-OrganizationConfig -PublicFoldersEnabled Remote
- Complete migration batch
- Complete-MigrationBatch PFMigration
- Get migration batch status (The command may be run a few times to keep tracking the statuses)
- Get-MigrationBatch PFMigration
- Enable public folders as remote
- Test and unlock public folders on new Exchange server
- After the below command is entered, the specified user can check his/her mailbox to see if public folders are accessible
- Set-Mailbox username -DefaultPublicFolderMailbox PF_Mailbox_Name
- Enable public folders as local
- Set-OrganizationConfig -PublicFoldersEnabed Local
- After the below command is entered, the specified user can check his/her mailbox to see if public folders are accessible
Migrating Mailbox
- Create a new or configure existing Exchange 2016 Mailbox Database
- Reminder
- Up to 5 DBs for Standard edition; 100 for Enterprise edition
- Best practice
- Separate transaction logs and DV to different storage volume (especially for non-HA implementations)
- Examine the paths (EdbFilePath, LogFolderPath)
- Get-MailboxDatabase | fl *path*
- Change path
- Move-DatabasePath -Identity DB_Name -EdbFilePath "Target_Path_1" -LogFolderPath "Target_Path_2"
- Other
- Multiple small DBs is better than fewer large DBs (faster backup/restore/repair itmes)
- Keep name short and identifiable "DB01 vs Mailbox Database 1"
- Names must be unique
- Rename DB
- Set-MailboxDatabase "Source DB Name" -Name "Target Name"
- Multiple small DBs is better than fewer large DBs (faster backup/restore/repair itmes)
- Separate transaction logs and DV to different storage volume (especially for non-HA implementations)
- Common Issue: Mailbox quota differs among different databases on existing and new servers (default: 2GB)
- Acquire the existing quota information
- Get-MailboxDatabase -IncludePreExchange2013 | Select Name,IssueWarningQuota,ProhibitSendQuota,ProhibitSendReceiveQuota
- Fix by matching the quota of new server with that of the existing one
- Get-MailboxDatabase -Server EXCH16 | Set-MailboxDatabase -IssueWarningQuota 5GB -ProhibitSendQuota 6GB -ProhibitSendReceiveQuota 10GB
- Acquire the existing quota information
- Common Issue: Outlook Address Book not configured on existing Exchange servers
- Check
- Get-OfflineAddressBook
- Fix by letting the new server use the OAB of the existing server
- Get-MailboxDatabase -Server EXCH16 | Set-MailboxDatabase -OfflineAddressBook "Default Offline Address Book (Previous Exchange)"
- Reminder
- Exclude mailbox databases from provisioning (mailbox provisioning load balancer)
- If no target DB is selected while creation of the migration batch, Exchange automatically distributes mailboxes across available mailbox databases
- To Exclude a DB from provisioning
- Set-MailboxDatabase "DB name" -IsExcludedFromProvisioning $true
- Schedule backup of the new server (make sure it is successful to backup and restore)
- Massive amount of transaction logs could be generated during migration on the destination server which could take significant amount of disk space
- May assume 1GB logs per 1GB mailbox data
- Keep monitoring disk space usage on target server
- Migrate arbitration mailboxes first
- Check
- Get-Mailbox -Arbitration | Select name,database
- Do
- Get-Mailbox -Arbitration | New-MoveRequest
- Get-MoveRequest | Get-MoveRequestStatistics
- Verify
- Check report "Report: Download the report for this user". Look for start time and end time, error messages (if failed), etc.
- Check
- Move shared mailboxes and delegates altogether
- Chief Executive Officer + his/her assistant
- Specific team + specific shared mailbox
- Equipment mailboxes + equipment manager
- Migration speed depends on size of mailboxes, performance of source and destination servers
- Online migration: migration can run while users are accessing their mailboxes
- Cutover: 95% of mailbox is migrated, then either auto-suspend, require manual completion or auto-complete
- Completion stage involves disconnecting end user and displaying a message asking users to restart Outlook
- Configure backup to truncate transaction log (which could outgrow available target storage)
Decommission Servers
- Sanity Check
- Client Access namespaces migrated?
- Check DNS entries for Client Access namespaces
- Check load balancer configuration
- Review IIS logs (look for any user activity – see action list below)
- Mail flow migrated?
- Mailboxes migrated?
- Public folders migrated?
- Client Access namespaces migrated?
- Action List
- Confirm server no longer responsible for send connectors (Outbound email to the Internet)
- Ensure only new Exchange is in source server (EAC > Mail Flow > Edit Send Connector > Source Server)
- Analyse usage via transport logs to confirm no SMTP traffic hitting a relay receive connector
- Enable verbose protocol logging for a few hours or days to look for activity
- Get-ReceiveConnector -Server Old_Server | Select Identity,Enabled,ProtocolLogging
- Should be enabled and verbose. If not, configure them so
- Set-ReceiveConnector "Old_Connector" -ProtocolLoggingLevel Verbose
- Check logs under C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\FrontEnd\ProtocolLog\SmtpReceive\RECV*.LOG
- Afterwards, disable verbose logging
- Get-ReceiveConnector -Server Old_Server | Where ($_.ProtocolLoggingLevel -eq "Verbose") | Set-ReceiveConnector -ProtocolLoggingLevel None
- Enable verbose protocol logging for a few hours or days to look for activity
- Confirm no more mail flow appearing in message tracking logs
- Get-MessageTrackingLogs -Start (Get-Date).AddDates(-3)
- $messages | Get-MessageTrackingLogs -Start (Get-Date).AddDates(-5) -ResultSize unlimited
- $messages | Group-Object -Property:Sender | Select Name,Count | ft -auto
- Confirm no more client access traffic in IIS logs
- Path: C:\inetpub\logs\LogFiles
- Filter for username by importing to Excel, Log Parser or Log Parser Studio
- Confirm server no longer responsible for send connectors (Outbound email to the Internet)
- Remove mailbox databases and public folders
- Get-Mailbox -Database DB
- Remove-MailboxDatabase DB
- Remove-PublicFolderDatabase PF_Name
- Verify OAB of new Exchange server is configured to existing OAB
- Get-OfflineAddressBook
- Uninstall Exchange from Control Panel
Techniques
- Start PowerShell Logging (append mode)
- Start-Transcript transcript.log -Append
- Stop PowerShell Logging
- Stop-Transcript
- Connect to Other Exchange Servers
- Connect-ExchangeServer MBX01 -ClientApplication:ManagementShell
- Invoke standard PowerShell commands on remote computers using PowerShell Remoting
- Invoke-Command -ComputerName MBX01,MBX02 -ScriptBlock {Restart-Service -ServiceName MSExchangeIS}
Thanks , Appreciate your efforts for that great post...
ReplyDelete
ReplyDeleteExcellent Blog! I would like to thanks for the efforts you have made in writing this post.
I am hoping the same best work from you in the future as well. This is very beneficial to me.
I’m happy I came across this website. I still learn something new from your posts! It will give
you a great idea aboutupdate here