PowerShell Splatting – build parameters dynamically

Have you ever needed to run a command with parameters that depend on the runtime environment?  I often see logic like this:

If($Cred) { Get-WmiObject Win32_OperatingSystem -Credential $Cred }            
Else      { Get-WmiObject Win32_OperatingSystem }

It doesn’t look too terrible if you only have one option, but things get ugly fast.  What if you want the same logic for $Credential, $ComputerName, and $Filter?  You end up with 6 potential combinations and an unreadable mess of code, and this is with only three parameters.

The answer is splatting!

What is splatting?

Splatting is just a way to pass parameters to commands, typically with a hash table.  It was introduced with PowerShell v2, so it is compatible pretty much anywhere.  Here’s a simple example

#Define the hash table            
$GWMIParams = @{            
    Class = "Win32_OperatingSystem"            
    Credential = $Cred            
    ComputerName = 'localhost'            
}            
            
#Splat the hash table.  Notice we put an @ in front of it:            
Get-WmiObject @GWMIParams

Many blog posts focus on the readability splatting offers.  Readability is very important, but splatting gives us the framework needed to build up parameters for a command dynamically.

Building up command parameters

Let’s build a simple example.  The basic steps we take include creating a hash table, adding key-value pairs to that hash table, and splatting the hash table against a command.

#Create the initial hash table            
#You can use @{} to create an empty hash table            
$GWMIParams = @{            
    ErrorAction = "Stop"            
}            
            
#Add parameters depending on the environment            
#We use simple logic here, but you can get creative            
if($Cred)            
{            
    #We can add a key value pair with the Add method            
    $GWMIParams.add("Credential", $Cred)            
}            
if($Computer)            
{            
    #This alternative to the Add method is easier to read            
    $GWMIParams.ComputerName = $Computer            
}            
if($Filter)            
{            
    $GWMIParams.Filter = $Filter            
}            
            
#Splat the hash table.  You can splat multiple hash tables and still use parameters            
Get-WmiObject @GWMIParams -Class Win32_OperatingSystem

When we run this, Get-WMIObject will have different parameters depending on whether we have $Computer, $Filter, or $Cred defined in our session.  We get a side benefit to this:  a hash table with parameters and their values, which you can use for providing verbose or debug output.

If we ran the example code without Computer, Filter, or Credential variables defined, the parameters will look like this:

image

If we set $Computer to ‘localhost’ and run the same code, we now get different parameters:

image

Next steps

That’s about it!  For further reading, check out Get-Help about_Splatting (the about topic was added in PowerShell 3), or search around for numerous blog posts on the topic.

The real fun is figuring out what logic you should use to work with the hash table you are splatting.  If you follow best practices when writing PowerShell functions, you open up access to the PSBoundParameters, conveniently in the form of a hash table!

Advertisements

One thought on “PowerShell Splatting – build parameters dynamically

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s