Gary's $this and that about PowerShell

I am a Microsoft Senior Premier Field Engineer based out of Atlanta, GA. My focus is Powershell. This blog is mainly to share interesting Powershell script samples.

The Get-MailboxStatistics Cmdlet, the TotalitemSize Property, and that pesky little “b”

The Get-MailboxStatistics Cmdlet, the TotalitemSize Property, and that pesky little “b”

  • Comments 8
  • Likes

In my experiences with Exchange and Powershell, I have definitely come across some interesting things.  One of strangest…or so I thought…was the fact that whenever I looked at mailbox size it had a funny little “b” at the end and seemed to be in bytes.  That little “b” though made converting that number to say MB or GB a little tricky.  To see a mailbox size in Exchange 2007 or 2010, you mainly might want to use the “totalitemsize” property that is output for mailboxes when you run the “get-mailboxstatistics” cmdlet in Exchange Management Shell (EMS is just fancy branding for what I call POPS, plain old PowerShell, with the Exchange snap-in loaded, or remoted through RBAC in Exchange 2010).

The Totalitemsize property isnt shown by the default formatting of the objects output by get-mailboxstatistics, but if you format the output into a list or table and ask for that property you can see it.  check out these screen shots:

No Formatting…
  image

With formatting…
 image

In the above screen shot you can see the totalitemsize property clearly shows a value, but there is that little “b”.  Now in some regards, I like that “b” because it keeps away any confusion about what type of size unit that number is…clearly this is bytes.

So, what if we want to display this in MB or GB?

If we look at this from a traditional way, we might quickly think, lets just chop off that “b” and divide the number by the unit we need…something maybe like this: “(totalitemsize-without the b) / (1024 X1024)”.  That would give us a version of the size in MB.  This can be done, but you need to change this value to a string first in order to parse it out like a string.  Its not that difficult to figure it out, but I am not going to show it here, because the point of this post is to educate on how to use these objects and value properly.

If you take just the totalitemsize property as shown below and pipe it to Get-Member (gm) you can see that the value is not simple string or number.  Since there was a “b” showing, suspecting a normal number format might not have been a good guess.  I might have though string, but either way, showing that “b” was just plain weird.

image

So…lets look at the value property shown above.  Notice, that the value doesn't just contain a simple integer or other number object.  It contains another weird looking Exchange .Net object.  Hmmmm…lets take a look at that one through the good ole Get-Member microscope:

image

Now we are getting somewhere.  Take a look at those methods above.  So, now I am starting to realize that there is a method to this little “b” madness.  It turns out that the number shown in bytes with that pesky “b” was simply the default .ToString() method representation of the totalitemsize property.  It looks like we have methods to yield the value in whatever format we want.

image

With these simple methods we can get the totalitemsize in whatever format we want it to be in.  Its literally built into the object.  Now how do we use this from a practical standpoint.  There are lots of approaches here, but I am thinking way ahead.  Perhaps we want to look at lots of mailboxes at one time.  Maybe we want to export that data to a CSV, or html.  Maybe we want to pipe it to something else.  Who knows.  In order to keep things flexible, I like to maintain the integrity of the original objects that came out of the get-Mailboxstatistics in the first place.  This brings me to my favorite choice, Add-Member.

Add-Member lets us modify objects, and in this case, we are simply going to add on a new property on to the output objects from the Get-MailboxStatistics.  We are going to add on the totalitemsize in MB.  Here is a pipeline style way to do this:

image

 

Get-Mailbox | Get-MailboxStatistics | Add-Member -MemberType ScriptProperty -Name TotalItemSizeinMB -Value {$this.totalitemsize.value.ToMB()} -PassThru | Format-Table DisplayName,TotalItem*

In this oneliner above and in the screen shot, you can see that this command will work against all mailboxes.  If you simply leave off the formatting the objects are the original Microsoft.Exchange.Data.Mapi.MailboxStatistics object, but you can see below the scriptproperty we added on.

image

I hope this is helpful in understanding the deal behind that pesky “b” that shows in totalitemsize.

 

-Gary Siepser

This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm.

Comments
  • Your last script doesn't work with Exchange 2010. The script produces statistics in Mb, Kb and Gb - presumably depending on the size of the mailbox. Don't you even test this before publishing to the world wide web?

  • Why would it work? 'Get-MaliboxStatistics' ha ha

  • Things changed in Exchange 2010 unfortunately for this post.  This stuff really does only apply properly to Exchange 2007.  Exchange 2010 brought about the use of PowerShell remoting to use EMS.  This added neat capabilities like RBAC, but came with some complications, like making the pure PowerShell aspect of Exchange a bit more complicated.  Since everything happens through a PS remoting sessoin, the objects like this that come back from cmdlets are being created on another PowerShell session, serialized, sent to your local session, deserialized and output.  Unfortunately object serialization and deserialization is a bit like sending a fax, while the resurrected object is usable like the originial, it is by no means the actual same thing.  One of these days I will take a look back through this post and see about adding parts to talk about both version.  These days though I am not focusing as much on Exchange in favor of pure PowerShell so we'll see.  I can continue to answer specific questions and comments though.

  • Hello,

    i check this comdlet for Exchange 2007, but doesn't work :

    [PS] C:\>Get-MailboxStatistics Administrator

    Get-MailboxStatistics : The Windows Cluster service encountered an error during

    function OpenCluster:.

    At line:1 char:22

    + Get-MailboxStatistics <<<<  Administrator

       + CategoryInfo          : NotSpecified: (0:Int32) [Get-MailboxStatistics],

       ExClusTransientException

       + FullyQualifiedErrorId : BCF15CC5,Microsoft.Exchange.Management.MapiTasks

      .GetMailboxStatistics

    N.B : i have the Full admin right.

    Could you give me an idea please ?!

    Thanks in advance.

    Youssef

  • Like, +1, etc.

    Thanks for this, very helpful!

  • Need to update this line:

    Get-Mailbox | Get-MaliboxStatistics | Add-Member -MemberType ScriptProperty -Name TotalItemSizeinMB -Value {$this.totalitemsize.value.ToMB()} -PassThru | Format-Table DisplayName,TotalItem*

    To be:

    Get-Mailbox | Get-MailboxStatistics | Add-Member -MemberType ScriptProperty -Name TotalItemSizeinMB -Value {$this.totalitemsize.value.ToMB()} -PassThru | Format-Table DisplayName,TotalItem*

    LI <--> IL in the get-mailboxstatistics command

  • is it any wonder I hate powershell. All that work for something you used to be able to get instantly at a moments glance in the GUI. I just don't see PS as a step forward

  • Problem is, Get-MailboxStatistics output just a display name - not unique and cant really be used as such. The other half of the information you need is in Get-Mailbox :- found answer in following link. once you have the data on all your mailboxes, and the output can be IMPORTED into excel you can do all your sorting etc and delete whatever you dont want

    ***if this is what you were looking for, please click this link and give the guy some credit.. i didnt come up with this, i just found it


    #REM http://www.experts-exchange.com/Software/Server_Software/Email_Servers/Exchange/Q_27828458.html

    $Mailboxes = Get-Mailbox -ResultSize Unlimited
    foreach ($Mailbox in $Mailboxes)
    {
    $Mailbox | Add-Member -MemberType "NoteProperty" -Name "MailboxSizeMB" -Value ((Get-MailboxStatistics $Mailbox).TotalItemSize.Value.ToMb())
    }
    $Mailboxes | Sort-Object MailboxSizeMB -Desc | Select PrimarySMTPAddress, MailboxSizeMB


    #REM - to export this out -- do the following ;) enjoy (see the part where it says "Select" you can add additional fields like ALIAS etc to this)

    $Mailboxes = Get-Mailbox -ResultSize Unlimited
    foreach ($Mailbox in $Mailboxes)
    {
    $Mailbox | Add-Member -MemberType "NoteProperty" -Name "MailboxSizeMB" -Value ((Get-MailboxStatistics $Mailbox).TotalItemSize.Value.ToMb())
    }
    $Mailboxes | Sort-Object MailboxSizeMB -Desc | Select PrimarySMTPAddress, MailboxSizeMB | Export-Csv -NoType "C:\temp\Mailboxessize.csv"

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment