Loadbalance of the Exchange Database is very important. We need to make sure that database is not dumped with all the mailbox and once database gets big then move maiboxes to the other database. We can automate this process buy make the script to find the smallest size of the database in the Exchange orginisation and create the mailbox in the same
$MailboxSvr = Get-MailboxServer | select name
$i = 0
foreach($svr in $mailboxsvr)
{
$db = Get-MailboxDatabase -Server $svr.Name
foreach($database in $db)
{
$Server = $database.Server.Name
$Db = $database.Identity
$edbfilepath = $database.EdbFilePath
$path = “`\`\” + $Server + “`\” + $edbfilepath.DriveName.Remove(1) + “$”+ $edbfilepath.PathName.Remove(0,2)
$Dbsize = get-item $path |select-object length
$K = $Server + ” ” + $Db + ” ” + $Dbsize.Length
if ($i -eq 0 )
{
$edbsize = $Dbsize.Length
}
If ($edbsize -gt $Dbsize.Length)
{
$edbsize = $Dbsize.Length
$sdb = $database.Identity
}
$i = 1
}
}
Write-output “ENTER THE FOLLOWING DETAILS”
$DName = Read-Host “User Diplay Name ”
$FName = Read-Host “First Name ”
$LName = Read-Host “Last Name ”
$passwd = Read-Host “Password ” -asSecureString
$PrincipalName = $FName + “.” + $LName + “@domain.com”
$Aliasname = $FName + “.” + $LName
New-Mailbox -Name $DName -Database $sdb -UserPrincipalName $PrincipalName -FirstName $FName -LastName $LName -Alias $Aliasname -Password $passwd -ResetPasswordOnNextLogon $true -SamAccountName $Aliasname
You can get the complete copy of the code in the below link file
This is a great tool, thanks so much. If it wouldnt be too much trouble, I have the following issue that probably is just a small change that I cant figure out. I have 20 database, and SG20 is reserved for resource mailboxes.
Is there a way to tell it to load balance across all databases, excuding one?? Thanks again!
Hi, I have modified the code, added new line. you need add the details of SG20 which is allocated for Resource mailbox in the below line. Please let know if it works for you
$MailboxSvr = Get-MailboxServer | select name
$i = 0
foreach($svr in $mailboxsvr)
{
$db = Get-MailboxDatabase -Server $svr.Name
foreach($database in $db)
{
if $database.Identity -ne “Server\Storagegroup\Database”
{
$Server = $database.Server.Name
$Db = $database.Identity
$edbfilepath = $database.EdbFilePath
$path = “`\`\” + $Server + “`\” + $edbfilepath.DriveName.Remove(1) + “$”+ $edbfilepath.PathName.Remove(0,2)
$Dbsize = get-item $path |select-object length
$K = $Server + ” ” + $Db + ” ” + $Dbsize.Length
if ($i -eq 0 )
{
$edbsize = $Dbsize.Length
}
If ($edbsize -gt $Dbsize.Length)
{
$edbsize = $Dbsize.Length
$sdb = $database.Identity
}
$i = 1
}
}
}
Nice work… Your script is much closer to what I need than any of the others I’ve found so far. (most have to be run on the mailbox server in question). I’m looking to put together a script that outputs the smallest (in terms of total mail) database, but my mailboxe servers are CCR clusters, and the script you have won’t parse, as it cannot connect to \\servername\driveletter$ because \\servername is a ccr cluster name, not a physical machine. I believe the only way to get what I need would be to recursively count up all the mailbox sizes in each database and then sort that count, but I have no idea where to start for that.
Thanks!
Paul
Hi Krishna
great script. one problem though. i am running exchange 2007 in CCR. the $path varialbe return the CMS name which is only a node name and so it comes back with error.
Cannot find path ‘\\briexmail01\g$\exchange\DB_BRIEXMAIL01_08\DB_BRIEXMAIL01_08.EDB’ because it does not exist.
At :line:14 char:23
+ $Dbsize = get-item <<<< $path |select-object length
we have 2 clustered mailbox servers briexmail01 and briexmail02
briexmb01 and briexmb02 are in cluster briexmail01
briexmb03 and briexmb04 are in cluster briexmail02
any thoughts
any assistance would be greatly appreciated
Hi Paul
the script below should fix your issue with CCR.
############################################
$SourceFile = “c:\scripts\CCRDatabases.csv”
$DBlist = Import-Csv $SourceFile
$i = 0
foreach ($db in $DBlist)
{
########### Node name is either of the CCR cluster nodes###############
########### Headers of CSV identity,Nodename##############
$identity = $Db.identity
$Nodename = $Db.Nodename
$colitems = Get-MailboxDatabase $identity | Select Identity, @{Name=”Size”;Expression={$objitem = (Get-MailboxDatabase $Identity); $path = “`\`\” + $Nodename + “`\” + $objItem.EdbFilePath.DriveName.Remove(1).ToString() + “$”+ $objItem.EdbFilePath.PathName.Remove(0,2); $size = ((Get-ChildItem $path).length)/1048576KB; [math]::round($size, 2)}}, @{Name=”Sizeb”;Expression={$objitem = (Get-MailboxDatabase $Identity); $path = “`\`\” + “$Nodename” + “`\” + $objItem.EdbFilePath.DriveName.Remove(1).ToString() + “$”+ $objItem.EdbFilePath.PathName.Remove(0,2); $sizeb = ((Get-ChildItem $path).length)/1024KB; [math]::round($sizeb, 2)}}, @{Name=”Mailbox”;expression={(Get-Mailbox -Database $Identity | Measure-Object).Count}}
##if($error.count -gt 0){
##Write-host “Database not present”
##$error.clear()
##}
##else
foreach ($obj in $colitems)
{
if ($i -eq 0 )
{
$smsize = $obj.size
}
If ($smsize -gt $obj.size)
{
$smsize = $obj.size
$smidentity = $obj.Identity
}
$i = 1
write-host $obj.Identity, $obj.Size “GB” ,$obj.Sizeb “MB” ,No of Mailboxes $obj.Mailbox
} }
Write-output “ENTER THE FOLLOWING DETAILS”
write-host $smidentity $smsize
$DName = Read-Host “User Diplay Name “
$FName = Read-Host “First Name “
$LName = Read-Host “Last Name “
$passwd = Read-Host “Password ” -asSecureString
$PrincipalName = $FName + “_” + $LName + “@domain.com”
$Aliasname = Read-Host “Alias “
New-Mailbox -Name $DName -Database $smidentity -UserPrincipalName $PrincipalName -FirstName $FName -LastName $LName -Alias $Aliasname -Password $passwd -ResetPasswordOnNextLogon $true -SamAccountName $Aliasname
You really make it seem so easy with your presentation
but I find this topic to be actually something that I think I would never understand.
It seems too complex and extremely broad for me. I’m looking forward for
your next post, I’ll try to get the hang of it!
Hi All
Is there a way I can put this script in a function so I can call it in another function to create mailboxes?
This is what I came up with so far
this is the function with the script that was made by Krishna
function selectsmallestEXECMaildatabase
{
$MailboxSvr = Get-MailboxServer -identity sg2vexmb01
$i = 0
foreach($svr in $mailboxsvr)
{
$db = Get-MailboxDatabase -Server $svr.Name
foreach($database in $db)
{
switch ($database.identity)
{
$recoverydatabase
{
write-host “do not create mailbox in “+$recoverydatabase
}
$maildatabase1
{
write-host “do not create mailbox in “+$maildatabase1
}
$maildatabase2
{
write-host “do not create mailbox in “+$maildatabase1
}
$maildatabase9
{
write-host “do not create mailbox in “+$maildatabase1
}
$maildatabase10
{
write-host “do not create mailbox in “+$maildatabase1
}
default
{
$Server = $database.Server.Name
$Db = $database.Identity
$edbfilepath = $database.EdbFilePath
$path = “`\`\” + $Server + “`\” + $edbfilepath.DriveName.Remove(1) + “$”+ $edbfilepath.PathName.Remove(0,2)
$Dbsize = get-item $path |select-object length
$K = $Server + ” ” + $Db + ” ” + $Dbsize.Length
if ($i -eq 0 )
{
$edbsize = $Dbsize.Length
}
If ($edbsize -gt $Dbsize.Length)
{
$edbsize = $Dbsize.Length
$sdb = $database.Identity
write-host “$sdb”
}
$i = 1
}
}
}
}
}
This is the function to create mailbox script I am trying to call the above function in
However it keeps telling me that $sdb cannot be found as a mail database
New-Mailbox : Cannot bind argument to parameter ‘Database’ because it is null.
At D:\vicki\scripts\UserAccountScripting\CreateNewUserPPLSOFT.ps1:600 char:18
+-Database <<<< $sdb `
function createexecIMUsermailbox
{
write-host "createexecIMUsermailbox function"
selectsmallestEXECMaildatabase
write-host "$sdb"
New-Mailbox-FirstName $titlecasefirstname`
-Lastname $titlecaselastname`
-Name $displayname `
-Alias $samaccountname `
-OrganizationalUnit $imusersou `
-UserPrincipalName $upn -SamAccountName $samaccountname `
-Password (ConvertTo-SecureString $password -AsPlainText -Force) -ResetPasswordOnNextLogon $true `
-Database $sdb `
#wait for mailbox to populate variables for 15 secs before setting primary email address to firstname.lastname@income.com.sg
start-sleep -s 15
Set-Mailbox -identity $samaccountname -alias $samaccountname -PrimarySmtpAddress $email -EmailAddressPolicyEnabled $false
}