I’ve spent a lot of time working on Exchange migration projects lately, which means that I’ve moved a lot of mailboxes. When I’m planning batches of mailboxes to migrate one of the pieces of information I look at is the current size and mailbox count for the mailbox databases on the server I’m migrating to.

For Exchange Server 2007 environments I use this script to quickly report that information to me.

[PS] C:\Scripts>.\get-mbinfo.ps1 -server EX2007MB

Database                                    Size (Mb)                 Mailboxes
--------                                    ---------                 ---------
EX2007MB_DB1                              98774.89                        86
EX2007MB_DB2                              92505.02                        53
EX2007MB_DB3                                102523                        63
EX2007MB_DB4                                107795                        61
EX2007MB_DB5                              98085.02                        72
EX2007MB_DB6                              101591.3                        69
EX2007MB_DB7                              112167.1                        90
EX2007MB_DB8                                102109                        57
EX2007MB_DB9                                104767                        35

This script is only written to work for Exchange Server 2007 Mailbox servers at the moment, and needs only one parameter provided (the -server).

Here is the full script code.

#
#.SYNOPSIS 
#Returns the list of mailbox databases on a server
#along with the mailbox count and .edb file size
#for each database.
#
#.EXAMPLE
#.\get-mbinfo.ps1 -server EX2007MB
#

#You must specify a server name
param($server)

#If server name not provided try using the local host
if ($server -eq $nul) {$server = $env:COMPUTERNAME}

#Exit if server is not an Exchange mailbox server
$rolecheck = Get-ExchangeServer $server -erroraction silentlycontinue
if ($rolecheck.IsMailboxServer -ne $true)
{
	Write-Host "Server" $server "is not a mailbox server" -foregroundcolor red -backgroundcolor white
	Write-Host "Use -Server to specify a valid mailbox" -foregroundcolor red -backgroundcolor white
	Write-Host "server to run script against." -foregroundcolor red -backgroundcolor white
	Exit
}

#Check if its a cluster so that node name can be used for EDB file size check
$cluster = get-ClusteredMailboxServerStatus -identity $server -erroraction silentlycontinue 
if ($cluster -eq $nul)
{
	$servername = $server
}
else
{
	$CluObj = New-Object -com "MSCluster.Cluster"	
	$CluObj.Open($Server)
	$ActiveNode = $CluObj.ResourceGroups.Item($Server).OwnerNode.Name

	$servername = $ActiveNode
}

#Get the list of mailbox databases from the server (excluding recovery databases)
$dbs = Get-MailboxDatabase -server $server | Where {$_.Recovery -ne $true}

#Quick reorder
$dbs = $dbs | sort-object name

foreach ($db in $dbs)
{ 
	#Get the mailbox count for the database
	$mailboxes = Get-Mailbox -database $db -IgnoreDefaultScope -Resultsize Unlimited -erroraction silentlycontinue
	$mbcount = $mailboxes.count
	
	#Get the EDB file size for the database
	$edbfilepath = $db.edbfilepath 
	$path = "`\`\" + $servername + "`\" + $db.EdbFilePath.DriveName.Remove(1).ToString() + "$\"+ $db.EdbFilePath.PathName.Remove(0,2) 
	$dbsize = Get-ChildItem $path 
	[float]$size = $dbsize.Length /1024/1024 
	$dbname = $db.name

	$returnedObj = new-object PSObject
	$returnedObj | add-member NoteProperty -name "Database" -value $dbname
	$returnedObj | add-member NoteProperty -name "Size (Mb)" -value $size
	$returnedObj | Add-Member NoteProperty -Name "Mailboxes" -Value $mbcount
	$returnedObj
}

Note: I referenced some code samples on the web when I was putting this together but forgot to track where they were from. If you spot a snippet that originated from you please let me know so I can add credit.

About the Author

Paul Cunningham

Paul is a former Microsoft MVP for Office Apps and Services. He works as a consultant, writer, and trainer specializing in Office 365 and Exchange Server. Paul no longer writes for Practical365.com.

Comments

  1. CoffeeBlack

    FYI – When copying your code, your path name appears as though it is incorrect now for some reason. What used to be slashes are now single quotes or something.

    $path = ““” + $servername + “`” + $db

    1. Paul Cunningham

      A bunch of my code samples got messed up in a DB migration between WordPress sites. I’ll try and fix it. In the meantime if you copy/paste into the PowerShell ISE or VS Code it should highlight any syntax problems.

  2. Luis Reyes

    Script Works into an environment Exchange 2013?

    Greetings from Mexico

    🙂

  3. Garry

    This script is working better for me and appears to be more accurate:

    Get-MailboxDatabase | Select Server, StorageGroupName, Name, @{Name=”Size (GB)”;Expression={$objitem = (Get-MailboxDatabase $_.Identity); $path = ““” + $objitem.server + “`” + $objItem.EdbFilePath.DriveName.Remove(1).ToString() + “$”+ $objItem.EdbFilePath.PathName.Remove(0,2); $size = ((Get-ChildItem $path).length)/1048576KB; [math]::round($size, 2)}}, @{Name=”Size (MB)”;Expression={$objitem = (Get-MailboxDatabase $_.Identity); $path = ““” + $objitem.server + “`” + $objItem.EdbFilePath.DriveName.Remove(1).ToString() + “$”+ $objItem.EdbFilePath.PathName.Remove(0,2); $size = ((Get-ChildItem $path).length)/1024KB; [math]::round($size, 2)}}, @{Name=”No. Of Mbx”;expression={(Get-Mailbox -Database $_.Identity | Measure-Object).Count}} | Format-table -AutoSize

  4. Garry

    The script reported that there are 441 on my database “m7sg10priv1”.
    I went into the Exchange Management Console for Recipient Mailboxes and did a filter where “Database” equals “m7sg10priv1”, and only 1 mailbox showed up.

    So I don’t know if the mailbox # count is correct.

  5. AGOTAY

    In my case I like returned dbsize to be in GB so I made this change at the end and works fine.

    $returnedObj | add-member NoteProperty -name “Size (GB)” -Value (“{0:n2}” -f ($dbsize.Length/1024MB))

  6. Joss

    This script doesn’t work with a 2003’s OS server. I get :
    Get-ChildItem : Cannot find path ‘\MyCCRNameMySGMyDB.edb’ because it does not exist.

    It’s strange because this works well on a 2008 server’s OS.

    Any clue?

    Best regards

  7. Michael

    I overlooked the Unix-like “.” leading the command. I was treating it more like a DOS batch file.
    Thank you for this script, it did work.

  8. Michael

    I copied and pasted into Notepad and gave it the name you mention. In the Windows PowerShell on my Win2008 Standard server, I see a “Suggestion” that “the command was not found, but does exist in the current location”. This is followed by the error “The term ‘get-mbinfo.ps1’ is not recognized as the name of a cmdlet…..”

    I used your parameter to input the name of my Exchange server.
    Thank you.

  9. Rajbabu

    Thanks…

    The below script is also give the same… 🙂

    Get-MailboxDatabase | foreach-object {add-member -inputobject $_ -membertype noteproperty -name mailboxdbsizeinGB -value ([math]::Round(([int64](get-wmiobject cim_datafile -computername $_.server -filter (‘name=”’ + $_.edbfilepath.pathname.replace(“”,”\”) + ””)).filesize / 1GB),2)) -passthru} | Sort-Object mailboxdbsizeinGB -Descending | format-table identity,mailboxdbsizeinGB

    1. Rajbabu

      But not the mailbox count 🙂

  10. Murambi

    Thanks a whole load. This is just what i needed. Your articles rock Paul!

  11. allenr74

    Thanks for this script. I used it to get the mailbox count on a remote server. It worked for 2 times. Now, when I identify the server with as before (-server servername), I get an error that the object cannot be located. The server is obviously still in AD. I will try to run it locally but was wondering if you have ever seen this issue?

  12. Mide

    Thanks a bunch! Exactly what I was looking for.

Leave a Reply