Getting Mailbox Sizes in PowerShell

One of the comments I hear often by Exchange admins who move from a legacy version of Exchange to Exchange 2007, is that they can’t find how to see a list of users and their mailbox sizes. Fear not – help is here!

In earlier versions of Exchange, we could look in the Exchange console and see mailbox sizes on a per database basis. Not bad, but better than what we have in the Exchange 2007 GUI.

Fortunately, we can use PowerShell to see the information we need. And, we have more control over how the information is displayed, as well as what information is displayed. Let’s fire up PowerShell and get started.

We can use the Get-MailboxStatistics cmdlet and supply a username like this:

​Get-MailboxStatistics [username]

This shows the DisplayName, ItemCount, StorageLimitStatus, and LastLogonTime fields for the specified user, as seen in Figure 1 below.

getting mailbox sizes in powershell

Figure 1

But that doesn’t show what we need. We can have the cmdlet display just specific fields, such as DisplayName, ItemCount, and TotalItemSize, which will show the size of the mailbox. For that, we use the FT command, short for Format-Table, along with the fields we want.

​Get-MailboxStatistics [username] | ft DisplayName, TotalItemSize, ItemCount

This shows us the size of the mailbox in bytes, as well as the number of items, and the username, as seen in Figure 2 below.

getting mailbox sizes in powershell 2 small

Figure 2

We can add another field to show if the user is above or below the storage limits by including the StorageLimitStatus as seen in Figure 3.

getting mailbox sizes in powershell 3 small

Figure 3

Showing data for all users

Now that we can see the specific fields, we can remove the [username] parameter and the command will show us the information all users, as seen in Figure 4.

getting mailbox sizes in powershell 4 small

Figure 4

Filtering results

As you can see, this will show us system mailbox sizes as well, which probably doesn’t do us any good. So let’s filter them out. We add

​| where {$_.ObjectClass –eq “Mailbox”}

right after Get-MailboxStatistics to help.

Note – that’s a pipe at the beginning. This code essentially says to only display those objects classified as mailboxes. From that, we get a cleaner list, as seen in Figure 5 below.

getting mailbox sizes in powershell 5 small

Figure 5

Sorting results

So that shows us all of the users and their sizes, but they appear in a random, unsorted order, which doesn’t do anyone any good. In PowerShell, we can sort using the Sort-Object cmdlet. Right after our filter, we add

​| Sort-Object TotalItemSize –Descending

This tells PowerShell to sort according to the TotalItemSize parameter (the size of the mailbox) of the Get-MailboxStatistics results, in descending order, as seen in Figure 6. Simple enough, right?

getting mailbox sizes in powershell 6 small

Figure 6

Customizing results

This is all fine and good, but having to figure out how big a mailbox is based on the number of bytes is more math than we should have to use. Fortunately, we can convert bytes to MB by replacing the “TotalItemSize” field with

​@{expression={$_.TotalItemSize.Value.ToMB()}

as seen in Figure 7 below.

getting mailbox sizes in powershell 7 small

Figure 7

This converts the values of TotalItemSize to megabytes. If you’ve got monster mailboxes, you could use replace ToMB with ToGB to convert to Gigabytes. Now the value is much easier to understand. But doing this causes the column header to be mangled. Not so good. Fortunately, we can customize this by amending the code.

​@{label=”Total Size (MB)”;expression={$_.TotalItemSize.Value.ToMB()}

Which gives us a much friendlier header. Based on those results, we might as well clean up the rest of the headers, so we customize the ItemCount using

​@{label=”Items”;expression={$_.ItemCount}}

StorageLimitStatus using

​@{label=”Storage Limit”;expression={$_.StorageLimitStatus}}

And finally, the DisplayName using

​@{label=”User”;expression={$_.DisplayName}}

The text between the quotes is what the column header will say. What we end up with is a much more readable report on the mailbox sizes of our users.

Bring it all together

We can bring the columns closer together by using the –auto switch, as seen in Figure 8. This gives us our desired results.

getting mailbox sizes in powershell 8 small1

Figure 8

The final one liner of code looks like this:

​Get-MailboxStatistics | where {$_.ObjectClass –eq “Mailbox”} | Sort-Object TotalItemSize –Descending | ft @{label=”User”;expression={$_.DisplayName}},@{label=”Total Size (MB)”;expression={$_.TotalItemSize.Value.ToMB()}},@{label=”Items”;expression={$_.ItemCount}},@{label=”Storage Limit”;expression={$_.StorageLimitStatus}} -auto

“But, Pat,” you say, “that’s an awful lot of code to type each time I want to see mailbox sizes”. Right you are, Grasshopper. So, we copy and paste that code into Notepad, and save it as Get-MailboxSizes.ps1 in the scripts folder. Then, we need to simply open PowerShell, type Get-MailboxSizes, and voila – the data we need. See my earlier article on customizing PowerShell for quicker access to scripts.

With PowerShell, we were able to take a simple cmdlet, filter and sort the results, give the results more human names, and convert values into amounts that make sense. We could further filter the data so that only users on a specific server, or a specific mailbox database are displayed, and even export to a .csv file. The possibilities are endless.

Hopefully, you see how flexible PowerShell really is.

Got a question? Post it on our Exchange Server Forums!

Related Article: