Getty Images

How to use PowerShell splatting in your administrative scripts

Give this PowerShell splatting tutorial a closer look to see how to simplify complex commands to make your code more versatile, which can be a boon in team environments.

Splatting in PowerShell is a colorful term, but it's a handy technique for admins who want to write cleaner and more efficient code.

In PowerShell, parameters can turn a simple cmdlet into a long unreadable line. In modern scripting languages, you often have a line continuation character -- the backtick or backquote ` -- that splits one long line into multiple lines. However, PowerShell offers another choice specifically for cmdlet parameters: splatting. A splat defines parameters in a hash table and then passes the hash table to a cmdlet, saving line space and making parameters reusable.

How to use splatting in PowerShell

A hash table in PowerShell is a collection of key-value pairs. The keys are strings, and the values can be any object or variable type. In the case of a splat, the key is the parameter name, and the value is the desired value to pass to that parameter.

Start with a simple PowerShell splatting example you can run on your local device:

Get-ChildItem -Path C:\Users\user\Downloads -Filter *.pdf -Recurse -Depth 5 -File

This command searches the Downloads folder for PDF files. It's not particularly wide, so you don't need to shorten it. We could take each parameter and add it to a hash table. Using the same values, our hash table would look like the following:

$splat = @{
    Path    = 'C:\Users\user\Downloads'
    Filter  = '*.pdf'
    Recurse = $true
    Depth   = 5
    File    = $true
}

We declare the switch parameters -- -Recurse and -File -- using $true in a splat.

Then, to pass those parameters to the Get-ChildItem cmdlet, you use the @ symbol in front of the variable name:

Get-ChildItem @splat

It is common to have the splat and the command next to each other in a script:

$splat = @{
    Path    = 'C:\Users\user\Downloads'
    Filter  = '*.pdf'
    Recurse = $true
    Depth   = 5
    File    = $true
}

Get-ChildItem @splat

How to convert to splats using VS Code

When you work with splats in PowerShell, there is no parameter name autocompletion that you get when typing a command. When you start a command, you might not know the length of your command and might not expect the need to splat. For those reasons, you might find yourself converting an already typed-out command into a splat, as I often do. This is tedious, but there is an easier way.

You can use Visual Studio Code (VS Code) to convert commands to splat with a quick command and a couple of prerequisites.

First, install the EditorServicesCommandSuite module, specifically version 1.0.0-beta4:

Install-Module EditorServicesCommandSuite -Scope CurrentUser -AllowPrerelease -RequiredVersion 1.0.0-beta4

Run the import command inside the PowerShell integrated console while in VS Code:

Import-CommandSuite

And, if you want this to import every time you open VS Code, add it to your VS Code PowerShell profile. You can open the VS Code-specific profile by typing the following into the PowerShell integrated console of VS Code:

code $PROFILE

And then simply paste the Import-CommandSuite command into that file and save it.

Next, place your cursor in a command to convert to a splat, open the command palette (F1 or Ctrl-Shift-P), and select PowerShell: Show Additional Commands from PowerShell Modules, which is available via the Shift-Alt-S hotkey.

Type splat, and select Splat Command. If your cursor is on a command with parameters, VS Code makes the splat. Below is an example of our converted splat:

$getChildItemSplat = @{
    Path    = 'C:\Users\user\Downloads'
    Filter  = '*.pdf'
    Recurse = $true
    Depth   = 5
    File    = $true
}

Get-ChildItem @getChildItemSplat

This process greatly reduces the difficulty of splat conversion. You can still use parameter autocompletion, while not worrying about command length until your command is fully typed out.

How can I reuse PowerShell splats?

It may not be immediately obvious, but since hash tables are just normal variables, you can reuse or modify them as needed.

This simplifies your code when running a cmdlet multiple times, but each time may differ by using a single or a few parameters. You can build your splat and then call the cmdlet with the differing parameter and include the splat.

For instance, if you need to get several users based on filters from Microsoft's Graph API and you need to get some specific properties, you can build your splat to include those properties and then include the splat when you call the cmdlet.

$splat = @{
    Property = 'Id','DisplayName','Mail','UserPrincipalName','GivenName','Surname','AccountEnabled'
    All = $true
}
$users = foreach ($name in $firstNames) {
    Get-MgUser -Filter "GivenName EQ '$name'" @splat
}

In this case, $splat stores the values for the Property and All parameters on Get-MgUser. Each iteration of the foreach loop calls Get-MgUser. You can pass a unique filter and include the parameters from the splat using the @ symbol with the splat.

Splatting makes for flexible scripts. We can build a splat based on conditions and then have one place where the cmdlet is used. This helps with debugging or verbose output to easily find the parameter values.

For example, you can write a simple function to reset a user's password in Active Directory. Normally, this is a fairly long command, but by writing a dedicated function, you can save a little bit of time.

In this case, we accept the username and the password as mandatory parameters and optionally accept a server. In the function, if the server parameter is passed, we add an additional parameter to our splat before passing it to Set-ADAccountPassword:

Reset-AdUserPassword {
    param (
        [Parameter(Mandatory)]
        [string]$User,
        [Parameter(Mandatory)]
        [string]$Password,
        [string]$Server
    )
    $splat = @{
        Identity = $User
        NewPassword = (ConvertTo-SecureString $Password -AsPlainText -Force)
        Reset = $true
    }
    if ($PSBoundParameters.Keys -contains 'Server') {
        $splat['Server'] = $Server
    }
    Set-ADAccountPassword @splat
}

Since the splat is simply a hash table, we use the hash table notation to add the Server parameter and assign it the value of $Server.

Why splats are helpful for admins

Splats are useful to simplify and shorten commands, which makes scripts easier to understand. This is a benefit not only for other team members, but for future you who needs to understand the code.

Anthony Howell is an IT expert who is well versed in multiple infrastructure and automation technologies, including PowerShell, DevOps, cloud computing, and the Windows and Linux OSes.

Dig Deeper on IT operations and infrastructure management

Cloud Computing
Enterprise Desktop
Virtual Desktop
Close