Home » Exchange Server » PowerShell Scripts for Balancing Database Availability Groups

PowerShell Scripts for Balancing Database Availability Groups

One of the recommendations in Microsoft’s Preferred Architecture for Exchange Server 2013 is to distribute active database copies evenly across all members of a database availability group.

As with the namespace model, each DAG within the site resilient datacenter pair operates in an unbound model with active copies distributed equally across all servers in the DAG. This model provides two benefits:

  1. Ensures that each DAG member’s full stack of services is being validated (client connectivity, replication pipeline, transport, etc.).
  2. Distributes the load across as many servers as possible during a failure scenario, thereby only incrementally increasing resource utilization across the remaining members within the DAG.

You can achieve an even distribution of active database copies in your DAG by applying a combination of PowerShell scripts and activation preference configuration.

Reviewing Your Activation Preference Distribution

To review the current configuration of your database availability group you can use two PowerShell scripts. The first script is RedistributeActiveDatabases.ps1 which is available in the $exscripts folder of any server or management workstation that has the Exchange management tools installed.

To look at the current database distribution use RedistributeActiveDatabases.ps1 with the -ShowDatabaseDistributionByServer switch.

The detail we’re most interested in at this stage is the PreferenceCountList. For the DAG member SYDEX1 the value is “{4, 0, 0, 0}” which means:

  • 4 database copies on SYDEX1 with Activation Preference 1
  • 0 database copies on SYDEX1 with AP of 2, 3, or 4

A better visual representation of the database AP layout can be gathered by running Get-DAGApMap.ps1 (available on Github), which generates a CSV of the configuration that is easier to read.


The DAG shown above is clearly not balanced, so what can we do about that?

Balancing Activation Preferences for a Database Availability Group

Although we can manually change the activation preference values for each of the database copies it would be quite tedious to do so for a large DAG. Instead, we can use RedistributeActiveDatabases.ps1 again, this time with the -BalanceActivationPreferences switch. If you don’t want to be prompted for each change that is made add the -Confirm:$false switch as well.

After the script has finished running we can use the same methods shown earlier to review the configuration.

Notice now that each DAG member has a PreferenceCountList of “{1, 1, 1, 1}” indicating an evenly balanced DAG as far as activation preferences go.

And again we can use Get-DAGApMap.ps1 to see it in CSV format instead.


Rebalancing the Database Availability Group

Now that the activation preferences are evenly distributed, what about the active database copies themselves? We can look at the current active database copies by running Get-MailboxDatabaseCopyStatus.

Or rather we could, if not for this bug which has been present in every build of Exchange 2013 up to CU8 so far. A fix may be forthcoming in a later build.

Fortunately we can use RedistributeActiveDatabases.ps1 again with the -ShowDatabaseCurrentActives switch.

The sections of the output above like this one tell us what we want to know.

In the example above the database DB02 is active on server SYDEX2, which has an AP of 1.

Finally, if we want to rebalance the DAG so that each database is active on its AP=1 copy, we can run RedistributeActiveDatabases.ps1 with the -BalanceDbsByActivationPreference switch. Use -Confirm:$false if you don’t want to be prompted for each switchover.

Paul is a Microsoft MVP for Office Servers and Services. He works as a consultant, writer, and trainer specializing in Office 365 and Exchange Server. Paul is a co-author of Office 365 for IT Pros and several other books, and is also a Pluralsight author.
Category: Exchange Server


  1. Michael says:

    Hi Paul

    Thanks this is very helpful.
    But I would like to go even a step further.
    Not only divide the load of your databases but also divide the user load across the different databases.

    The thing I would like to achieve is to get an even load (mailbox size wise) across all databases.
    So not based on how many users there are on a database but based on mailbox sizes so that you get databases with almost identical sizes.

    What are your thoughts on this?
    Is it useful and possible to script this?

    Thanks in advance.

Leave a Reply

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