Data Type Formatting

PowerShell variables can store all kinds of data types. Some of these include Strings, Integers and DateTime. This give PowerShell flexibility when handling different object types, values and more. The question is, did you know that you can convert data stored in variables between these data types? For this PowerShell Tip of the week, we’ll cover some examples of this conversion as well as why you might want to do this.

Converting Data Types

First we need to walk-through a couple sample data type conversions to get a feel for what they can and then we can explore some more specific scenarios.

Converting a Number to a String and Back to a Number Again

For this example, we have a variable called $Size that has a value of 258395839 and is stored as an integer in PowerShell. What if we wanted to convert the variable to a string. First, we need to Syntax:
[sourcecode language=”powershell”]
[<data type>]$<Variable>
[/sourcecode]
For this example it would be:
[sourcecode language=”powershell”]
[String]$Size
[/sourcecode]
Now, this alone does not actually convert the variable: (see below)

So how do we take advantage of changing data types? We can either use it as part of a one liner or store the new value in a variable:

We can perform the opposite as well by converting the String to a 64 bit integer:


Convert a String to DateTime (Real World)

Let’s say we have a value called $Processed and it contains what looks like a date, but is in fact a string. This could be because a value was stored / converted to this or that the system that was queried stored the value as a string:
[sourcecode language=”powershell”]
"Thursday, April 11, 2019 12:00:00 PM +00:00"
[/sourcecode]
Well that also looks like a time value type:

Practical Scenarios

A scenario that I run into a lot is working with mailbox sizes in Exchange. In Exchange Server PowerShell, mailbox statistics are listed in bytes:
[sourcecode language=”powershell”]
Get-Mailbox | Get-MailboxStatistics | ft DisplayName,TotalItemSize -Auto
[/sourcecode]

However, the data field (TotalItemSize) is hard to work with as the output is not just a raw number. If we were to take that field and try to add a succession of mailboxes it would not work as expected and just the visual representation makes for poor reporting. How can we convert this first in Exchange PowerShell?
[sourcecode language=”powershell”]
Get-Mailbox | Get-MailboxStatistics | ft {$_.TotalItemSize.Value.ToKB()}
Get-Mailbox | Get-MailboxStatistics | ft {$_.TotalItemSize.Value.ToMB()}
Get-Mailbox | Get-MailboxStatistics | ft {$_.TotalItemSize.Value.ToGB()}
[/sourcecode]
The Value.ToXX is the converting agent. As we can see, there are many options and we can even choose ToTB if we want to. Not very useful, but it is a valid option.
Why cover this? Because in Office 365, ToMB does not work. The above is just one way to handle the data. The other time ToMB does not work is using Windows PowerShell to connect to remote Exchange Servers. So in order to compensate for these two scenarios, we can convert the information provided in TotalItemSize to a string, manipulate it, clean it up and then convert it to MB manually. This same task can be done with Mailboxes, Archive Mailboxes and Public folders alike. Here is a sample code section for getting Public Folder sizes:
[sourcecode language=”powershell”]
Get-PublicFolderStatistics $PublicFolder | Select Name,ItemCount,TotalItemSize,FolderPath |% {;
$Size = [string]$_.TotalItemSize;
$StepOne = $Size.Split('(');
$StepTwo = $StepOne[1].Split(')');
$Bytes = $StepTwo[0].Split(' ') -replace ‘[,]’,'';
$Bytes2 = [int64]$Bytes[0];
$MegaBytes = $Bytes2/1024/1024;
$MbxSize = [Math]::Round($MegaBytes,2);
$_.TotalItemSize = $MbxSize;
return $_}
[/sourcecode]
This allows us to capture TotalItemSize as its normal datatype, clean it up and then return it in MB just like ToMB would accomplish. As you can see, converting datatypes is useful and practical, however, not always possible:


So make sure you understand your datatype before converting a variable…. and always … always … Test this before putting any data type changes into production. Also watch your integer datatypes as Int32 might be too small depending on your data values, so Int64 might be more appropriate. This is especially true of mailbox size data (see above).

Related Post

A Good EndingA Good Ending

Like all good scripts, starting off well should be reciprocated with a good ending as well. What does that mean? Think processing, cleanup, ending transcripts, truncating log files and more.