Latest Update:

v1.8 (07/20/2015): fixed a copy/paste error in the script and cleaned up the code to be a little more efficient (removed redundant IF-statement. Published the script to the TechNet Script Gallery for easier download access.


In Exchange 2010 one had the option to put a Mailbox server which was part of a DAG into “maintenance mode” by running the “StartDagServerMaintenance.ps1” script that was included with the product. Likewise StopDagServerMaintenance.ps1 was used to pull a server out of this so-called maintenance state. In fact, this script would move any active mailbox databases to another node in the DAG and mark this server as temporarily unavailable to the other servers. That way, if a failover would occur during the server was in ‘maintenance mode’ you wouldn’t risk that it ended up as a valid failover target.

Exchange 2013 now has the ability to go beyond what was possible before and extend this functionality. You now have the possibility to put an entire server into maintenance mode, meaning that also components like e.g. Transport Service or the Unified Messaging Call Router are temporarily put on hold why you do some work on your server.

There might be various reasons to put a server into maintenance mode. For instance when you need to install software or you want to do some troubleshooting without affecting users that might have a mailbox in an active mailbox database on that server. To facilitate the process, I created two scripts which will automatically put an Exchange 2013 Server in or take it back out of Maintenance Mode.

The manual process

The process for putting an Exchange 2013 server into maintenance mode is relatively straightforward. To enable the Maintenance Mode, you must run the commands below.

If the server is a Mailbox server and before you can disable the transport service, all active queues need to be drained first. To help clearing out the queues, existing messages on the server will be moved to another server. Please note that the TargetServer value has to be a FQDN:

[sourcecode language=”PowerShell”]Set-ServerComponentState -Component HubTransport -State Draining -Requester Maintenance
Redirect-Message -Server -Target <server_fqdn>

If the server is part of a DAG, you must also run these commands:

[sourcecode language=”PowerShell”]Suspend-ClusterNode
Set-MailboxServer -DatabaseCopyActivationDisabledAndMoveNow $true
Set-MailboxServer -DatabaseCopyAutoActivationPolicy Blocked[/sourcecode]

Once all queues are empty, you can disable all components:

[sourcecode language=”PowerShell”]Set-ServerComponentState -Component ServerWideOffline -State Inactive -Requester Maintenance[/sourcecode]

Taking the server out of Maintenance Mode is a matter of simply reversing the actions we took to put it into Maintenance Mode.

First, we reactive all components:

[sourcecode language=”PowerShell”]Set-ServerComponentState -Component ServerWideOffline -State Active -Requester Maintenance[/sourcecode]

If the server is part of a DAG, you need to reactive it in the cluster (by resuming the cluster node):

[sourcecode language=”PowerShell”]Resume-ClusterNode
Set-MailboxServer -DatabaseCopyActivationDisabledAndMoveNow $false
Set-MailboxServer -DatabaseCopyAutoActivationPolicy Unrestricted[/sourcecode]

If the server is a Mailbox Server, the transport queues need to be resumed as well:

[sourcecode language=”PowerShell”]Set-ServerComponentState –Identity -Component HubTransport -State Active -Requester Maintenance[/sourcecode]

Although not explicitly required, it’s best to restart the transport services after changing their component states. This ensures they ‘pick up’ the changed component states immediately rather than having to wait for Managed Availability (Health Service) to take action.

Using the scripts

Sometimes it can take a while before active queues are drained. Because I do not always want to wait in front of the screen and periodically check the queues myself, I created two little script that fully automate the process explained above. Besides the required steps, the scripts also perform additional safety-checks and inform you about other server component states which might prevent a server from working correctly.

The first script, Start-ExchangeServerMaintenanceMode.ps1 will put a server into Maintenance Mode, whereas Stop-ExchangeServerMaintenanceMode.ps1 can be used to take a server out of the maintenance state.

Please note that the scripts rely on built-in Exchange functions and therefore need to be run from the Exchange Management Shell.

Version history

v1.8 (07/20/2015): fixed copy/paste bug; removed duplicate code and made some overall improvements to script efficiency.

v1.7 (07/08/2015): removed the requirement to dot-source the script. Published the script to the TechNet Script Gallery for easier download access.

v1.6 (29/11/2013): some minor bug fixes in the Start-ExchangeMaintenanceMode script.

v1.5 (28/11/2013): Based on feedback from several readers, I’ve improved the scripts by rewriting parts of the code and, as such, making it more lenient and more usable in scenarios where you want to run the script from a remote Exchange server. The script now also restarts the Transport service(s) after changing their component states. This ensures that the new component states are picked up immediately, rather than after Managed Availability kicks in. Without the change it could take anywhere from a few minutes to a few hours before the transport services were really inactive/active again. The download links at the bottom of the page are updated to point to the new versions of the scripts. Last, but not least, when ending a maintenance mode, the script will query the server for any components that might still be inactive and display a warning if any are found. A special thanks to Dave Stork for some of the ideas!

v1.4: update the script to include some additional error checks. First it will check whether the person who is executing the script has local admin rights. If not, the script will throw a warning and exit. Secondly it will also check whether the TargetServer name can be resolved. If it’s not an FQDN, it will resolve it to an FQDN. If it cannot be resolved, an error will be thrown.

v1.3: after some feedback from Brian Reid (thanks Brian!), I’ve finally updated the script to include the “Redirect-Message” cmdlet. This will ensure that the queues will drain more quickly on the server by moving messages from one server to another. Have a look at Brian’s blog if you need more info:

v1.2: Maarten Piederiet emailed me pointing out that he had encountered some issues while using the script. Apparently, while draining the message queues, the script ran forever because it waits for every queue to become empty; including Poison- & Shadow Redundancy queues. To avoid this from happening, he made a minor change to the script to now excluded both queues. Thanks for the tip!

The scripts

Below you find links to my SkyDrive from where you can download the scripts. Enjoy!

Start-ExchangeServerMaintenanceMode (v1.8)

Stop-ExchangeServerMaintenanceMode (v1.5)

Disclaimer: these scripts are provided “as-is” and are to be used on your own responsibility. I do not and cannot take any reliability for the use of these scripts in your environment. Please use with caution and always test them before use.

If you have suggestions, comments or think things can be better: please let me know! Your feedback is greatly appreciated!