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″]
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.
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.
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,
You’ll need to look at your event log to see what is being logged when the active database copies are moving.
Is it possible to balance DB’s by DAG?
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.
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.
*What if you actually WANT to activate them by their second preference, for maintenance on storage, is there a command to do so?
What you actually WANT to activate them by their second preference, for maintenance on storage, is there a command to do so?
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.
Wouldn’t surprise me to hear that CU11 broke it. I don’t know if any fix, and CU12 is probably going to be released this month since the last update was in December.
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
Are you doing this in the Exchange Management Shell?
I had the same issue when I was using Powershell ISE with Exchange snap-in. Run this in EMS and it worked. Thanks Paul.
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
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!
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
Are there any ramifications on scheduling this script to run periodically/on startup?
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.
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}}
Ok. Good luck with your testing?
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}}
Gigantic PowerShell one-liners are messy and difficult to read and understand. Why not write it as a script instead? You’ll thank yourself later.
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.
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.
Use the start/stop DAG maintenance scripts. Demonstrated here:
https://www.practical365.com/how-to-install-updates-on-exchange-server-2010-database-availability-groups/
What rights does the account that runs the script need? Our script account recently lost domain admin rights, and keeps failing now.
These accounts have domain-, schema-, Enterprise-rights
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
Is the name of your DAG really dag1 ?
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
Switchovers and failovers are all logged in event logs. You can drill down into the Applications and Services Logs in event viewer to investigate.
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
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
Typo sorry “mount only DB7 on Server2 instead of Server1 – how would I do this?” – been one of those days
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
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.
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/
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.
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.
Pingback: markwilson.it » Core solutions of Microsoft Exchange Server 2013 brain dump
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.
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?
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
Jamille, I’ve removed your script from the comment. I recommend hosting your script somewhere like the TechNet Script Gallery so you can just link people to it.
http://gallery.technet.microsoft.com/scriptcenter
What a pitty…
Pingback: Installing Cumulative Updates for Exchange Server 2013
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?
That is the script, yes.
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
-ShowDatabaseDistributionByServer is all on one line. There’s a carriage return that shouldn’t be there.
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 🙂
I’ve never seen that before. Has the script been modified by someone?
You need to uninstall Windows Management Framework 3.0 (KB2506146 and KB2506143). I had the same error and after the uninstall it started working. See this article:
http://blogs.technet.com/b/exchange/archive/2012/12/14/windows-management-framework-3-0-on-exchange-2007-and-exchange-2010.aspx
Hope this helps,
David Garcia
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”
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
Add…
-confirm:$false
…to the end of the command.
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”
Pingback: Installing Updates on Exchange 2010 Database Availability Groups