PowerShell Data Types & Type Accelerators: A Tutorial

Published:26 August 2020 - 6 min. read

Today’s sponsor is n8n, the AI-native workflow automation tool built for ITOps and DevSecOps. With 100+ templates to get you started quickly and a powerful visual editor, you can automate complex workflows without giving up control. Check it out here.

 

 

 

 

 

Like many other languages, PowerShell uses objects for just about everything. PowerShell has data types to “categorize” types of objects with different schemas of properties and methods.

Once you wrap your head around PowerShell data types, you’ll soon see the time-saving ability of a concept called PowerShell type accelerators. Accelerators are methods to speed up assigning data types in PowerShell.

In this article, you’re going to learn about various object data types and also how to use accelerators to make it easier to work with them.

Type Accelerator Examples

Even if you have not heard of accelerators before, you most likely have used them while coding. Using PowerShell to get types you will find, [Array], [Bool], or [String] are all type accelerators. What these class accelerators offer is quick access to the longer .NET definitions.

  • [Array][System.Array]
  • [CmdletBinding][System.Management.Automation.CmdletBindingAttribute]

How do we find out what our options are for using accelerators within PowerShell? Read on to learn all about type accelerators!

Discover PowerShell Data Types by Getting Type Accelerators

PowerShell offers a one-line command that will return every type of accelerator known to PowerShell. For example, the available type accelerators from a PowerShell 7 environment are below.

[PSObject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Get
Key                          Value
---                          -----
Alias                        System.Management.Automation.AliasAttribute
AllowEmptyCollection         System.Management.Automation.AllowEmptyCollectionAttribute
AllowEmptyString             System.Management.Automation.AllowEmptyStringAttribute
AllowNull                    System.Management.Automation.AllowNullAttribute
ArgumentCompleter            System.Management.Automation.ArgumentCompleterAttribute
ArgumentCompletions          System.Management.Automation.ArgumentCompletionsAttribute
<SNIP>

Understanding how to use each accelerator is a different task altogether. To do so, you need to understand the constructors of a given accelerator. Using the GetConstructors method, we can discover the necessary parameters for a constructor.

First, we retrieve the URI accelerator to learn that there are six different types. The output may not always be clear about which value to use—if so, reading the Microsoft reference documents often clarifies how to use the class.

( [Type]"URI" ).GetConstructors() | ForEach-Object {
	( $_.GetParameters() | ForEach-Object { $_.ToString() } ) -Join ", "
}
Enumerating constructor parameters
Enumerating constructor parameters

PowerShell Data Types Accelerators

Armed with the ability to find PowerShell data types accelerators and what constructors they may use, let’s dive into using the most common ones!

URI

URL’s (Uniform Resource Locators) and URI’s (Uniform Resource Identifiers) can be difficult to manipulate. Many times, the only recourse is to use string manipulation to extract the values that you need. .NET offers the URI type accelerator for these occasions.

The below example demonstrates passing a simple URL to the URI accelerator. The output is the component segments of the URI and makes manipulation much quicker.

[URI]"https://google.com/"
The schema for the URI type
The schema for the URI type

Once you have a URI object, there are simple methods available for further use as seen by the Get-Member output below.

$URI = [URI]"https://google.com/"
$URI | Get-Member -Type Method
Methods on URI type
Methods on URI type

WMI, WMISearcher, WMIClass

Familiar to many long-time PowerShell administrators is WMI or Windows Management Instrumentation. Many Windows settings exist within the WMI framework. So what can we do with the WMI, WMISearcher, and WMIClass accelerators?

  • WMIClass – Access the static properties and methods of a class.
  • WMISearcher – Create a search for WMI objects.
  • WMI – Retrieve a single instance of a class.

Demonstrated below is code using all three methods to create the notepad.exe process, locate that process, and then retrieve further process details.

# Create notepad.exe Process
$ProcessManager = [WMICLASS]"root\cimv2:WIn32_Process"
$ProcessManager.Create("notepad.exe")

# Locate the notepad.exe process
$Search = [WmiSearcher]'SELECT * FROM Win32_Process'
$Processes = $Search.Get()
$Process = $Processes | Where-Object Name -Match "Notepad"

# Use WMI accelerator to retrieve the notepad.exe process
$WMIProcess = [WMI]("\.\root\cimv2:Win32_Process.Handle='{0}'" -F $Process.ProcessId)

XML

Working with XML documents is a challenge. XML offers a flexible but verbose format. Attempting to parse through a long and complex document is difficult in any language. PowerShell makes this much easier using PowerShell data type accelerator XML. Consume an XML document, either from a string or from a file using Get-Content.

$XML = [XML]"<note>
	<to>Joe</to>
	<from>Ashley</from>
	<heading>Reminder</heading>
	<body>Don't forget Bob's birthday this weekend!</body>
</note>"

$XML.Note.Body
XML example
XML example

You can see how it is easy to navigate through the nodes to find a specific value. For example, let’s say we don’t want the heading child node. XPath searches are easy to perform by using the SelectNodes method. Using the SelectSingleNode to target a single node, remove the node using the RemoveChild method.

$XPath = '/note'
$Nodes = $XML.SelectNodes($XPath )
$Nodes | ForEach-Object {
  $Node = $_.SelectSingleNode('heading')
  $_.RemoveChild($Node) | Out-Null
}
Removing XML nodes
Removing XML nodes

RegEx

Regular Expressions make complex searches within text content easier. Constructing these queries is a challenge in and of itself. Once you have crafted the perfect query, you can use the PowerShell RegEx accelerator to perform a fast match on text content.

Although not technically a PowerShell data type, the regex type accelerator can still cut down tremendously on performing regex matches.

Below is a simple RegEx matching method. Craft a simple regular expression and call the Match method on a text string to perform a search.

([RegEx]'\d{8}').Match('This will find the first 8 values, like 12345678').Value
Matching strings with regex
Matching strings with regex

DateTime

Common to PowerShell is needing to work with dates in scripts. There are many ways to manipulate date and time. An easy way, with many useful methods, is by using the PowerShell data type [DateTime] accelerator. Some of the more useful techniques are:

  • Parsing a Date Time String
  • Formatting a Date Time
  • Date Time Arithmetic Operations

Parsing a Date Time String

Given a known date format (i.e., is not a custom format), the DateTime accelerator will return a valid System.DateTime object, which is the the same object type when using the Get-Date function.

[DateTime]::Parse('2020-08-10')
Converting strings to datetime objects
Converting strings to datetime objects

Formatting a Date Time

Data files often need a date-time string in a unique format. For example, let’s take the same date that we previously created and call the ToString method. To this method, we will pass the custom date format, MM_dd_yyyy-hh:mm:ss. Note that this is not a typical format, but using the ToString method, we will properly output the date in this format.

([DateTime]::Parse('2020-08-10')).ToString('MM_dd_yyyy-hh:mm:ss')
Converting strings and datetime objects
Converting strings and datetime objects

Date Time Arithmetic Operations

Adding and subtracting time from an existing datetime object is crucial. Instead of using complicated workarounds, leverage the DateTime class to perform these operations.

([DateTime]::Parse('2020-08-10')).AddDays(5)
(([DateTime]::Parse('2020-08-10')).AddDays(5)).AddMonths(-2)
Date arithmetic
Date arithmetic

With 5 days added, we also need to remove two months. Despite using the AddMonths method, passing a negative value subtracts the time. Chaining operations, using parentheses, we end up at the desired result.

TimeSpan

Much like the DateTime class, the TimeSpan class makes working with time ranges easy. Unlike DateTime, extra mathematical operations such as division and multiplication, are available.

Creating a Time Span Object

There are several ways that you can construct a timespan value. In our example, we are using the Hours, Minutes, Seconds constructor. Other possible constructors are shown below.

  • Ticks
  • Hours, Minutes, Seconds
  • Days, Hours, Minutes, Seconds
  • Days, Hours, Minutes, Seconds, Milliseconds
$TimeSpan = [TimeSpan]::New(1,0,0)
$TimeSpan
Create timespans
Create timespans

Multiplication and Division on a TimeSpan

Let’s say you have defined a given time span, but you want to find out what three times that range would be. It is simple to do using the Multiply method.

$TimeSpan.Multiply(3)
Timespan ranges
Timespan ranges

What about division, though? How would we split a given time interval into fourths? We can use the Divide method to find the quarter values of time span.

$TimeSpan.Divide(4)
Timespan ranges again
Timespan ranges again

IPAddress

Navigating IP address management is a chore, as is validation. The IPAddress accelerator offers the ability to validate IPv4 and IPv6 addresses.

[IPAddress]"10.0.0.1"
The IPAddress type accelerator
The IPAddress type accelerator

As you can see, this is a valid IP address, but what if we had a value that we weren’t sure was a correct address? Passing a malformed or out of range address will result in an error informing of the incorrect value.

[IPAddress]"258.0.0.1"
Unable to convert to type
Unable to convert to type

PSCredential

Securing credentials are critical to interacting with web services, remote systems, or third-party applications. The PSCredential class encrypts a password into an object. Passing this object into functions and cmdlets makes authentication easy.

In the example below, we are creating a PSCredential object used to store our secure values. Note that the password value requires a secure string.

[PSCredential]::New("username", ("password" | ConvertTo-SecureString -AsPlainText -Force))
Creating a new PSCredential
Creating a new PSCredential

Although we see the username value outputted here, we do not see the password value. How do we retrieve that?

$Credential = [PSCredential]::New("username", ("password" | ConvertTo-SecureString -AsPlainText -Force))
$Credential | Format-List
UserName and Password property on PSCredential
UserName and Password property on PSCredential

The simplest way to retrieve the password for this object is to use the GetNetworkCredential method. Next we will return the password property.

$credential.GetNetworkCredential().Password
Finding the password on a PSCredential object
Finding the password on a PSCredential object

Conclusion

PowerShell Data Types accelerators make complex operations easy in PowerShell. There are many accelerators, but with these tips, you should be able to use Powershell to get the many types and discover new uses. There are often unique ways to use accelerators. Learning these differences will increase your productivity drastically!

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!