Home Β» Exchange Server Β» How to Rebalance Mailbox Databases in an Exchange Server Database Availability Group

How to Rebalance Mailbox Databases in an Exchange Server Database Availability Group

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.

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.

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

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

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

56 comments

  1. M G says:

    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

  2. Hein says:

    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 πŸ™‚

  3. David says:

    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

  4. Gary H says:

    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?

  5. Christian says:

    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?

  6. Wayne says:

    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?

    • 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.

  7. Joe Hardy says:

    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

    • 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.

  8. Jetty says:

    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?

    • 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.

  9. James Slack says:

    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

  10. Rosario says:

    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

      • Rosario says:

        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

  11. quaaarks says:

    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

  12. Edwin says:

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

  13. Gary says:

    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.

  14. David says:

    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. David says:

    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}}

      • David says:

        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}}

    • 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.

  16. Robban says:

    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

  17. Gareth Hillary says:

    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

    • Gareth Hillary says:

      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!

  18. sanju says:

    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

  19. Stefan says:

    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.

  20. Adams Toomer says:

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

  21. Adams Toomer says:

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

  22. Mike says:

    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.

    • Mike Walker says:

      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.

Leave a Reply

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