PowerShell to Create New Mailboxes in the smallest database in Exchange 2007 Organization

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

http://powershell.com/cs/cfs-filesystemfile.ashx/__key/CommunityServer.Components.UserFiles/00.00.00.30.62/NewMailbox_5F00_SmalletDatabase.txt

7 thoughts on “PowerShell to Create New Mailboxes in the smallest database in Exchange 2007 Organization

  1. 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!

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

    }

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

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

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

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

      }

Leave a comment