After an outage or maintenance to the Exchange 2010 or Exchange 2013, or Exchange 2016 Mailbox servers in a Database Availability Group you may find that the mailbox databases are no longer balanced across all of the DAG members.

For example after applying updates to DAG members you may see that all of the mailbox databases are active on a single DAG member.

[PS] C:\>Get-MailboxDatabase | ft name, server, activationpreference -AutoSize

Name                Server ActivationPreference
----                ------ --------------------
Mailbox Database 02 EX1    {[EX2, 1], [EX1, 2]}
Mailbox Database 01 EX1    {[EX1, 1], [EX2, 2]}
Mailbox Database 03 EX1    {[EX1, 1], [EX2, 2]}
Mailbox Database 04 EX1    {[EX2, 1], [EX1, 2]}

You can see in the above output that all of the mailbox databases are active on server EX1, even though some of them have EX2 as a preferred server.

Exchange Server 2010 Service Pack 1 shipped with a script that allows you to automatically redistribute mailbox databases to their first activation preference. The script can be found in the Scripts folder of the Exchange Server 2010 installation path, which by default would be C:Program FilesMicrosoftExchangeV14Scripts.

You can use the script to output a report of the current mailbox database distribution among the DAG members.

[PS] C:\Program Files\Microsoft\Exchange Server\V14\Scripts\>.\RedistributeActiveDatabases.ps1 -DagName DAG -ShowDatabase
DistributionByServer | ft

ServerName           TotalDbs      ActiveDbs     PassiveDbs PreferenceCoun     MountedDbs  DismountedDbs DagName
                                                            tList
----------           --------      ---------     ---------- --------------     ----------  ------------- -------
EX2                         4              0              4 {2, 2}                      0              0 dag
EX1                         4              4              0 {2, 2}                      4              0 dag

To rebalance the mailbox databases based on activation preference use the following script parameters.

[PS] C:\Program Files\Microsoft\Exchange Server\V14\Scripts\>.\RedistributeActiveDatabases.ps1 -DagName DAG -BalanceDbsBy
ActivationPreference

***************************************
Balance DAG DBs
Thursday, October 28, 2010 10:16:36 PM
***************************************
Dag                                :   dag
ServerCount                        :   2
DatabaseCount                      :   4
CopiesCount                        :   8

----------------------------
Starting Server Distribution
----------------------------

ServerName TotalDbs ActiveDbs PassiveDbs PreferenceCountList MountedDbs DismountedDbs DagName
---------- -------- --------- ---------- ------------------- ---------- ------------- -------
EX1               4         4          0 {2, 2}                       4             0 dag
EX2               4         0          4 {2, 2}                       0             0 dag


-----------------------
Starting Database Moves
-----------------------

Considering move of 'Mailbox Database 04' from 'ex1' (AP = 2) to 'EX2' (AP = 1)...

Confirm
Are you sure you want to perform this action?
Moving mailbox database "Mailbox Database 04" from server "ex1.exchangeserverpro.local" to server
"EX2.exchangeserverpro.local".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): a
Database 'Mailbox Database 04' successfully moved from 'ex1' to 'ex2'.

ServerName ActiveDbs PassiveDbs
---------- --------- ----------
EX1                3          1
EX2                1          3 `n
Considering move of 'Mailbox Database 02' from 'ex1' (AP = 2) to 'EX2' (AP = 1)...

Confirm
Are you sure you want to perform this action?
Moving mailbox database "Mailbox Database 02" from server "ex1.exchangeserverpro.local" to server
"EX2.exchangeserverpro.local".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): a
Database 'Mailbox Database 02' successfully moved from 'ex1' to 'ex2'.

ServerName ActiveDbs PassiveDbs
---------- --------- ----------
EX1                2          2
EX2                2          2 `n

----------------
Summary of Moves
----------------
Successfully moved      : 2
Moved to less preferred : 0
Failed to move          : 0
Not moved               : 2

Start time              : Thursday, October 28, 2010 10:16:35 PM
End time                : Thursday, October 28, 2010 10:17:51 PM
Duration                : 00:01:15.3764472



DbName                    : Mailbox Database 01
ActiveOnPreferenceAtStart : 1
ActiveServerAtStart       : ex1
ActiveOnPreferenceAtEnd   : 1
ActiveServerAtEnd         : ex1
IsOnMostPreferredCopy     : True
MoveStatus                : NoMoveAttempted

DbName                    : Mailbox Database 02
ActiveOnPreferenceAtStart : 2
ActiveServerAtStart       : ex1
ActiveOnPreferenceAtEnd   : 1
ActiveServerAtEnd         : ex2
IsOnMostPreferredCopy     : True
MoveStatus                : MoveSucceeded

DbName                    : Mailbox Database 03
ActiveOnPreferenceAtStart : 1
ActiveServerAtStart       : ex1
ActiveOnPreferenceAtEnd   : 1
ActiveServerAtEnd         : ex1
IsOnMostPreferredCopy     : True
MoveStatus                : NoMoveAttempted

DbName                    : Mailbox Database 04
ActiveOnPreferenceAtStart : 2
ActiveServerAtStart       : ex1
ActiveOnPreferenceAtEnd   : 1
ActiveServerAtEnd         : ex2
IsOnMostPreferredCopy     : True
MoveStatus                : MoveSucceeded

The outcome of the moves can be seen here. Each mailbox database in the DAG is now active on its preferred server.

[PS] C:\>Get-MailboxDatabase | ft name, server, activationpreference -AutoSize

Name                Server ActivationPreference
----                ------ --------------------
Mailbox Database 02 EX2    {[EX2, 1], [EX1, 2]}
Mailbox Database 01 EX1    {[EX1, 1], [EX2, 2]}
Mailbox Database 03 EX1    {[EX1, 1], [EX2, 2]}
Mailbox Database 04 EX2    {[EX2, 1], [EX1, 2]}

[adrotate banner=”49″]

About the Author

Paul Cunningham

Paul is a former Microsoft MVP for Office Apps and Services. He works as a consultant, writer, and trainer specializing in Office 365 and Exchange Server. Paul no longer writes for Practical365.com.

Comments

  1. Tony

    Hi Paul. Sorry for the comment on such an old article, but when i try running it i get this

    Sending data to a remote command failed with the following error message: The WinRM client sent a request to the remote
    WS-Management service and got a response saying the request was too large. For more information, see the about_Remote_
    Troubleshooting Help topic.

    I did some gooling, and made a change to the Web.config file for the powershell virtual directory. That makes the script work. https://www.pei.com/2015/10/windows-server-management-request-too-large/
    But then when i open Powershell for exchange again, it spits out all kinds of errors that it cant connect to the other servers because too many requests, etc..
    Unless i have to make this change on all servers. I just wanted to verify that this wont break anything else as far as you know.

  2. Great H

    Thanks Paul sincerely, every issues can be resolved after reading your articles instead of open case to Microsoft and waste a lot of time, truely expert.

  3. egemen

    Hello Paul,

    I run the script without any issue but even after the databases move to primary one, they instantly return their first state what could cause this issue?

    Regards,

  4. Felice Gioino

    Is it possible to balance DB’s by DAG?

  5. Mike

    Hi, Is it safe to copy database.edb and the logs from passive database member without dismounting the database? I wanted to manually copy the db from HQ to DR site and synchronize it as a dag member.

    Thank you.

    1. Mike Walker

      Negative! Never do anything directly with database/log files while the database is still mounted. There are many sites documenting how to do manual seeds by copying/restoring the database, but all require at least a brief outage to dismount and make the database consistent.

      Another way is to create new databases with the DAG config you want and then move all existing mailboxes to them, so the DAG synch happens at the same time as the moves.

  6. Adams Toomer

    *What if you actually WANT to activate them by their second preference, for maintenance on storage, is there a command to do so?

  7. Adams Toomer

    What you actually WANT to activate them by their second preference, for maintenance on storage, is there a command to do so?

  8. Stefan

    It seems that this script no longer works after CU11 which I think has to do with RPS proxying. Is there a workaround for CU11 to use this script? From what I have read, CU12 will restore RPS original functionality so this may be moot.

    1. Avatar photo
  9. sanju

    For me it never works

    S] D:Exchange Serverv15Scripts>.RedistributeActiveDatabases.ps1 -DagName DAG01 -BalanceDbsByActivationPreference

    annot convert value “DAG01″ to type
    Microsoft.Exchange.Data.Directory.SystemConfiguration.DatabaseAvailabilityGroup”. Error: “Cannot convert the
    DAG01” value of type “Deserialized.Microsoft.Exchange.Data.Directory.SystemConfiguration.DatabaseAvailabilityGroup”
    o type “Microsoft.Exchange.Data.Directory.SystemConfiguration.DatabaseAvailabilityGroup”.”
    t D:Exchange Serverv15ScriptsRedistributeActiveDatabases.ps1:2801 char:3
    $script:dag = Get-DatabaseAvailabilityGroup $DagName -Status
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

    Log-Error : [02:40:33.145 UTC] Could not find DAG matching ‘DAG01’!
    t D:Exchange Serverv15ScriptsRedistributeActiveDatabases.ps1:2806 char:3
    Log-Error ($RedistributeActiveDatabases_LocalizedStrings.res_0089 -f $DagName) …
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Log-Error

    When i run the Get-DatabaseAvailabilityGroup I see Correct DAG Names. I have removed the Server names here for example

    [PS] D:Exchange Serverv15Scripts>Get-DatabaseAvailabilityGroup

    Name Member Servers Operational Servers
    —- ————– ——————-
    DAG01
    DAG02
    DAG03
    DAG04

    I am 100 percent Sure DAG name is correct. I am on exchange 2013 CU8

      1. Will

        I had the same issue when I was using Powershell ISE with Exchange snap-in. Run this in EMS and it worked. Thanks Paul.

  10. Gareth Hillary

    This article looks like exactly what we need but when I try to go and run it I fall at the first hurdle.

    We are using Exchange 2013 so the scripts are in a slightly different folder to the syntax however I have edited it to reflect the appropriate folder, V15 instead of 14.

    I get the following output, please can you tell me where I am going wrong:

    [PS] C:\>C:Program FilesMicrosoftExchange ServerV15Scripts>.RedistributeActiveDatabases.ps1 -DagName DAG -ShowData
    base DistributionByServer | ft
    C:Program : The term ‘C:Program’ is not recognized as the name of a cmdlet, function, script file, or operable
    program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:1
    + C:Program FilesMicrosoftExchange ServerV15Scripts>.RedistributeActiveDatab …
    + ~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (C:Program:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    1. Gareth Hillary

      I am a pillock – I have realised how to execute the script. Navigate to the folder first via changing directory from the command line.

      Doh!

  11. Robban

    Hi

    I upgraded to CU10 and this wonderful script stopped working. On my still CU7 it works.
    Anyone noticed this?

    Errro:
    “Cannot process argument transformation on parameter ‘Identity’. Cannot convert value “DATABASENAME” to type “Microsoft.Exchan
    ge.Configuration.Tasks.DatabaseCopyIdParameter”. Error: “Cannot convert hashtable to an object of the following type: M
    icrosoft.Exchange.Configuration.Tasks.DatabaseCopyIdParameter. Hashtable-to-Object conversion is not supported in restr
    icted language mode or a Data section.”
    WARNING: [08:51:27.449 UTC] Cannot bind argument to parameter ‘mdb’ because it is null.Cannot process argument
    transformation on parameter ‘Identity’. Cannot convert value DATABASENAME” to type

    Regards Robban

  12. Greg

    Are there any ramifications on scheduling this script to run periodically/on startup?

    1. Avatar photo

      I wouldn’t run it on startup, that’s not the right time to be doing a DAG rebalance.

      Some people choose to schedule it to run just prior to their backups, if the backups depend on certain database copies being active. Others might run it nightly or weekly depending on how neat and tidy they like things to be.

      Personally I would just run it manually after completing any maintenance.

  13. David

    Ok, check this crazy huge command here:

    I have not tested yet.

    It is supposed to:

    1. Check in the SERVER1, which MailboxDatabases are mounted on it
    2. It lists all MailBoxDatabases from SERVER1 where the ActivationPreference is 2
    3. Displays info about which ones will be moved to the ActivationPreference2 Server where
    4. Ignore the ones that already are on the AP2 Server.

    Get-MailboxDatabase -Server SERVER1 | Where {$_.ServerName -eq “SERVER1”} | Sort Name | ForEach {$db=$_.Name; $xNow=$_.Server.Name ;$dbown=$_.ActivationPreference| Where {$_.Value -eq 2}; Write-Host $db “on” $xNow “Move to” $dbOwn.Key -NoNewLine; If ( $xNow -ne $dbOwn.Key){Write-host “Already On AP 2″ -ForegroundColor Red} {Write-Host ” Moving to” -ForegroundColor Blue; Move-ActiveMailboxDatabase $db – ActivateOnServer $dbOwn.key -confirm:$True} Else {Write-Host ” OK” -ForegroundColor Green}}

      1. David

        Ok, with a few tweaks here and there, this is the final ‘WORKING!’ version:

        Move All Databases From One Server to its Activation Preference 2

        Get-MailboxDatabase -Server SERVER1| Where {$_.ServerName -eq “SERVER1”} | Sort Name | ForEach {$db=$_.Name; $xNow=$_.Server.Name ;$dbown=$_.ActivationPreference | Where {$_.Value -eq 2}; Write-Host $db “on” $xNow “Will be moved to” $dbOwn.Key -NoNewLine; If ( $xNow -ne $dbOwn.Key){Write-host ” >>> Moving…” -ForegroundColor Red; Move-ActiveMailboxDatabase $db -ActivateOnServer $dbOwn.key -confirm:$False} Else {Write-Host ” – Already on Activation Preference 2″ -ForegroundColor Green}}

  14. David

    Hello, Paul.

    I would like to run a script or command line cmdlet, that could move all active mailbox databases from an specific server to the server whose activation preference is 2.

  15. Gary

    How would you script moving all databases to a specific server in the DAG instead of the preferred server? For instance, maintenance will be occurring on server 1 in the DAG so in preparation you move all databases to be mounted on server 2 in the DAG.

    1. Avatar photo
  16. Edwin

    What rights does the account that runs the script need? Our script account recently lost domain admin rights, and keeps failing now.

    1. quaaarks

      These accounts have domain-, schema-, Enterprise-rights

  17. quaaarks

    Hi,
    when I use this script: .RedistributeActiveDatabases.ps1 -DagName dag1 -ShowDatabaseDistributionByServer | ft
    I get following error:

    The operation couldn’t be performed because object ‘dag1’ couldn’t be found on ‘dc.domain.com’.
    + CategoryInfo : NotSpecified: (:) [Get-DatabaseAvailabilityGroup], ManagementObjectNotFoundException
    + FullyQualifiedErrorId : [Server=EXCH1,RequestId=eea7abfb-5a4a-4885-8740-f96617cb4dc7,TimeStamp=27.03.2014 16
    :03:43] D83A179C,Microsoft.Exchange.Management.SystemConfigurationTasks.GetDatabaseAvailabilityGroup
    + PSComputerName : exch1.domain.com

    Log-Error : [16:03:43.628 UTC] Could not find DAG matching ‘dag1’!
    At C:Program FilesMicrosoftExchange ServerV15ScriptsRedistributeActiveDatabases.ps1:2801 char:3
    + Log-Error ($RedistributeActiveDatabases_LocalizedStrings.res_0089 -f $DagName) …

    I receive these errors with Exchange 2013 as well as in Exchange 2010 Environment?
    I would appreciate any help

    1. Rosario

      Is the name of your DAG really dag1 ?

  18. Rosario

    Paul, thanks, another great article. My question:

    In a DAG none of the databases is mounted on one primary server. They are mounted on the two others. So I would like to redistribute or do a manual switch over, but before doing that, I would ask WHY were they mounted on the other two servers leaving that one server only with copies an no active DB?

    So is there a means to know the reason of this switch over? No hardware failure on that server, no Error entries in the Event Viewer. Where else should I investigate?

    Thanks a lot, Rosario

      1. Rosario

        Thanks, I found the Event-Viewer entries and would like to mention them here for reference.

        On the faulty server have a look at Event-Viewer->Applications and Services Logs->Microsoft->Exchange->HighAvailability and same path->MailboxDatabaseFailureItems

  19. James Slack

    Hi Paul,

    Is there a way to mount a DB on a specific server in a DAG when it is currently mounted on a different server in that DAG?

    We have 12 DBs and 2 servers (ignoring DR). Say I wish to mount only DB7 on DB2 instead of DB1 – how would I do this?

    The reason I ask is that we get some issues when we have to reboot one of the DAG servers. The DBs should all fail over to the other server, but sometimes one or two get stuck in limbo. This makes the other server take 19 minutes (due exchange services) to boot and those DBs that dont fail over are stuck offline until it comes back. I do the reboot correctly, stopping services etc. first.

    If I can dismount DBs one at a time and mount them on the server I desire, it will be a lot better.

    I believe the mount-database command will just mount the DB in the same place.

    Thanks

    1. James Slack

      Typo sorry “mount only DB7 on Server2 instead of Server1 – how would I do this?” – been one of those days

      1. Avatar photo

        For starters, you’ll avoid all this trouble if you place the DAG member in maintenance mode before you reboot it. Example here:

        https://www.practical365.com/how-to-install-updates-on-exchange-server-2010-database-availability-groups

        (refer to the parts on using StartDagServerMaintenance.ps1 and StopDagServerMaintenance.ps1)

        And just to be clear why this is encouraged:
        https://www.practical365.com/bother-running-dag-server-maintenance-mode-scripts/

        To answer your question, yes you can make any single database copy active on a DAG member without using this rebalance script. You simply do a manual switchover:

        http://technet.microsoft.com/en-us/library/dd298068(v=exchg.141).aspx

        1. James Slack

          Awesome, Thanks Paul.

          Sadly we updated to 2010 from 2003 and I had no in work training and outside of work was busy with other exams. This means most of the things that are different will remain unknown until you find something by chance (usually the hard way).

          This info is exactly what I needed, thank you.

          Time for me to get learning 2010… probably will have that down just in time to go to 2013.

        2. Avatar photo

          A lot of what you’ll learn for 2010 is still relevant in 2013 anyway, so hit it hard and you’ll be better off in the long run. Really it was the 2003 -> 2007/2010 jump that was the biggest in terms of new stuff to learn.

          There’s some free video training here if you or your team mates need somewhere to start:
          https://www.practical365.com/exchange-2010-free-training-videos/

  20. Jetty

    Question – I am not an exchange admin and am working my way through some Exchange items and would like to understand this better. What would happen in the event of a failure if the active database is mounted on the server with the activation preference of 2?

    1. Avatar photo

      In a failure situation a process called Best Copy Selection evaluates a number of factors and that is how the database copy to attempt to bring online is chosen. Activation preference is one of those factors but it is not the only one.

      If you’re asking if its possible that db copy AP=1 could come online, yes that is possible, if Best Copy Selection chooses that copy.

  21. Joe Hardy

    What kind of impact does this have on outlook clients in a 24/7/365 shop? Is there a default level of availability this script uses? ie: “none” – “best availibility”
    Wondering if end users will see any performance hits or disconnects in outlook if we run this cmdlet / script.
    Thanks,
    Joe

    1. Avatar photo

      Good question. I think it honors the setting on the database, but a quick scan through the script code didn’t find where that might be controlled.

      There’s always a risk even during a planned switchover that something will go wrong of course.

  22. Wayne

    Hi Paul

    What if i have 3 servers in single DAG (All roles installed on each) 2 are active/passive and 3rd is just passive , how do i make sure that the DB’s end up back on the original place and leave the 3rd as passive?

    1. Avatar photo

      There are no active/passive servers in a DAG. There are only active database copies and passive database copies.

      If you want to control which database copy becomes active when the rebalancing script is run as shown above, then you would set that database copy’s activation preference to 1.

  23. Christian

    Hi Paul,
    Do you know a way to include an email report the result of the command RedistributeActiveDatabases.ps1 -DagName DAG -BalanceDbsBy ActivationPreference in the script?

    1. Jamille

      Here’s a script to run a dag rebalance and to email you the results. You will have to change the variables below the main comments to suit your environment

      Edit: removed

      1. Avatar photo
        1. Jean-Luc Ch.

          What a pitty…

  24. Gary H

    Thanks Paul.. It works like a charm.

    Is there a Script to Automatically Rebalance going forth? or is the only method to run this rebalance script?

  25. David

    paul

    can you shed some light…..? IM getting this when i run issue this cmd

    thanks

    .RedistributeActiveDatabases.ps1 -DagName DAG -ShowDatabase
    DistributionByServer | ft

    [PS] C:Program FilesMicrosoftExchange ServerV14scripts>.RedistributeActiveDatabases.ps1 -DagName DAG -ShowDatabase
    DistributionByServer | ft
    C:Program FilesMicrosoftExchange ServerV14scriptsRedistributeActiveDatabases.ps1 : Parameter cannot be processed
    because the parameter name ‘ShowDatabase’ is ambiguous. Possible matches include: -ShowDatabaseCurrentActives -ShowData
    baseDistributionByServer -ShowDatabaseDistributionBySite.
    At line:1 char:34
    + .RedistributeActiveDatabases.ps1 <<<< -DagName DAG -ShowDatabase DistributionByServer | ft
    + CategoryInfo : InvalidArgument: (:) [RedistributeActiveDatabases.ps1], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameter,RedistributeActiveDatabases.ps1

  26. Hein

    Weird. Can’t see what i am doing wrong. I get this:

    At C:Program FilesMicrosoftExchange ServerV14scriptsRedistributeActiveDatabases.ps1:1928 char:3
    + return $moveSuccessful
    + ~~~~~~~~~~~~~~~~~~~~~~
    Control cannot leave a finally block.
    At C:Program FilesMicrosoftExchange ServerV14scriptsRedistributeActiveDatabases.ps1:2538 char:5
    + return $success
    + ~~~~~~~~~~~~~~~
    Control cannot leave a finally block.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : ControlLeavingFinally

    Hopefully you can shine a light on this and help me out 🙂

    1. Daniel Wielosz

      If you have Exchange 2010 on Windows Server 2012, you need to add -version 2.0 parameter:

      Below you can find definition of task sheduler action:

      powershell.exe -Version 2.0 -command “. ‘c:Program FilesMicrosoftExchange ServerV14binRemoteExchange.ps1’; Connect-ExchangeServer -auto;. ‘c:Program FilesMicrosoftExchange ServerV14ScriptsRedistributeActiveDatabases.ps1’ -DagName DAG -BalanceDbsByActivationPreference -confirm:`$true”

  27. M G

    Hi,
    Thanks Paul
    But how can i make it run automatically ?
    i mean it asks to verify moving databases but i like this script every night run as a scheduled task and fully automatic (i do not want to enter “y” press enter and …)
    i like it to be run without asking for verification

      1. Ahmed Gamal

        Run automatically by scheduler task on Action :

        Program/script:
        Start a program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

        Add arguments:
        -version 4.0 -NonInteractive -WindowStyle Hidden -command “. ‘C:\Program Files\Microsoft\Exchange Server\V15\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; .’C:\Program Files\Microsoft\Exchange Server\V15\Scripts\RedistributeActiveDatabases.ps1’ -DagName DAG-SAPTCO -BalanceDbsByActivationPreference -confirm:$false”

Leave a Reply