Make your PowerShell scripts easier to read with splatting.
No one likes horizontal scrolling
The format of PowerShell cmdlets make them universally easy to use. Enter the cmdlet name, then enter the various parameter switches and values for those parameters. For a lot of commands, everything can fit cleanly on one line and within either the standard 80 character width of a standard prompt or the full screen width of your favorite editor.
However, there are going to be times you want to specify a LOT of parameters, and some of those parameter values may be lengthy in nature. The last thing you want to do though is have to start scrolling sideways or trying to wrap your “one-liner” to read it.
Let’s look at a quick example. I want to run New-ADUser to create a user, and I want to populate a lot of information at creation time.
- User’s name is “Test User”
- I want to set a password.
- I want the account to be enabled after creation.
- I want to specify a specific OU in which to create the user.
- I want to include the user’s city and state.
Here is what this would look like on one line:
New-ADUser -Name "Test User" -GivenName "Test" -Surname "User" -DisplayName "Test User" -SamAccountName "TestUser" -UserPrincipalName "TestUser@lab.thinkpowershell.com" -AccountPassword (ConvertTo-SecureString "DemoPass1" -AsPlainText -Force) -Enabled $true -City "Minneapolis" -State "MN" -Path "ou=Users, ou=LAB, dc=lab, dc=thinkpowershell, dc=com"
I am guessing you had to scroll to look at it, and I am guessing that you found it annoying AND hard to get a clear picture of the user being created. That line is 355 characters wide!
Now you might say “well, you could put some of those values into shorter variables names”, but even with short variables names you will run into situations where you exceed your screen width. Luckily, there is a better way!
Splatting – embracing vertical scrolling
Splatting sounds more like slang than an official technical term (and I don’t think you will find it in “official” documentation), but per a guest article on docs.microsoft.com,
Splatting is a method of passing a collection of parameter values to a command as unit. Windows PowerShell associates each value in the collection with a command parameter.
The benefit of using splatting is readability. Instead of having to stretch your parameter assignments out horizontally, Splatting gives us a clean, concise, readable format that extends vertically in which to assign values to our parameters. For the splatting variable, we can either use an array or a hash table. Let’s take a look.
Splatting with an array
An array can be used if the cmdlet parameters are positional, meaning you don’t have to specify a parameter name. For example, let’s say you want to run Get-ChildItem for the file SecurityAndMaintenance_Error.png in C:\Windows\System32. To declare a splatting variable array, we can do it in the following format to keep it readable and vertical. Note that the variable is $Params and we use @(…) so we can stretch it vertically.
$Params = @("C:\Windows\System32", "SecurityAndMaintenance_Error.png")
Now to execute Get-ChildItem using this splatting variable, we run the following. Pay special attention to the fact we use @ instead of $ in front of the variable name Params. When we use @, we are actually referencing a named splatting variable, which will be treated differently.
PS C:\Windows\system32> Get-ChildItem @Params Directory: C:\Windows\System32 Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 7/16/2016 8:18 AM 6886 SecurityAndMaintenance_Error.png
Splatting with a hash table
Arrays are supported for splatting, but if you are writing a script you want to follow best practices by using named parameters only, not positional parameters. Hash tables allow us to specify parameter names/values in a key/value format, which is why you should make it a habit to use hash tables by default for splatting.
Let’s take a look at our original example for creating a new AD user. We can take our list of parameters and values and assign it to a hash table variable (note hash tables are bracketed with @{…}, whereas arrays were @(…):
$Params = @{ AccountPassword = (ConvertTo-SecureString "TestPassword1" -AsPlainText -Force); City = "Minneapolis"; DisplayName = "Test User"; Enabled = $true; GivenName = "Test"; Name = "Test User"; Path = "ou=Users, ou=LAB, dc=lab, dc=thinkpowershell, dc=com"; SamAccountName = "TestUser"; State = "MN"; Surname = "User"; UserPrincipalName = "TestUser@lab.thinkpowershell.com"; }
The width of this script block maxes out at 84 characters, compared to 355 when we spelled it all out on one line. That is 24% of the original width!
To execute New-ADUser and use this variable for splatted parameters, we do it in the same way we did for an array, using @Params:
New-ADUser @Params
And that, more (readability) or less (horizontal scrolling), is splatting!
Next Steps
- Read the about_Splatting article on docs.microsoft.com (in Reference below).
- Review your current scripts and implement splatting with hash tables where it will make your script easier to read.
Reference
- about_Splatting | docs.microsoft.com
Igor says
Nice explanation and useful. For complete info, it would be good to explain also use of back tick (` ) as it can be also used to splat vertically long commands.
Aaron Rothstein says
Thanks for the feedback. I have used the back tick as well, particularly when I am dealing with a long string, like a WMI query string or a filter.
Michael Frank says
Though back ticks work they’re not the best for readability.
I think the most useful thing about splatting is being able to build up parameters based on conditional logic in the calling script.
Aaron Rothstein says
Agreed that is a very useful benefit of splatting. I am planning a follow-up post to focus on that benefit.
Al says
Microsoft does officially refer to this as splatting
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-6
Using @params to pass parameter values still catches me out, force of habit I guess!