PowerShell splatting may sound strange, but this technique offers a convenient way to format and send arguments to cmdlets and functions. Instead of a long list of parameters or those same parameters separated by error-prone backticks, you can leverage splatting to make your code more readable and easier to use.
Not a reader? Watch this related video tutorial!In this article, you’ll learn how best to use PowerShell splatting to enhance your scripts and code!
Prerequisites
If you’d like to follow along with this article, ensure you have Windows PowerShell 5.1 for most of the common functionality but PowerShell 7.1 to be able to override splatted parameters (demo below).
What is PowerShell Splatting?
To understand PowerShell splatting, you must first understand basic parameters. Typically, when you pass parameters to a command in PowerShell, you’d use a dash, the parameter name followed by the argument as shown below.
Copy-Item -Path "TestFile.txt" -Destination "CopiedFile.txt" -WhatIf -Force
Alternatively, you could pass parameters using backticks as well.
Why might you use the traditional method or the backtick method? The traditional method is fine, but with many parameters, this often becomes unwieldy to deal with and read. Using a backtick, “`, appears to give much better readability. This technique is usually not recommended due to the ease of forgetting or misplacing a backtick.
Instead, you can use PowerShell splatting. To splat a parameter set, first create a hashtable containing key/value pairs of each parameter and parameter argument. Then, once you have the hashtable built, pass that set of parameters to the command using @<hashtable name>
.
For example, you can create a hashtable called $Params
and then pass that set of parameters defined in the hashtable to the Copy-Item
cmdlet as shown below.
$Params = @{
"Path" = "TestFile.txt"
"Destination" = "CopiedFile.txt"
"WhatIf" = $True
"Force" = $True
}
Copy-Item @Params
Combining Traditional Parameters and Splatting
When you are testing scripts, or on the command-line, you can easily combine both methods. With scripts, it is often best to ultimately create a splatted variable to assign to the function or cmdlet. As an example of what this looks like is below:
$Params = @{
"Path" = "TestFile.txt"
"Destination" = "CopiedFile.txt"
}
Copy-Item @Params -Force -WhatIf
As you can tell, this is a pretty useful technique where you don’t have to give up either method depending on your needs. Sometimes you may want to test an additional parameter or format the parameters differently for formatting by combining methods.
Overriding Splatted Parameters
In PowerShell 7.1, you can now override splatted parameters. Prior to this, you could not modify a splatted parameter via a passed parameter. As an example of overriding splatted parameters, notice how the -WhatIf
parameter is overridden below.
$Params = @{
"Path" = "TestFile.txt"
"Destination" = "CopiedFile.txt"
"WhatIf" = $True
"Force" = $True
}
Copy-Item @Params -WhatIf:$False
![Overriding a splatted parameter](https://adamtheautomator.com/wp-content/uploads/2020/11/Untitled-2020-11-17T124105.244.png)
Overriding splatted parameters allows you to negate the key/value parameter defined in the hashtable and instead, use the value of the parameter defined traditionally.
Splatting Arrays for Positional Parameters
It’s considered best practice to use named parameters which forces you to specify the name of the parameter followed by the parameter argument. However, you can also splat parameters by position also.
If, for example, you’d like to copy a file called TestFile.txt to a file called CopiedFile.txt, you can do this using positional parameters like below.
Copy-Item 'TestFile.txt' 'CopiedFile.txt'
Instead of specifying positional parameters the old-fashioned way, you can also create an array (vs a hashtable as shown above) with only the parameter values. Below you’ll see an example of this.
$ParamArray = @(
"TestFile.txt"
"CopiedFile.txt"
)
Copy-Item @ParamArray
![Positional splatted parameters using an array.](https://adamtheautomator.com/wp-content/uploads/2020/11/Untitled-2020-11-17T124746.699.png)
Though this technique isn’t used quite often, this can be useful, as it is a less verbose method of providing splatted parameters. Remember that you will need to make sure you know the arguments’ positions in a given function or cmdlet; otherwise, you run the risk of passing values to incorrectly targeted parameters.
Proxy Functions and Splatted Commands
Sometimes, a PowerShell cmdlet doesn’t do quite what you need. In this case, you may choose to create a “wrapper” function or maybe even a proxy function. These functions allow you to add additional parameters to the original cmdlet and then call that cmdlet with the new parameters.
Understanding $Args
and $PSBoundParameters
When you run a function in PowerShell, PowerShell creates an automatic array variable called $Args
. This array contains all unnamed parameter values passed to that function.
You’ll find another automatic variable called $PSBoundParameters
which contains a hashtable of all bound parameters. Notice below the Test-Function
function that returns the $Param1
and $Param2
parameters.
Function Test-Function {
Param(
$Param1,
$Param2
)
Write-Host "Unnamed Parameters" -ForegroundColor 'Green'
$Args
Write-Host "Bound Parameters" -ForegroundColor 'Green'
$PSBoundParameters
}
Test-Function "test1" "test2" "test3" -Param1 "testParam" -Param2 "testParam2"
![Demonstrating the automatic variables $Args and $PSBoundParameters.](https://adamtheautomator.com/wp-content/uploads/2020/11/Untitled-2020-11-17T124826.542.png)
$Args
and $PSBoundParameters
.How are these automatic variables relevant to splatting? When you are building a proxy command, automatically passing in both bound and unbound parameters is very useful.
Building a Wrapper Function using Splatted Parameters
To show how useful splatting can be in wrapper functions, create a custom function that passes unnamed parameters and named parameters to the Copy-Item
cmdlet. With this technique, you can quickly create custom functions that add additional functionality but retain the same parameter set you would expect.
Function Copy-CustomItem {
Get-ChildItem
Copy-Item @Args @PSBoundParameters
Get-ChildItem
}
![Wrapper Function using Splatted Parameters](https://adamtheautomator.com/wp-content/uploads/2020/11/Untitled-2020-11-17T124857.374.png)
It’s important to remember that if you use the CmdletBinding
declaration or define parameter attributes, the automatic variable $Args
no longer becomes available.
Conclusion
Splatting parameters to functions and cmdlets is an extremely useful technique for code readability and functionality. As it’s easy to manipulate hashtables and arrays, you can quickly expand upon splatted values to conditionally modify values depending on options that were passed. Incorporate this powerful technique into your scripts today!