Balancing the number of mailboxes across Exchange 2010 and 2007 databases
Introduction
In Exchange 2010, you now have the option to allow mailboxes to be automatically distributed across databases. However, the algorithm used simply randomly allocates the new mailbox to your chosen databases - rather than ensuring the mailbox count is balanced, and doesn't do anything about re-distributing mailboxes if you add new databases.
To help with this, and of course to help with any situation where you want to balance the number of mailboxes across a set of databases, I've written a simple script that help with moving mailboxes to balance out your databases.
Using Generate-DBBalanceScript.ps1
There's nothing too complicated about the script- it doesn't balance based on mailbox size (a future version), but simply creates a script with Move-Mailbox or New-MoveRequest commands that once complete, balances based on mailbox counts across the databases. You pass it the results of a Get-MailboxDatabase command, along with an output file that will contain the Mailbox move commands.
First of all, lets see it in action:
Of course, my example was the simplest - across all databases. Here's a few examples including the one above, and some others that show how to drill down to databases on specific servers:
Example One - Generate a move file based on all Exchange 2010 Databases:
Example Two - Generate a move file based on Exchange 2010 Databases located on a single server "servername":
.\Generate-BalanceMoveRequests.ps1 -DBs $o -OutputPowershellFile moves07.ps1 -Exchange2010:$false
Example Three - Generate a move file based on Exchange 2007 Databases located on two servers, "serverone" and "servertwo":
Download Generate-DBBalanceScript.ps1
You can download Generate-DBBalanceScript.ps1 here or view the script below.
Hope this helps!
.SYNOPSIS
Generates a Powershell file containing Mailbox Move Cmdlets to help balance mailbox databases, based on mailbox count, not size.
.DESCRIPTION
Using a list of Databases, works out the average number of mailboxes there should be per DB, then generates move commands to run seperately.
By Steve Goodman
.PARAMETER DBs
Databases to use
The result of a Get-MailboxDatabase cmdlet. Eg. (Get-MailboxDatabase -Server name)
.PARAMETER OutputPowershellFile
The filename to write, for example C:\output.ps1 or .\output.ps1
.PARAMETER Exchange2010
By default, true. Set to $false to generate Exchagne2007 move-mailbox commands
.EXAMPLE
Generate a move file based on all Exchange 2010 Databases
.\Generate-BalanceMoveRequests.ps1 -DBs (Get-MailboxDatabase) -OutputPowershellFile .\moves.ps1
.EXAMPLE
Generate a move file based on Exchange 2007 Databases located on a single server "servername"
$o=Get-MailboxDatabase -Server servername
.\Generate-BalanceMoveRequests.ps1 -DBs $o -OutputPowershellFile moves07.ps1 -Exchange2010:$false
.EXAMPLE
Generate a move file based on Exchange 2007 Databases located on two servers, "serverone" and "servertwo"
$o=Get-MailboxDatabase | where {$_.Server -eq "serverone" -or $_.Server -eq "servertwo"}
.\Generate-BalanceMoveRequests.ps1 -DBs $o -OutputPowershellFile moves07.ps1 -Exchange2010:$false
#>
param(
[parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Mailbox database object")][array]$DBs,
[parameter(Position=1,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Filename for output Powershell script")][string]$OutputPowershellFile,
[parameter(Position=2,Mandatory=$false,ValueFromPipeline=$false,HelpMessage="Is this for Exchange 2010")][bool]$Exchange2010=$true
)
# Check for Exchange cmdlets
if (!(Get-Command Get-MailboxDatabase -ErrorAction SilentlyContinue))
{
throw "Exchange Cmdlets not available";
}
# Check input object
if ($DBs[0].GetType().Name -ne "MailboxDatabase")
{
throw "Object is not an array of mailbox databases"
}
if ($DBs.Count -eq 1)
{
throw "You can't balance a single database";
}
# Check file does not exist
if ((Test-Path $OutputPowershellFile))
{
throw "File $($OutputPowershellFile) already exists";
}
# Initialise file
"# Mailbox Mail Powershell Script File, generated $(date)`r`n"|Out-File -FilePath $OutputPowershellFile -NoClobber
if (!(Test-Path $OutputPowershellFile))
{
throw "Could not write to $($OutputPowershellFile)";
}
# Initialise Variables
[int]$TotalMailboxes=0; # Total Mailboxes
[int]$BalancedCount=0; # Balanced Number of Mailboxes per DB
[array]$DBCounters=@(); # Array with DB Id, Mailbox Count and Mailbox listing
[array]$UA_DBCounters=@(); # Under allocated list from above, populated later
[array]$OA_DBCounters=@(); # Over allocated list from above, populated later
[array]$PA_DBCounters=@(); # Perfectly allocated list from above, populated later
[string]$Output=""; # Variable to write output text to
# Gather initial mailbox counts
Write-Host "Gathering Mailbox Counts"
for ($i = 0; $i -lt $DBs.Count; $i++)
{
Write-Progress -activity "Gathering Mailbox Counts" -status "Processing Database $($DBs[$i].Identity)" -PercentComplete (($i / $DBs.Count) * 100)
$Mailboxes = (Get-Mailbox -Database $DBs[$i].Identity -ResultSize Unlimited | select Identity)
$DBCounters=$DBCounters+1;
$DBCounters[$DBCounters.Count-1] = New-Object Object
$DBCounters[$DBCounters.Count-1] | Add-Member NoteProperty Database $DBs[$i].Identity
$DBCounters[$DBCounters.Count-1] | Add-Member NoteProperty Total $Mailboxes.Count
$DBCounters[$DBCounters.Count-1] | Add-Member NoteProperty Mailboxes $Mailboxes
$TotalMailboxes+=$Mailboxes.Count
}
Write-Progress -Activity "Gathering Mailbox Counts" -Completed -Status "Completed"
Write-Host "DB Counts are as follows:"
$DBCounters|Select Database,Total
$BalancedCount = $TotalMailboxes / $DBs.Count
Write-Host "Found $($TotalMailboxes) mailboxes across $($DBs.Count) databases. Aiming for $($BalancedCount) mailboxes per database."
Write-Host "Sorting Databases into over, under and perfectly allocated."
# Sort DBs into under-allocated, over-allocated and perfectly allocated
for ($i = 0; $i -lt $DBCounters.Count; $i++)
{
Write-Progress -activity "Sorting Databases into over, under and perfectly allocated" -status "Processing Database $($DBCounters[$i].Database)" -PercentComplete (($i / $DBCounters.Count) * 100)
if ($DBCounters[$i].Total -lt $BalancedCount)
{
$UA_DBCounters=$UA_DBCounters+1;
$UA_DBCounters[$UA_DBCounters.Count-1] = $DBCounters[$i];
} elseif ($DBCounters[$i].Total -gt $BalancedCount) {
$OA_DBCounters=$OA_DBCounters+1;
$OA_DBCounters[$OA_DBCounters.Count-1] = $DBCounters[$i];
} else {
$PA_DBCounters=$PA_DBCounters+1;
$PA_DBCounters[$PA_DBCounters.Count-1] = $DBCounters[$i];
}
}
Write-Progress -activity "Sorting Databases into over, under and perfectly allocated" -Completed -Status "Completed"
Write-Host "Found $($OA_DBCounters.Count) over, $($UA_DBCounters.Count) under and $($PA_DBCounters.Count) perfectly allocated";
# Make move list
Write-Host "Generating Powershell File '$($OutputPowershellFile)' to Balance DBs."
for ($i = 0; $i -lt $OA_DBCounters.Count; $i++)
{
Write-Progress -activity "Generating Powershell File '$($OutputPowershellFile)' to Balance DBs" -status "Processing Database $($OA_DBCounters[$i].Database)" -PercentComplete (($i / $OA_DBCounters.Count) * 100)
# Get the mailbox list
[array]$OA_Mailboxes = $OA_DBCounters[$i].Mailboxes
$UA_DBPointer=0;
for ($j=$BalancedCount; $j -lt $OA_Mailboxes.Count; $j++)
{
# Move to next underallocated DB if required
if ($UA_DBCounters[$UA_DBPointer].Total -ge $BalancedCount -and $UA_DBPointer -lt $UA_DBCounters.Count-1)
{
$UA_DBPointer++;
}
Write-Progress -activity "Generating move commands" -status "Processing $($OA_Mailboxes[$j].Identity)" -PercentComplete (($j / $OA_Mailboxes.Count) * 100)
# Generate a Powershell command for the move request
if ($Exchange2010)
{
$Output+="New-MoveRequest -Identity '$($OA_Mailboxes[$j].Identity)' -TargetDatabase '$($UA_DBCounters[$UA_DBPointer].Database)' -Confirm:" + '$false' + "`r`n";
} else {
$Output+="Move-Mailbox -Identity '$($OA_Mailboxes[$j].Identity)' -TargetDatabase '$($UA_DBCounters[$UA_DBPointer].Database)'`r`n";
}
$OA_DBCounters[$i].Total--; # Take one mailbox of the total on the overallocated DB
$UA_DBCounters[$UA_DBPointer].Total++; # Add one mailbox tot the total of the current underallocated DB
}
Write-Progress -activity "Generating move commands" -Completed -Status "Completed"
}
Write-Progress -activity "Generating Powershell File '$($OutputPowershellFile)' to Balance DBs" -Completed -Status "Completed"
Write-Host "DB Counts will be as follows after executing $($OutputPowershellFile):"
$OA_DBCounters|Select Database,Total
$UA_DBCounters|Select Database,Total
$PA_DBCounters|Select Database,Total
Write-Host "Writing Powershell file '$($OutputPowershellFile)'"
$Output | Out-File -FilePath $OutputPowershellFile -NoClobber -Append
Related posts:
- How to report which Exchange mailboxes group members have full access to
- Scripted Shared Mailbox Creation on Exchange 2007/2010
- Using the Exchange 2010 SP1 Mailbox Export features for Mass Exports to PST files
- Writing Powershell scripts that target Exchange 2007 and 2010
- Sync a text file to an Exchange distribution group



October 10th, 2010 - 19:34
This script looks like it’ll sort out a number of problems we’re having with the distribution of our mailboxes across our storage groups. We’ve got a SCR clustered Exchange 2007 environment and I’ve tried running your script but it fails immediately with the following error:
Unable to find type [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$fa
lse,HelpMessage="Mailbox database object")]: make sure that the assembly contai
ning this type is loaded.
To run the script I first typed:
$o=Get-MailboxDatabase -Server servername
followed by:
.\Generate-BalanceMoveRequests.ps1 -DBs $o -OutputPowershellFile moves07.ps1 -Exchange2010:$false
Apologies, I’m far from a powershell expert – more like a novice! Any help you could provide though would be great as this script is exactly the answer to our problems!
Thanks in advance,
Sam
October 13th, 2010 - 11:03
I’ll take a look – I did test on 2007 but will have another go. I tested on Powershell 2.0 so wonder if that is the issue..
Steve
October 13th, 2010 - 15:52
Hi Steve,
Many thanks! I’ll wait to hear from you – let me know if you need any more information about our environment etc. though.
Sam
October 13th, 2010 - 16:19
Hiya,
It looks like it’s a Powershell 1.0 issue – as a quick hack try the following:
Change the first bit of the script up until “# Check for Exchange cmdlets” to:
param($DBs,$OutputPowershellFile,$Exchange2010=$true)
# Check for Exchange cmdlets
This takes out some of the get-help compatibility and prompting for values, but assuming you put the right values (like you did above) it looks like it works fine on Win 2003 Ent + Exchange 2007 SP3 + Powershell 1.0.
Steve
October 14th, 2010 - 09:45
Hi Steve,
It’s working!!! That did the trick, thanks!
I’m planning to split the move script that’s generated into blocks of 100 mailboxes as we have around 1000 mailboxes to move (our old Exchange admin decided to tell the people creating mailboxes to create them all in one storage group for some reason leaving us with one SG with over 1800 mailboxes!!). Obviously we’ve got a fair amount of work to do to tell these users when we’ll be moving their mailboxes and to then schedule the appropriate scripts to run.
Thanks so much for your help with this – it’s saved us a huge amount of work!
Sam
October 14th, 2010 - 14:00
Hi Steve,
Sorry, one last question: Is there a way to tell the script to exclude one of the Storage Groups when balancing the mailboxes across the DBs? We need to exlude the First Storage Group completely as there is limited disk space available for this and it is only used for service mailboxes etc.
Thanks again,
Sam
October 15th, 2010 - 21:43
Hi Sam,
Would something like this as the bit to get the DBs do what you want?
$o = Get-MailboxDatabase | Where {$_.Storagegroup -ne “The one to exclude”}
Steve
October 18th, 2010 - 10:02
Hi Steve,
Thanks again – this worked, although with a slight modification:
I changed it to:
$o=Get-MailboxDatabase -server mkt-mbx01 | where-object {$_.name -ne “Mailbox Database”}
This excludes the first storage group’s mailbox DB successfully from the calculations for balancing the mailboxes.
Thanks once again for all your help – I’m learning more from you about Powershell scripting than I have from numerous books!
Sam
October 18th, 2010 - 13:44
Hi Sam,
Happy to help
Glad all is working the way you want.
Steve
October 18th, 2010 - 11:27
interesting, thanks
October 23rd, 2010 - 14:30
I just signed up to your blogs rss feed. Will you post more on this subject?
November 1st, 2010 - 13:11
Yes sure, let me know what you are interested in finding out.
November 3rd, 2010 - 22:12
Not really good with the scripting thing but i need to do this load balancing across top 2 exchange 2007 servers with 4 storage groups each. How would i achieve this using your scripts
November 4th, 2010 - 09:58
Hi Lamont,
You would use Example three from above:
$o=Get-MailboxDatabase | where {$_.Server -eq “serverone” -or $_.Server -eq “servertwo”}
.\Generate-BalanceMoveRequests.ps1 -DBs $o -OutputPowershellFile moves07.ps1 -Exchange2010:$false
Also, if you are using Powershell V1 and not Powershell V2 you will need to do this:
Change the first bit of the script up until “# Check for Exchange cmdlets” to:
param($DBs,$OutputPowershellFile,$Exchange2010=$true)
# Check for Exchange cmdlets
Steve
November 24th, 2010 - 17:36
Hi Steve,
I enjoy reading your blog. I’m trying to come up with a script to do something similar to this one. Our helpdesk creates all new mailboxes in one SG (Staging) and then we spread them out among the other SG’s. to balance them. I would like to automate this task to move them to the least populated SG’s, similar to what you are doing with these scripts.
November 24th, 2010 - 22:03
Hey Randy,
It shouldn’t be too hard to change the script to do what you want, if it won’t out of the box. Are you trying to empty out the staging SG on each run of the script?
Steve
November 29th, 2010 - 15:50
Hi Steve,
That is exactly what we would like to do…
Randy
December 1st, 2010 - 19:24
Oh, and I should point out that we are running Exchange 2007.
December 1st, 2010 - 19:29
Hey Randy,
I’ll take a look and if needed update the script/add extra info. Might be in a couple of days tho!
Steve
December 4th, 2010 - 20:09
Hi Steve,
Great script! Is it possible to get the reverse, balance mailbox databases based on mailbox size not count for Exchange 2010?
Cheers,
Alan
December 4th, 2010 - 22:07
Hi Alan,
Glad you like it. I’d been thinking the same thing – it would be useful to balance based on size instead of mailbox numbers.
Balancing on mailbox numbers has a basis in each DB’s underlying LUN being fully provisioned to be able to support full quotas for each mailbox. However another approach could be to add storage and additional DBs as mailboxes grow toward their quotas, and this would require re-balancing the databases based on size as you suggest.
So – It’s added to my to-do list
Steve
December 15th, 2010 - 21:55
Hi,
thanks for your script . I tried and it work but there is a small issue while running moves.ps1 in exchange 2007 environments . so issue is that for every mailbox move it prompts for yes or No input. so can you help me with that so that all i can do without changing anything in moves.ps1. or there is any way to add -confirm :$false in each line while generating the script.
January 24th, 2011 - 13:58
Hi Steve
Great script. Any news on a script that are able to relocate based on size
Thanks,
Peter
January 24th, 2011 - 23:10
I will have to do that soon, won’t I.. And take into account archive mailboxes, too. It is on my list – the new year has been pretty busy so far so just getting a handle again on the blog
Steve
March 3rd, 2011 - 15:16
Hi Steve,
I did notice one issue when the script generates the list of moves. Currently it uses the Identity of each user which seems to the OU plus CN. We have some users with parenthesis in the name of the OU where their mailbox resides which causes the script to fail with the following error:
The term ‘Sales’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spell
ing of the name, or if a path was included, verify that the path is correct and try again.
At C:\Tech\Scripts\PowerShell\dbmoves.ps1:41 char:83
+ New-MoveRequest -Identity ‘domain.com/Corp/Users/HQ (Sales <<<< )/Smith, Tom' -TargetDat
abase 'DB15'
+ CategoryInfo : ObjectNotFound: (Sales:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Is there any way to have it output the user name via PrimarySMTPAddress in the move script?
Thanks,
-Devon
March 19th, 2011 - 22:29
Hi Devon
Have mailed you an update
Steve
July 27th, 2011 - 15:04
Hi Steve,
Do you have any information on how to balance the databases based on mailbox size and only on a select list of databases? Thanks for all you do.
August 30th, 2011 - 16:33
Hi Steve,
We have 6 databases in all, but they are in pairs. Just for an example say there are two on Solid state drives, two on Fiber channel 15K and 2 on SATA. What would I have to do to get your script to balance mailboxes across two server but just within two specific databases?
In case that isn’t completely clear here is an example:
Server 1 databases: SS-Server1-DB1, FC-Server1-DB1, SATA-Server1-DB1
Server 2 databases: SS-Server2-DB1, FC-Server2-DB1, SATA-Server2-DB1
I would like to balance the mailboxes between the two SS* databases, then the mailboxes between the two FC* databases, and finally the mailboxes between the two SATA* databases.
Thanks for your assistance.
Greg
September 20th, 2011 - 15:58
Steve,
This is a fine piece of work. I am so close to getting it working but keep hitting some limit. Below is output that I get from any Exchange 2010 server where I run this. We have a 12 node DAG that just got 4 new nodes introduced and I’m trying to balance those 19705 accounts across 12 servesr rather than the current 8. There are 96 new databases and the script targets 75 per db which makes sense. What is perplexing is that the file it generates 7103 New-MoveRequests but ignores 58 databases and as you can see below it overloads 36 db’s. Have I hit some limit? Any help would be appreciated.
—————————————————————————————————————–
Found 19705 mailboxes across 264 databases. Aiming for 75 mailboxes per database.
Sorting Databases into over, under and perfectly allocated.
Found 168 over, 96 under and 0 perfectly allocated
Generating Powershell File ‘.\moves6.ps1′ to Balance DBs.
DB Counts will be as follows after executing .\moves6.ps1:
EXSRV09DB01 — 75
EXSRV09DB02 — 75
EXSRV09DB03 — 75
EXSRV10DB01 — 75
EXSRV10DB02 — 75
EXSRV10DB03 — 75
EXSRV11DB01 — 75
EXSRV11DB02 — 75
EXSRV11DB03 — 75
EXSRV12DB01 — 75
EXSRV12DB02 — 75
EXSRV12DB03 — 75
EXSRV01DB01 — 75
EXSRV01DB02 — 75
EXSRV01DB03 — 75
EXSRV01DB04 — 75
EXSRV09DB04 — 75
EXSRV09DB05 — 75
EXSRV09DB06 — 75
EXSRV09DB07 — 75
EXSRV09DB08 — 75
EXSRV09DB09 — 75
EXSRV10DB04 — 75
EXSRV10DB05 — 75
EXSRV10DB06 — 75
EXSRV10DB07 — 75
EXSRV10DB08 — 75
EXSRV10DB09 — 75
EXSRV11DB04 — 75
EXSRV11DB07 — 75
EXSRV11DB05 — 75
EXSRV11DB06 — 75
EXSRV11DB09 — 75
EXSRV11DB08 — 75
EXSRV12DB06 — 75
EXSRV12DB05 — 75
EXSRV12DB04 — 75
EXSRV12DB07 — 75
EXSRV12DB08 — 75
EXSRV12DB09 — 75
EXSRV01DB06 — 75
EXSRV01DB10 — 75
EXSRV01DB12 — 75
EXSRV01DB09 — 75
EXSRV01DB07 — 75
EXSRV01DB08 — 75
EXSRV01DB05 — 75
EXSRV01DB11 — 75
EXSRV09DB10 — 75
EXSRV09DB11 — 75
EXSRV09DB12 — 75
EXSRV09DB13 — 75
EXSRV09DB14 — 75
EXSRV09DB15 — 75
EXSRV09DB16 — 75
EXSRV09DB17 — 75
EXSRV09DB18 — 75
EXSRV10DB10 — 75
EXSRV10DB11 — 75
EXSRV10DB12 — 75
EXSRV10DB13 — 75
EXSRV10DB14 — 75
EXSRV10DB15 — 75
EXSRV10DB16 — 75
EXSRV10DB17 — 75
EXSRV10DB18 — 75
EXSRV11DB11 — 75
EXSRV11DB18 — 75
EXSRV11DB13 — 75
EXSRV11DB12 — 75
EXSRV11DB10 — 75
EXSRV11DB16 — 75
EXSRV11DB17 — 75
EXSRV11DB15 — 75
EXSRV11DB14 — 75
EXSRV12DB10 — 75
EXSRV12DB11 — 75
EXSRV12DB12 — 75
EXSRV12DB13 — 75
EXSRV12DB14 — 75
EXSRV12DB15 — 75
EXSRV12DB16 — 75
EXSRV12DB17 — 75
EXSRV12DB18 — 75
EXSRV01DB19 — 75
EXSRV01DB22 — 75
EXSRV01DB15 — 75
EXSRV01DB14 — 75
EXSRV01DB23 — 75
EXSRV01DB17 — 75
EXSRV01DB16 — 75
EXSRV01DB21 — 75
EXSRV01DB20 — 75
EXSRV01DB13 — 75
EXSRV01DB18 — 75
EXSRV01DB24 — 75
EXSRV02DB01 — 75
EXSRV02DB02 — 75
EXSRV02DB03 — 75
EXSRV02DB04 — 75
EXSRV02DB05 — 75
EXSRV02DB06 — 75
EXSRV02DB07 — 75
EXSRV02DB08 — 75
EXSRV02DB09 — 75
EXSRV02DB10 — 75
EXSRV02DB11 — 75
EXSRV02DB12 — 75
EXSRV02DB13 — 75
EXSRV02DB14 — 75
EXSRV02DB15 — 75
EXSRV02DB16 — 75
EXSRV02DB17 — 75
EXSRV02DB18 — 75
EXSRV02DB19 — 75
EXSRV02DB20 — 75
EXSRV02DB21 — 75
EXSRV02DB22 — 75
EXSRV02DB23 — 75
EXSRV02DB24 — 75
EXSRV03DB01 — 75
EXSRV03DB02 — 75
EXSRV03DB03 — 75
EXSRV03DB04 — 75
EXSRV03DB05 — 75
EXSRV03DB06 — 75
EXSRV03DB07 — 75
EXSRV03DB08 — 75
EXSRV03DB09 — 75
EXSRV03DB10 — 75
EXSRV03DB11 — 75
EXSRV03DB12 — 75
EXSRV03DB13 — 75
EXSRV03DB14 — 75
EXSRV03DB15 — 75
EXSRV03DB16 — 75
EXSRV03DB17 — 75
EXSRV03DB18 — 75
EXSRV03DB19 — 75
EXSRV03DB20 — 75
EXSRV03DB21 — 75
EXSRV03DB23 — 75
EXSRV03DB22 — 75
EXSRV03DB24 — 75
EXSRV08DB01 — 75
EXSRV08DB02 — 75
EXSRV08DB03 — 75
EXSRV08DB04 — 75
EXSRV08DB05 — 75
EXSRV08DB06 — 75
EXSRV08DB07 — 75
EXSRV08DB08 — 75
EXSRV08DB09 — 75
EXSRV08DB10 — 75
EXSRV08DB11 — 75
EXSRV08DB12 — 75
EXSRV08DB13 — 75
EXSRV08DB14 — 75
EXSRV08DB15 — 75
EXSRV08DB16 — 75
EXSRV08DB17 — 75
EXSRV08DB18 — 75
EXSRV08DB19 — 75
EXSRV08DB20 — 75
EXSRV08DB21 — 75
EXSRV08DB22 — 75
EXSRV08DB23 — 75
EXSRV08DB24 — 75
EXSRV04DB01 — 75
EXSRV04DB02 — 240
EXSRV04DB03 — 238
EXSRV04DB04 — 237
EXSRV04DB05 — 236
EXSRV04DB06 — 234
EXSRV04DB07 — 233
EXSRV04DB08 — 231
EXSRV04DB09 — 230
EXSRV04DB10 — 227
EXSRV04DB11 — 225
EXSRV04DB12 — 223
EXSRV04DB13 — 220
EXSRV04DB14 — 218
EXSRV04DB15 — 216
EXSRV04DB16 — 214
EXSRV04DB17 — 212
EXSRV04DB18 — 210
EXSRV04DB19 — 208
EXSRV04DB20 — 206
EXSRV04DB21 — 204
EXSRV04DB22 — 200
EXSRV04DB23 — 195
EXSRV04DB24 — 191
EXSRV05DB06 — 185
EXSRV05DB02 — 180
EXSRV05DB08 — 176
EXSRV05DB09 — 173
EXSRV05DB04 — 169
EXSRV05DB03 — 161
EXSRV05DB05 — 155
EXSRV05DB07 — 150
EXSRV05DB01 — 143
EXSRV05DB14 — 132
EXSRV05DB12 — 112
EXSRV05DB11 — 106
EXSRV05DB10 — 90
EXSRV05DB15 — 50
EXSRV05DB16
EXSRV05DB17
EXSRV05DB13
EXSRV05DB18
EXSRV05DB19
EXSRV05DB20
EXSRV05DB24
EXSRV05DB21
EXSRV05DB22
EXSRV05DB23
EXSRV07DB03
EXSRV07DB01
EXSRV07DB02
EXSRV07DB04
EXSRV07DB05
EXSRV07DB06
EXSRV07DB07
EXSRV07DB08
EXSRV07DB09
EXSRV07DB10
EXSRV07DB11
EXSRV07DB12
EXSRV07DB13
EXSRV07DB14
EXSRV07DB15
EXSRV07DB16
EXSRV07DB17
EXSRV07DB18
EXSRV07DB19
EXSRV07DB20
EXSRV07DB21
EXSRV07DB22
EXSRV07DB24
EXSRV07DB23
EXSRV06DB01
EXSRV06DB02
EXSRV06DB03
EXSRV06DB04
EXSRV06DB05
EXSRV06DB06
EXSRV06DB07
EXSRV06DB08
EXSRV06DB09
EXSRV06DB10
EXSRV06DB11
EXSRV06DB12
EXSRV06DB13
EXSRV06DB14
EXSRV06DB16
EXSRV06DB20
EXSRV06DB17
EXSRV06DB18
EXSRV06DB19
EXSRV06DB15
EXSRV06DB21
EXSRV06DB22
EXSRV06DB23
EXSRV06DB24
Writing Powershell file ‘.\moves.ps1′
—————————————————————————————————————–
September 20th, 2011 - 22:38
Hiya,
I’ve not tried the script on that many mailboxes and wouldn’t recommend running that many move requests in one go (though, I must admit the script shouldn’t have went wrong).
Do you have any better success if you limit the number of databases, perhaps balancing 1-10, 11, 20 etc?
Steve
September 21st, 2011 - 00:34
Steve,
Thanks for getting back to me. How would I limit? I am excluding a dozen resource account databases. I was trying to figure out a way to try and have it see half of our server and do the balancing against it only. I guess the challenge is how to omit some and include only others?
September 21st, 2011 - 01:23
Steve,
Stretching my weak powershell skills to their limits I managed to do all the inclusions/exclusions and divide everything in half. Half of my existing servers coupled with half the new in each new set. Same results but only half as much
Same deal. It excludes most, not all of the new databases. We’ve done get-mailboxdatabase |fl side by side between working and non-working db’s and their identical. All databases were created with standard script as you can imagine what a chore it would be manually.
Any ideas? Thanks for your help.
Found 9636 mailboxes across 132 databases. Aiming for 73 mailboxes per database.
Sorting Databases into over, under and perfectly allocated.
Found 84 over, 48 under and 0 perfectly allocated
Generating Powershell File ‘.\moves.ps1′ to Balance DBs.
DB Counts will be as follows after executing .\moves.ps1
September 21st, 2011 - 12:31
Steve,
I quarted it down to 72 databases and have the same strange results. The balacing is going against 3 servers, 2 old and one new. Results below:
Found 5399 mailboxes across 72 databases. Aiming for 75 mailboxes per database.
Sorting Databases into over, under and perfectly allocated.
Found 48 over, 24 under and 0 perfectly allocated
Generating Powershell File ‘.\moves1-2to6.txt’ to Balance DBs.
DB Counts will be as follows after EXSRVecuting .\moves1-2to6.txt:
EXSRV01DB01 — 75
EXSRV01DB02 — 75
EXSRV01DB03 — 75
EXSRV01DB04 — 75
EXSRV01DB06 — 75
EXSRV01DB10 — 75
EXSRV01DB12 — 75
EXSRV01DB09 — 75
EXSRV01DB07 — 75
EXSRV01DB08 — 75
EXSRV01DB05 — 75
EXSRV01DB11 — 75
EXSRV01DB19 — 75
EXSRV01DB22 — 75
EXSRV01DB15 — 75
EXSRV01DB14 — 75
EXSRV01DB23 — 75
EXSRV01DB17 — 75
EXSRV01DB16 — 75
EXSRV01DB21 — 75
EXSRV01DB20 — 75
EXSRV01DB13 — 75
EXSRV01DB18 — 75
EXSRV01DB24 — 75
EXSRV02DB01 — 75
EXSRV02DB02 — 75
EXSRV02DB03 — 75
EXSRV02DB04 — 75
EXSRV02DB05 — 75
EXSRV02DB06 — 75
EXSRV02DB07 — 75
EXSRV02DB08 — 75
EXSRV02DB09 — 75
EXSRV02DB10 — 75
EXSRV02DB11 — 75
EXSRV02DB12 — 75
EXSRV02DB13 — 75
EXSRV02DB14 — 75
EXSRV02DB15 — 75
EXSRV02DB16 — 75
EXSRV02DB17 — 75
EXSRV02DB18 — 75
EXSRV02DB19 — 75
EXSRV02DB20 — 75
EXSRV02DB21 — 75
EXSRV02DB22 — 75
EXSRV02DB23 — 75
EXSRV02DB24 — 75
EXSRV06DB01 — 75
EXSRV06DB02 — 118
EXSRV06DB03 — 116
EXSRV06DB04 — 114
EXSRV06DB05 — 111
EXSRV06DB06 — 109
EXSRV06DB09 — 107
EXSRV06DB07 — 105
EXSRV06DB08 — 103
EXSRV06DB10 — 101
EXSRV06DB11 — 98
EXSRV06DB12 — 96
EXSRV06DB13 — 93
EXSRV06DB14 — 90
EXSRV06DB16 — 88
EXSRV06DB20 — 86
EXSRV06DB17 — 83
EXSRV06DB18 — 77
EXSRV06DB19 — 27
EXSRV06DB15
EXSRV06DB21
EXSRV06DB22 — 2
EXSRV06DB23
EXSRV06DB24
Writing Powershell file ‘.\moves1-2to6.txt’
September 21st, 2011 - 15:29
Steve,
Sorry I won’t bombard with anymore information after this. I reduced this down to 2 servers, old to new with 18 databases balancing to 24. Still strange results. Any thoughts?
.\Generate-DBBalanceScript.ps1 -DBs $o -OutputPowershellFile .\moves9to4.2.txt
Gathering Mailbox Counts
DB Counts are as follows:
Database Total
———— —–
EXSRV09DB01 — 122
EXSRV09DB02 — 122
EXSRV09DB03 — 120
EXSRV09DB04 — 118
EXSRV09DB05 — 120
EXSRV09DB06 — 109
EXSRV09DB07 — 118
EXSRV09DB08 — 115
EXSRV09DB09 — 117
EXSRV09DB10 — 112
EXSRV09DB11 — 116
EXSRV09DB12 — 106
EXSRV09DB13 — 111
EXSRV09DB14 — 99
EXSRV09DB15 — 103
EXSRV09DB16 — 108
EXSRV09DB17 — 108
EXSRV09DB18 — 103
EXSRV04DB01 — 5
EXSRV04DB02 — 5
EXSRV04DB03 — 5
EXSRV04DB04 — 5
EXSRV04DB05 — 5
EXSRV04DB06 — 5
EXSRV04DB07 — 5
EXSRV04DB08 — 5
EXSRV04DB09 — 6
EXSRV04DB10 — 5
EXSRV04DB11 — 4
EXSRV04DB12 — 5
EXSRV04DB13 — 5
EXSRV04DB14 — 4
EXSRV04DB15 — 6
EXSRV04DB16 — 3
EXSRV04DB17 — 10
EXSRV04DB21 — 10
EXSRV04DB19 — 6
EXSRV04DB23 — 11
EXSRV04DB20 — 10
EXSRV04DB22 — 3
EXSRV04DB18 — 4
EXSRV04DB24 — 3
Found 2162 mailboxes across 42 databases. Aiming for 51 mailboxes per database.
Sorting Databases into over, under and perfectly allocated.
Found 18 over, 24 under and 0 perfectly allocated
Generating Powershell File ‘.\moves9to4.2.txt’ to Balance DBs.
DB Counts will be as follows after executing .\moves9to4.2.txt:
EXSRV09DB01 — 51
EXSRV09DB02 — 51
EXSRV09DB03 — 51
EXSRV09DB04 — 51
EXSRV09DB05 — 51
EXSRV09DB06 — 51
EXSRV09DB07 — 51
EXSRV09DB08 — 51
EXSRV09DB09 — 51
EXSRV09DB10 — 51
EXSRV09DB11 — 51
EXSRV09DB12 — 51
EXSRV09DB13 — 51
EXSRV09DB14 — 51
EXSRV09DB15 — 51
EXSRV09DB16 — 51
EXSRV09DB17 — 51
EXSRV09DB18 — 51
EXSRV04DB01 — 51
EXSRV04DB02 — 67
EXSRV04DB03 — 67
EXSRV04DB04 — 66
EXSRV04DB05 — 65
EXSRV04DB06 — 64
EXSRV04DB07 — 64
EXSRV04DB08 — 63
EXSRV04DB09 — 62
EXSRV04DB10 — 61
EXSRV04DB11 — 61
EXSRV04DB12 — 60
EXSRV04DB13 — 59
EXSRV04DB14 — 58
EXSRV04DB15 — 57
EXSRV04DB16 — 56
EXSRV04DB17 — 55
EXSRV04DB21 — 54
EXSRV04DB19 — 52
EXSRV04DB23 — 51
EXSRV04DB20 — 41
EXSRV04DB22 — 3
EXSRV04DB18 — 4
EXSRV04DB24 — 3
Writing Powershell file ‘.\moves9to4.2.txt’
October 27th, 2011 - 15:39
Steve, did you ever update this script to balance mailboxes based on size? We’ve got to divide a single database into 5 and we want to balance the size of the database.
November 8th, 2011 - 00:23
Hi Michael,
I haven’t had a look at it yet, sadly it’s hard to come back to the older posts to add features as I have been pretty busy over the last few months.
Steve
November 29th, 2011 - 02:25
Steve, do you know if a script can be created to rebalance the DAG in 2010?
If I have 3 servers, 3 databases and have copies of each DB on each server, If I lose a server the DB all work but the third server is never used again when back online unless I manually balance them.
November 30th, 2011 - 23:40
Hiya,
A script is built into Exchange 2010 which performs this:
Open Exchange Management Shell:
cd $exscripts
\RedistributeActiveDatabases.ps1 -DagName DAG -BalanceDbsByActivationPreference
Steve
January 9th, 2012 - 17:10
Hey there Steve, I was wondering if you ever got a chance last year to write the Generate-BalancebySizeMoveRequests.ps1????
Chris
January 18th, 2012 - 21:11
Great script Steve!!!
February 1st, 2012 - 18:33
Cheers Shawn,
Steve