次の方法で共有


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

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 https://www.microsoft.com/info/cpyright.htm.

Comments

  • Anonymous
    January 01, 2003
    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.

  • Anonymous
    October 11, 2011
    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?

  • Anonymous
    October 11, 2011
    Why would it work? 'Get-MaliboxStatistics' ha ha

  • Anonymous
    December 21, 2011
    The comment has been removed

  • Anonymous
    February 02, 2012
    Like, +1, etc. Thanks for this, very helpful!

  • Anonymous
    June 25, 2012
    The comment has been removed

  • Anonymous
    March 04, 2014
    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

  • Anonymous
    July 30, 2014
    The comment has been removed

  • Anonymous
    October 27, 2015
    Es un excelente aporte, me ayudo mucho

    Gracias

  • Anonymous
    February 02, 2016
    To get this to work in Exchange 2010 just needs a little rudimentary understanding of PowerShell.
    2010 feeds values back in the best suited size (KB, MB, GB).
    These values can still be converted using this method, you just need to use one of several avenues to get there.

    Example:

    $MBoxes = Get-Mailbox | Get-MailboxStatistics
    $MBoxes | ForEach-Object -Process { $_.DisplayName + " n " + $_.TotalItemSize.Value.ToMB() + " MB n" }

    Obviously not the cleanest output, but that's manageable with a little more work.

  • Anonymous
    March 28, 2016
    If performing from a imported PS session the methods .ToMB() is lost as the type becomes a custom object.
    The $variable.TotalItemSize.Value becomes a two element array [0] in KB,MB or GB and [1] always in bytes.

    So to use this we can play with strings to achieve what we want..

    $mailboxes = Get-Mailbox -Filter{(RecipientType -eq "UserMailbox") -and (CustomAttribute12 -eq "Whatever")}
    foreach ($mailbox in $mailboxes)
    {
    $size1 = Get-MailboxStatistics $mailbox.id
    [string]$bob = $size1.TotalItemSize.Value
    [int]$bill = $bob.TrimEnd(" bytes)").Split("(")[1] # The bytes part of the array.
    $bill = $bill/1mb # Convert into MB's
    if ($bill -le 1500) {do something} Else {"Too Big " + $bill} # note -le 1500 NOT 1500MB

    }

  • Anonymous
    April 06, 2016
    get-mailbox -resultsize unlimited | Get-MailboxStatistics | ft displayname,@{label="Total Size (MB)";expression={$_.TotalItemSize.Value.ToMB()}}