Whether to install CU updates on Exchange Server 2019 /2016 or reboot the server, the Exchange Admin follows some steps to place Exchange server Node (DAG Mode Only) in maintenance mode.
This PowerShell Module helps you place your Exchange Server in maintenance mode easily and safely using only one line of code.
Table of Contents
- System Requirements:
- Download Exchange Server 2016/2019 PS Maintenance Module
- Versions and updates
- Supported Cmdlets
- Enable Maintenance Mode on Exchange Server 2019 or 2016
- Stop-EMMDAGEnabled
- Test-EMMReadiness
- Test cases and behavior using Exchange Server 2019 / 2016
- EMM vs StartDagServerMaintenance.PS1
- Conclusion
System Requirements:
- Microsoft.Exchange.Management.PowerShell.SnapIn
- FailoverClusters PowerShell Module
- Run the PowerShell as an administrator
- The Exchange Management shell should be installed on the computer.
- PowerShell 5.1, using PowerShell 7, won’t work.
The EMM in the naming convention stands for Exchange Maintenance Mode.
Download Exchange Server 2016/2019 PS Maintenance Module
The PSModule is now hosted in PowerShell Gallery. To download it, just open PowerShell and type the following command
Install-Module -Name EmmExDAGModule
Versions and updates
3 – Jun 2023 / Version 2.2
This version has multiple updates to support organizations with multiple Exchange Servers and gives the flexibility to manage the options. Please read the Supported Cmdlets section for more information.
- List Exchange certificate when running Test-EMMReadiness
- Only shows the failed result for Database copy and replication health
- Shows cluster best practices
- Exchange Database move will check and confirm another health database before moving the database.
- Updating queue moving issue.
- 120 Second, wait for the DB Move to be removed.
- Connect to the internet, get the latest version information, and show any known issues.
- Uses Exchange Management Shell to load instead of adding PSSnapin
- Minor issues in the reporting.
Feel free to check it from Microsoft PowerShellGallery.com
Lets work together in making this better. Feel free to send a Pull Request from my GitHub with the required update
Supported Cmdlets
To simplify the process, there are only three cmdlets:
Start-EMMDAGEnabled
Start the process of placing an exchange server in maintenance mode. The supported parameters are:
- [string][Required] ServerForMaintenance: The server name you want to place in maintenance mode. This name can be a NetBIOS name or FQDN.
- [string][Required] ReplacementServerFQDN: The server name will act as a replacement. This is only used for Queue Transfer, so all queued messages in
ServerForMaintenance
are transferred toReplacementServerFQDN
- [Switch] IgnoreQueue: Use this parameter to skip queue check and transfer. Use this option to accelerate the process if the messages in the queue are not essential and can remain queued in the Exchange server while it’s down.
- [switch] IgnoreCluster: This option can be used by organizations with IP-Less DAG.
- [switch] SkipDatabaseHealthCheck: This option forces database migration from one node to another by skipping multiple health checks, which include:
- SkipClientExperienceChecks: Skip Catalog health, even if it was in a failed state.
- SkipCpuChecks: Ignore CPU utilization.
- SkipMaximumActiveDatabasesChecks
- SkipMoveSuppressionChecks: Skip how many times the database migrated within an hour.
EMM moves each database using activation preference order.
Stop-EMMDAGEnabled
Start placing the server, which is in maintenance mode, back into production. This cmdlet works even if your exchange server was in maintenance mode manually or by using Start-EMMDAGEnabled
. This cmdlet supports the following parameters:
- [String][Required]ServerInMaintenance: the name of the Exchange Server is currently in maintenance mode.
- [Switch]IgnoreCluster: This option can be used by organizations with IP-Less Cluster.
- [ValidationSet]ServerActivationMode: Set the Mailbox Server DatabaseCopyAutoActivationPolicy to
IntrasiteOnly
orUnrestricted
. The default is Unrestricted.
Test-EMMReadiness
The Test-EMMReadiness
scans your Exchange Server environment configuration and status and reports the current state which includes the Exchanges Server Component state, Cluster state, Database Queue Length, Services Health, and other details.
This cmdlet also reports which server is good to be used for maintenance and which server is not. Also, in this report, you will know if any server remained in maintenance mode or had any components disabled. This cmdlet supports the following parameter:
- [Switch]IgnoreCluster: This option can be used by organizations with IP-Less Cluster.
Read more about the manual process and how to enable or disable Exchange Server 2019 Maintenance Mode Step-By-Step here:
Enable Exchange 2019 Maintenance Mode
Disable Exchange 2019 Maintenance Mode
Before placing the server in maintenance mode, it’s recommended to start by running the Test-EMMReadiness
cmdlet to get a good overview and understanding of the current environment.
Challenges and Possible Issues with Manual process
One quick example is, that an administrator can set Hubtransport in Drain Mode in all the nodes, and Exchange Server accepts it. But if a user sent a message, it will be stored in the draft folder with a header.
As there is no message or warning that tells the administrator no more HubTransport service is available. The problem will appear to the users.
“Your Message will be sent, But we’re not quite ready. Check back in a couple of minutes“
Enable Maintenance Mode on Exchange Server 2019 or 2016
For this tutorial, an Exchange Server 2019 named EX01 and EX02 are used.
Example 1: The command below will set EX01 in Maintenance Mode, the –ReplacementServerFQDN
is the server that will be used for Queue Redirection (if required)
Start-EMMDAGEnabled -ServerForMaintenance EX01 -ReplacementServerFQDN EX02.test.local
Example 2: The command below sets Ex01 in Maintenance Mode, the -IgnoreQueue skips the redirecting of the queue to another server, which keeps all the messages queued on the same server.
Start-EMMDAGEnabled -ServerForMaintenance EX01 -ReplacementServerFQDN Ex02.test.local -IgnoreQueue
When using the -IgnoreQueue switch, the
ReplacementServerFQDN
is ignored.
Example 3: The command below sets Ex01 in Maintenance Mode, and the -IgnoreCluster skips the Failover Cluster check, this is helpful for IP-Less DAG.
Start-EMMDAGEnabled -ServerForMaintenance EX01 -ReplacementServerFQDN Ex02.test.local -IgnoreCluster
Currently, the Cluster Management won’t consider the cluster quorum, only will check to see if other nodes are available and active.
Limitation to consider.
Before placing the server in maintenance mode, its good to have deep visibility on the server status, use the
Test-EMMReadiness
for a deeper insight
Stop-EMMDAGEnabled
Use the Sop-EMMDAGEnabled to disable the Maintenance Mode and set the server back to a production active state.
Stop-EMMDAGEnabled -ServerInMaintenance Ex01
Test-EMMReadiness
The Test-EmmReadiness
don’t require any parameter to start.
This command will generate a full report about the Exchange infrastructure and list the Active and Inactive components, also run a few tests to give the administrator an overview of the Exchange Server Infrastructure.
Test-EMMReadiness
The Test-EMMReadiness
command will do the following:
- Pinging the
-SourceServer
and confirm its reachability - Test Web Services availability 80 and 443
- List all Exchange Server certificates with the expiry date.
- List some cluster configurations.
- List all the Exchange Servers HubTransport, ServerWideOffline, and HighAvailability component with their state.
- List the number of an active UP Cluster node and the non-active nodes other than Up
- Check the DatabaseCopyActivationDisabledAndMoveNow and DatabaseCopyAutoActivationPolicy policies
- List the number of failed services on each node, and show them if any.
- Show the Databases with the number of CopyQueueLength and ReplayQueueLength
- Run a Test-ReplicationHealth
To make the output shorter, EMM will only show the failed result if any from both Get-Mailboxdatabasecopy and Test-ReplicationHealth
All these tests should give the Exchange Server Administrator a view of the server components and what might go wrong or be forgotten in the infrastructure. Also, it’s good to say that this command won’t change anything, it’s only listing the current configuration.
Test cases and behavior using Exchange Server 2019 / 2016
This section will showcase how the EMM PS module can save you from some unexpected issues:
No More Active HubTransport Server Component
In this case, the admin needs to set EX02 to maintenance mode, while EX01 HubTransport Server Component is already in Draining State, so If the admin used the EmmEXDag module it will show the following
The process will stop and inform the admin to make sure that other HubTransport Server Components are available to avoid service disturbing.
The same thing will be applied to ServerWideOffline Server Component
No More Mailbox Server with a Non-Blocking Policy
In this example, the other nodes are configured with MailboxServer DatabaseCopyAutoActivationPolicy to Block
A Report of one Server in maintenance and the other in Active state
The image below shows how the report looks like if one node is already in maintenance mode and the other node is Active, so in this case, EX01 is already in maintenance mode but EX02 is still active.
EMM vs StartDagServerMaintenance.PS1
Both have the same purpose, making your Exchange Server ready to be offline without disturbing the mail flow, but there are some other practices I love to follow that the StartDagServerMaintenance.ps1 won’t do
If I wrote something wroge, feel free contact me and update me, maybe I missed something
Feature | EMM Module | StartDagServerMaintenance |
Hub transport Server Component | Drain it | No |
Redirect Queue | Redirect to another Node | No |
Cluster Node | Will Pause the node | Optional By Parameter |
MailboxServer Policy | Yes | Yes |
Confirm the availability of other nodes | Yes | No |
Logging | Showing progress | No |
Reports | Detailed Report using Test-EMMReadiness | Basic Reported by Get-MailboxServerRedundancy |
Conclusion
The EMM PS Module will give you a lot of insight view and of what’s going on so you can have a better understanding of Exchange infrastructure components. Also, will help you to set your Exchange Server 2016/2019 Maintenance mode in one line only
I hope you like this post and the module, feel free if you want to contribute to this script, update it send it back with your name in the top comment of the PS Module, and will update the PSRepository.
So I see one problem here. The Redirect server piece and database moves. Your assuming a small environment here. In large environments with say a full DAG the databases on one server more than likely will not be able to all move to another server. If instead you use Move-ActiveMailboxDatabase -Server EXO1 it would cause all the active database on that server to be moved to the next preference server that has a database copy for the databases. This would leave the Redirect server as only used for Transport message redirection.
Hi
The Move-ActiveMailboxDatabase is used to move the databases from one node to another.
the part of Redirect Server is mainly to move the pending messages in the server queue to another server to avoid any delay or data lose.
the Redirect queue can be ignored by using the “IgnoreQueue” parameter which will not do any message redirection, and instead move the databases from node to the other.
If I miss understand your question feel free and let me know, it can be a possibility to update the script with a newer feature.
Thanks
Your script is doing this..
It’s expected that Mounted Databases to be migrated to another node, but in case the migration process did not trigger, the script will proceed and Migrate the Database to the ReplacementServerFQDN
My comment is that it is not possible in a larger DAG environment because Not all the mailbox Databases will necessarily be on that target server. But if you use the Move=ActiveMailboxDatabase command it will move all the databases to their next activation preference server that is available.
The Script should move all database to another Server from the server where the script is executed or the source server. but should not effect any other server.
I will expend my lab to include more exchange servers to see how the script is behaving .
In my production, I have 2 servers and even on my lab I have 2 servers.
I will add one extra and see it.
Thanks for the comment.
Hi, The EMM Module is now updated with multiple feathers, Now and as you suggest, the EMM module moves the DB based on the Activation Preference.
Hope this update helps make it better. Feel free and leave any comment on any issue or update you like.
We have an IP-less DAG, and when we run the script we get an RPC error at line 608. Does the script not work with an IP-less DAG?
I did not try the script in IP-Less DAG, but I think it should work.
Anyway, what is the full error you are getting?
This is the error message:
Get-Cluster : Vergewissern Sie sich, dass der Clustername richtig geschrieben wurde. Möglicherweise liegt auch ein Netzwerkfehler vor. Stellen Sie sicher, dass die Clusterknoten eingeschaltet und mit dem Netzwerk verbunden sind, oder
wenden Sie sich an den Netzwerkadministrator.
Der RPC-Server ist nicht verfügbar
In C:\Program Files\WindowsPowerShell\Modules\EmmExDAGModule\1.0.6\EmmExDAGModule.psm1:608 Zeichen:19
+ $Status=Get-Cluster (Get-DatabaseAvailabilityGroup)| Get-Cl …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : Verbindungsfehler: (:) [Get-Cluster], ClusterCmdletException
+ FullyQualifiedErrorId : ClusterRpcConnection,Microsoft.FailoverClusters.PowerShell.GetClusterCommand
WARNING: The number of available clusters is not enough, Please stop and resume one node at least”
OK, the current 1.6 version doesn’t support IP-Less DAG.
I will update the script within the next few days to support IP-Less DAG.
Thanks for reporting.
The Module is now updated to support IP-Less DAG.
use the parameter -IgnoreCluster to configure and test your environment.
Hello,
we have now tried to fail over with the new version, but unfortunately we still get an error message:
Start-EMMDAGEnabled -IgnoreCluster -ServerForMaintenance -ReplacementServerFQDN
The error message says that it cannot find the IgnoreCluster parameter.
We have carried out the update using the update module. Version 1.1 is also displayed via Get-InstalledModule.
The module is currently only installed on Server1, where the command is also executed. Does the module have to be installed on both, or is there actually still a problem with the script?
I tested it on my servers and cluster management is ignored.
Just make sure to remove and delete all the previous versions and reinstall module 1.1
Hi,
Would you please open the file “C:\Program Files\WindowsPowerShell\Modules\EmmExDAGModule\1.1\EmmExDAGModule.psm1” and confirm that in line 50 there is the $IgnoreCluster and also in line 159
Thanks
Hi, at first many thanks for your tool.
But i have a little problem: I´ve use a IP less DAG and when i try to use the -IgnoreCluster parameter i got the error message that this parameter is not found! 🙁
I´ve installed the version 1.1, so the latest one.
Do you have a solution for me?
Best wishes
Hi,
Would you please open the file “C:\Program Files\WindowsPowerShell\Modules\EmmExDAGModule\1.1\EmmExDAGModule.psm1” and confirm that in line 50 there is the $IgnoreCluster and also in line 159
Thanks
Hi Faris,
yes it is.
Another reason why it’s strange that this doesn’t work. 🙁
Could it be that I am passing the parameter incorrectly?
Asked stupidly: what would be the exact syntax of the command to take a server of an IP less DAG into maintenance?
Start-EMMDAGEnabled -IgnoreCluster -ServerForMaintenance EX01 -ReplacementServerFQDN EX02.test.local
Correct?
Many thanks and best wishes
Hi Faris,
do you have any new information?
Many thanks in advance and best wishes
Basti
Please provide me with the PowerShell version you are using, also drop me an email to farisnt@gmail.com to take a closer look on whats going on on your side.
thanks for the tool, one issue, is that for unknown reason I got this error (regular cluster not ip less)
if i manually do Suspend-ClusterNode it works
Failed to prepare the cluster, Please check if the computer name is correct and if the computer still reachable or went
offline… Aborting
Thanks for the comment,
There should be a detailed Error before this line, can you tell me what is the error if available
Are you getting any correct output if U run the following
Get-ClusterNode -Cluster (Get-DatabaseAvailabilityGroup)
#Get Cluster node name by using the DAGand the following line
Suspend-ClusterNode -Name "YOUR SERVER NAME" -Cluster (Get-DatabaseAvailabilityGroup)
#Put the node on Suspend state.Make sure that the computer you are using has a FailoverCluster PowerShell module.
Feel free to share the output result to my email farisnt@gmail.com to address this issue and ensure it work fine with you
Hello, I am an Exchange 2019 IP Less Cluster. Is the Ignore-Cluster switch required in such scenario?
If I use the script without this switch I am always getting this error:
Starting Cluster Check…
Get-Cluster : Cannot convert ‘System.Object[]’ to the type ‘System.String’ required by parameter ‘Name’. Specified method is not supported.
At C:\Program Files\WindowsPowerShell\Modules\EmmExDAGModule\2.0\EmmExDAGModule.psm1:590 char:31
+ $Status=Get-Cluster (Get-DatabaseAvailabilityGroup)| Get-Cl …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-Cluster], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.FailoverClusters.PowerShell.GetClusterCommand
Hi
The Ignore-Cluster switch should be used whenever you have IP-Less DAG otherwise you will get the error you mention.
Hello, using your script the queue transfer is never completing. Any idea?
Queue Transfar request sent..
Checking Queue Value, and waiting for it to be 0, the timeout for this process is 60 second, Please wait.
Queue Transfer was not completed
The Number of remaining Queue is 26
Press Y to continue or any other key to abort the process: y
Queue Transfer is not completed, But the user accepted it
I notice this behavior on the Exchange server when it placed and exited maintenance mode multiple times.
The queue service seems to receive the command but it doesn’t respond to it.
you can accept it and continue or you can use the -ignorequeue parameter to avoid delay.
sometimes restarting the exchange server fixes the queue service issue and you can proceed with the full flow.
Okay I will wait a bit and retry in the coming days. Thanks for your prompt reply.
Perfekt and thanks for the prompt answer.
Great Module!
Helps a lot in automation process with Exchange maintenance and patching.
I would suggest 1 feature request that might be interesting:
Add the possibility to stop and disable the MSExchangeFrontEndTransport service with a Switch Flag when maintenance mode is enabled. (and the opposite action when the maintenance mode is disabled)
Topologies with Exchange servers an external load balancers is always an issue for them to be aware of the SMTP service being disabled when maintenance mode is enabled.
Depending on the LoadBalancer and the monitor type, the common pattern is to check the state of SMTP listening port (25 or 587).
When Exchange server is in maintenance mode, the SMTP listening port is always UP, but the underlying SMTP service is not working due to the maintenance mode.
Stopping and disabling the MSExchangeFrontEndTransport would be an easy way to stop unwanted SMTP traffic to Exchange server being in maintenance mode.
Thanks.
Cool idea.
I included the requested feature in the GitHub repo, Feel free to download it and try it.
Let me know how does it goes 🙂
Hi
This is a great script which help a lot. Thanks for this.
Just an aditional information to the chapter System Requirements:
To run this script, you need to have in minimum the Exchange right: Server Management.
Without this you will get errors like this:
Set-EMMHubTransportState : Cannot bind argument to parameter ‘Message’ because it is null.
At C:\Program Files\WindowsPowerShell\Modules\EmmExDAGModule\2.0\EmmExDAGModule.psm1:66 char:20
+ … $Step1=Set-EMMHubTransportState -Servername $PSBoundParameters[‘ …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Set-EMMHubTransportState], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Set-EMMHubTransportState
Great tip will add this to the next version.