PowerShell data/reference types for variables

When you store data in a variable, PowerShell can store it how you want it to be if you use the correct data type. This blog post will show you how that works and which data types I mostly use for my scripts.

What are data or reference types?

There are two ways in which you can find the types being referenced: data or reference. The Microsoft Learn documents refer to it like this:

“In PowerShell, each value has a type, and types fall into one of two main categories: value types and reference types. Consider the type int, which is typical of value types. A value of type int is completely self-contained; all the bits needed to represent that value are stored in that value, and every bit pattern in that value represents a valid value for its type. Now, consider the array type int[], which is typical of reference types. A so-called value of an array type can hold either a reference to an object that actually contains the array elements, or the null reference whose value is $null

Source: https://learn.microsoft.com/en-us/powershell/scripting/lang-spec/chapter-04?view=powershell-7.4

Other articles refer to it as data types, for example, this article from ScriptRunner: https://support.scriptrunner.com/articles/#!coding/powershell-data-types

But what can you do with it?

In PowerShell, you can store data in a Variable. Depending on what you try to store, it might not be in the correct format for further use in your script. In the chapters below, I will show you the types that I usually use to get things done 😉

[array]

This will create an array (Collection) of items you can use individually. When filling a variable, it will change to the System.Array BaseType for many things, but not always. You can specify [array] in front of the variable, for example: (Get-ChildItem will return an array by default, just an example 🙂 )

[array]$array=Get-ChildItem 

[datetime]

By using [datetime], you will have the option to use the different methods for calculation or formatting. For example:

PS C:\Users\HarmVeenstra> $datetime=get-date
PS C:\Users\HarmVeenstra> $datetime.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DateTime                                 System.ValueType

Because it’s in this format, you can use things like:

PS C:\Users\HarmVeenstra> $datetime.DayOfWeek
Thursday
PS C:\Users\HarmVeenstra> $datetime.Hour
14
PS C:\Users\HarmVeenstra> $datetime.AddHours(-1)

donderdag 11 april 2024 13:59:08

[string]

The simplest one is just a simple line of text without any carriage return. For example:

C:\Users\HarmVeenstra> $string="This is just a simple line of text"
C:\Users\HarmVeenstra> $string
This is just a simple line of text
C:\Users\HarmVeenstra> $string.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Using “.GetType()” behind the variable will show that the BaseType is System.Object with a String type.

[version]

This is something that I use to compare versions of applications or PowerShell modules. For example:

PS C:\Users\HarmVeenstra> $version='2.3.2'
PS C:\Users\HarmVeenstra> $version.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

PS C:\Users\HarmVeenstra> $version
2.3.2

The $version is just a string now, but if you use [version]… It will format it in Major, Minor, Build, and Revision, which is better for comparing versions:

PS C:\Users\HarmVeenstra> [version]$version='2.3.2'
PS C:\Users\HarmVeenstra> $version.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Version                                  System.Object

PS C:\Users\HarmVeenstra> $version

Major  Minor  Build  Revision
-----  -----  -----  --------
2      3      2      -1

[xml]

When working with XML files, you can use [xml] to store output straight away in XML format. For example: (Example.xml is an Office XML config for installation)

PS C:\Users\HarmVeenstra> $xml=Get-Content C:\temp\example.xml
PS C:\Users\HarmVeenstra> $xml
<Configuration ID="1ea22db9-fbc6-4254-aea8-7c5fa6b96b07">
  <Add OfficeClientEdition="64" Channel="MonthlyEnterprise" SourcePath="\\test.local\data\software\microsoft\m365" AllowCdnFallback="TRUE">
    <Product ID="O365ProPlusRetail">
      <Language ID="MatchOS" />
      <Language ID="zh-cn" />
      <Language ID="hr-hr" />
.....

If you use [xml], then it knows it’s an XML file and will look like this:

PS C:\Users\HarmVeenstra> [xml]$xml=Get-Content C:\temp\example.xml
PS C:\Users\HarmVeenstra> $xml.getType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    XmlDocument                              System.Xml.XmlNode

PS C:\Users\HarmVeenstra> $xml

Configuration
-------------
Configuration

PS C:\Users\HarmVeenstra> $xml.Configuration

ID          : 1ea22db9-fbc6-4254-aea8-7c5fa6b96b07
Add         : Add
Property    : {SharedComputerLicensing, PinIconsToTaskbar, SCLCacheOverride, AUTOACTIVATE…}
Updates     : Updates
RemoveMSI   : RemoveMSI
AppSettings : AppSettings
Display     : Display
Logging     : Logging

PS C:\Users\HarmVeenstra> $xml.Configuration.RemoveMSI.IgnoreProduct

ID
--
InfoPath
InfoPathR
PrjPro
PrjStd
SharePointDesigner
VisPro
VisStd

PS C:\Users\HarmVeenstra>

Wrapping up

I use these data types/references in my script to ensure a variable is in the correct format. You can use others if you follow the links mentioned above in the first chapter.

2 thoughts on “PowerShell data/reference types for variables

  1. If you’re adding a lot of elements to an array, e.g. in a loop, it can get very slow because every item you add creates a new copy of the array that’s one element larger. There is a .net type similar to Arrays that’s much faster for that use case.

    Instead of
    $mySlowArray = @()
    use
    $myFastArray = [System.Collections.ArrayList] @()

    The difference is huge.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.