Byte Quantified Size and some Powershell tricks

The other day, someone asked me how they could convert the output of an Exchange 2007 property that was being displayed as “Bytes” into KB. They were trying to do all sort of arithmetic (dividing by 1024, etc) to come up with the value and it wasn’t displaying the way they wanted.

The good news was that this particular property was actually of a strong-type “ByteQuantifiedSize”. This is an Exchange strong-type that has knowledge of the various ways to represent byte quantified data and can easily convert between them.

Ok, more specifics for the example: Suppose you are doing Get-MailboxStatistics and you want to output a list of the mailboxes along with their current size…

Get-MailboxStatistics | ft displayname, totalitemsize

DisplayName TotalItemSize
----------- -------------
mailbox1 6672B
Microsoft System Attendant 0B
SystemMailbox{714C896E-648E-41AD-A2F... 369231B

Notice that these returned objects are displaying their “TotalItemSize” in bytes. For something like the last mailbox in my list, this means I have to mentally insert a magnitude separator as I glance at the number (is that ~369kb or ~36.9kb). For a server with real mailboxes with real data in them, you may wish to format this data as KB, MB, or even GB to make it more useful for your purposes.

So, how do to it? Well, we will need to call a method on the ByteQuantifiedSize data before it gets output to reformat it the way we want. Here’s an example of the syntax to reformat this same example from above using KB instead of Bytes, and the resulting output:

Get-MailboxStatistics | ft displayname, @{ expression={$_.TotalItemSize.Value.ToKB()} }

DisplayName $_.TotalItemSize.Value.ToKB()
----------- -----------------------------
mailbox1 6
Microsoft System Attendant 0
SystemMailbox{714C896E-648E-41AD-A2F... 360

Eew, icky. We got the output magnitude that we wanted, but the column header looks terrible. Let’s make one last change-up and see if we can fix it:

Get-MailboxStatistics | ft displayname, @{ expression={$_.TotalItemSize.Value.ToKB() } ;label=”TotalItemSize (KB)” }

DisplayName TotalItemSize (KB)
----------- ------------------
mailbox1 6
Microsoft System Attendant 0
SystemMailbox{714C896E-648E-41AD-A2F... 360

Much better! Of course, the next question is “what other conversions can I do with BQS”? The “ToKB()” method isn’t the only one, of course!

Using the power of Powershell, it’s fairly straight forward to “discover” what conversions are available. Let’s walk through it, because the way to do this is fairly generic and may help you with other types besides just the BQS strong-type.

First, let’s focus on getting the byte quantified size data somewhere that we can take action on it. This is a pretty simple way to do it:

$a = Get-MailboxStatistics

Ok, so now all three objects are stored in my $a variable. We can confirm that by doing $a[0] to look at just the first entry in the index.

DisplayName ItemCount StorageLimitStatus LastLogonTime
----------- --------- ------------------ -------------
mailbox1 2 BelowLimit 9/7/2006 3:51:52 PM

Step two, let’s isolate just the TotalItemSize data on the output object:

$a[0].TotalItemSize

IsUnlimited Value
----------- -----
False 6672B

Great, we can see that this is some complex type that has at least IsUnlimited and Value data to it! Step three, let’s see what it REALLY has to it:

$a[0].TotalItemSize | Get-Member

Name MemberType Definition
---- ---------- ----------
CompareTo Method System.Int32 CompareTo(Unlimited`1 other), System...
Equals Method System.Boolean Equals(Object other), System.Boole...
get_IsUnlimited Method System.Boolean get_IsUnlimited()
get_Value Method Microsoft.Exchange.Data.ByteQuantifiedSize get_Va...
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
set_Value Method System.Void set_Value(ByteQuantifiedSize value)
ToString Method System.String ToString()
IsUnlimited Property System.Boolean IsUnlimited {get;}
Value Property Microsoft.Exchange.Data.ByteQuantifiedSize Value ...

Whoa! This strong type has a bunch of stuff available on it! But notice it’s only the two properties… the rest are methods which won’t help us do the magnitude conversion. What we really need to do is drill deeper into the Value property and see if it has any properties within.

 $a[0].TotalItemSize.Value | Get-Member

Name MemberType Definition
---- ---------- ----------
CompareTo Method System.Int32 CompareTo(ByteQuantifiedSize other)
Equals Method System.Boolean Equals(Object obj), System.Boolean E...
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
RoundUpToUnit Method System.UInt64 RoundUpToUnit(Quantifier quantifier)
ToBytes Method System.UInt64 ToBytes()
ToGB Method System.UInt64 ToGB()
ToKB Method System.UInt64 ToKB()
ToMB Method System.UInt64 ToMB()
ToString Method System.String ToString(), System.String ToString(St...
ToTB Method System.UInt64 ToTB()

Ah ha! Paydirt! So now we can see all of the available conversion methods we can use for BQS objects.

I hope the techniques in this drilldown help you out while you’re exploring the Powershell. Enjoy!