how properly enter into maintenance mode on Exchange2016/2013 DAG

Let’s assume that we have

ex01.itforce.local and ex02.itforce.local Exchange 2016 servers in DAG cluster. We need to install new CU on this cluster without downtime. (assumed that all CAS, smtp protocols are properly loadbalanced). So we need:

  1. at first disable all workloads/switch to maintenance mode on the node ex01,
  2. install CU on ex01,
  3. reboot ex01
  4. exit from maintenance mode on ex01
  5. enter into maintenance mode on ex02
  6. install CU on ex02,
  7. reboot ex02
  8. exit from maintenance mode on ex02
  9. equally spread workload on both nodes again
#goto ex01
#run in elevated mode powershell for exchange

#prepare smtp transport:
Set-ServerComponentState ex01 -Component HubTransport -State Draining -Requester Maintenance
Restart-Service MSExchangeTransport
Redirect-Message -Server ex01 -Target ex02.itforce.local

#to check:
Get-ServerComponentState -Identity ex01.itforce.local
Get-ServerComponentState ex01 -Component HubTransport

#prepare cluster:
Get-DatabaseAvailabilityGroup -Status | fl Name,PrimaryActiveManager
Move-ClusterGroup "cluster group" -Node ex02
Suspend-ClusterNode ex01
Get-ClusterNode
Get-DatabaseAvailabilityGroup -Status | fl Name,PrimaryActiveManager

#prepare mailboxes:
Get-MailboxDatabaseCopyStatus -Server ex01
Get-MailboxDatabaseCopyStatus -Server ex01 | ? {$_.Status -eq "Mounted"} | % {Move-ActiveMailboxDatabase $_.DatabaseName -ActivateOnServer ex02 -Confirm:$false}
Get-MailboxDatabaseCopyStatus -Server ex02
Set-MailboxServer EX01 -DatabaseCopyAutoActivationPolicy Blocked
Get-MailboxServer EX01 | ft Name,DatabaseCopyAutoActivationPolicy

#finally switch to maintenance mode ex01:
Set-ServerComponentState EX01 -Component ServerWideOffline -State Inactive -Requester Maintenance
Get-ServerComponentState EX01 -Component ServerWideOffline

#exit from maintenance on ex01:

Set-ServerComponentState EX01 -Component ServerWideOffline -State Active -Requester Maintenance
Get-ServerComponentState EX01 -Component ServerWideOffline

#enable cluster node:
Resume-ClusterNode EX01
Get-ClusterNode

#enable copy:
Set-MailboxServer EX01 -DatabaseCopyAutoActivationPolicy Unrestricted

#enable transports
Set-ServerComponentState EX01 -Component HubTransport -State Active -Requester Maintenance
Restart-Service MSExchangeTransport
Get-ServerComponentState EX01 -Component HubTransport
Get-ServerComponentState EX02 | ft Component,State -AutoSize

#Option1 - move all copy to ex01:
Get-MailboxDatabaseCopyStatus -Server ex02 | ? {$_.Status -eq "Mounted"} | % {Move-ActiveMailboxDatabase $_.DatabaseName -ActivateOnServer ex01 -Confirm:$false}
#Option2 - just loadbalance
cd "C:\Program Files\Microsoft\Exchange Server\V15\scripts"
.\RedistributeActiveDatabases.ps1 -DagName DAG4exchange -BalanceActivationPreferences
.\RedistributeActiveDatabases.ps1 -BalanceDbsByActivationPreference -Confirm:$false

#The same steps on ex02:
#goto ex02
#run in elevated mode powershell for exchange

#prepare smtp transport:
Set-ServerComponentState ex02 -Component HubTransport -State Draining -Requester Maintenance
Restart-Service MSExchangeTransport
Redirect-Message -Server ex02 -Target ex01.itforce.local
Get-ServerComponentState -Identity ex02.itforce.local
Get-ServerComponentState ex02 -Component HubTransport

#prepare cluster:
Get-DatabaseAvailabilityGroup -Status | fl Name,PrimaryActiveManager
Move-ClusterGroup "cluster group" -Node ex01
Suspend-ClusterNode ex02
Get-ClusterNode
Get-DatabaseAvailabilityGroup -Status | fl Name,PrimaryActiveManager

#prepare mailboxes:
Get-MailboxDatabaseCopyStatus -Server ex02
Get-MailboxDatabaseCopyStatus -Server ex02 | ? {$_.Status -eq "Mounted"} | % {Move-ActiveMailboxDatabase $_.DatabaseName -ActivateOnServer ex01 -Confirm:$false}
Get-MailboxDatabaseCopyStatus -Server ex01
Set-MailboxServer EX02 -DatabaseCopyAutoActivationPolicy Blocked
Get-MailboxServer EX02 | ft Name,DatabaseCopyAutoActivationPolicy

#finally switch to maintenance mode ex02:
Set-ServerComponentState EX02 -Component ServerWideOffline -State Inactive -Requester Maintenance
Get-ServerComponentState EX02 -Component ServerWideOffline

#exit from maintenance on ex02:

Set-ServerComponentState EX02 -Component ServerWideOffline -State Active -Requester Maintenance
Get-ServerComponentState EX02 -Component ServerWideOffline

#enable cluster node:
Resume-ClusterNode EX02
Get-ClusterNode

#enable copy:
Set-MailboxServer EX02 -DatabaseCopyAutoActivationPolicy Unrestricted

#enable transports
Set-ServerComponentState EX02 -Component HubTransport -State Active -Requester Maintenance
Restart-Service MSExchangeTransport
Get-ServerComponentState EX02 -Component HubTransport
Get-ServerComponentState EX01 | ft Component,State -AutoSize


#Option1 - move all copy to ex02 (optional):
Get-MailboxDatabaseCopyStatus -Server ex01 | ? {$_.Status -eq "Mounted"} | % {Move-ActiveMailboxDatabase $_.DatabaseName -ActivateOnServer ex02 -Confirm:$false}

#Option2 - re-loadbalance workload:
cd "C:\Program Files\Microsoft\Exchange Server\V15\scripts"
.\RedistributeActiveDatabases.ps1 -DagName DAG4exchange -BalanceActivationPreferences
.\RedistributeActiveDatabases.ps1 -BalanceDbsByActivationPreference -Confirm:$false

Except bottom re-balancing builtin Exchange scripts all other rows can be copy pasted into Exchange management console.