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 ", "
}
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/"
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
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
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
}
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
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')
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')
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)
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
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)
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)
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"
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"
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))
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
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
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!