Windows PowerShell: Splatting

Bundling parameters before sending them along to a command can save you time, but only if you’re using the latest version of Windows PowerShell.

Don Jones

Where else but in the IT industry could you use a word like “splatting” in a serious, professional context? Windshield repair, perhaps, but not many other places.

In Windows PowerShell terms, splatting is a way of bundling parameters to send to a command. This is a new feature of Windows PowerShell 2.0. If you’re still messing around with version 1 (say, because you’re using Exchange Server 2007, which requires it), then this won’t work.

The Old Way

Normally, you’d run commands by providing parameters to them right on the command line. For example:

Get-WmiObject –computername SERVER-R2 –class Win32_LogicalDisk –filter "DriveType=3" –credential "Administrator"

You can still do that in version 2.0 of the shell, of course. If you don’t like all that typing, you can truncate the parameter names. Just be sure to provide enough of each parameter name so that the shell will be able to determine which parameter you meant. This is also legal:

Get-WmiObject –comp SERVER-R2 –cla Win32_LogicalDisk –filt "DriveType=3" –cred "Administrator"

There are still positional parameters, of course. Read the help for Get-WmiObject, and you’ll see you can use the –class parameter in the first position. That means you don’t even have to provide the parameter name, as long as its value goes in the right spot:

Get-WmiObject Win32_LogicalDisk –comp SERVER-R2 –filt "DriveType=3" –cred "Administrator"

Combine that with the ability to use aliases in place of cmdlet names, and you can end up with a truly unreadable command line:

Gwmi Win32_LogicalDisk –comp SERVER-R2 –filt "DriveType=3" –cred "Administrator"

In classes, I tell my students to type whatever they want when they’re using the shell. After all, saving yourself typing saves you time. That’s what the shell is all about. However, I also tell them they should copy and paste a command into a script. It makes sense to use the full cmdlet name and the full parameter names. Doing so makes the eventual script easier to read.

Some commercial script editors, like SAPIEN PrimalScript and Quest PowerGUI (with a free plug-in), can even expand cmdlet or parameter names from the abbreviated to full versions. This helps you truncate names with less effort.

The New Way

Splatting is a whole new way of passing parameters to a command. You start by creating a hashtable, which is also called a dictionary or associative array. A hashtable is a collection of key=value pairs. A basic hashtable contains two keys, each with a single value. It looks like this in Windows PowerShell:

@{'key1'='value1';'key2'='value2'}

The “@” sign starts the hashtable, which is enclosed in curly braces—the ones that look like this: { }. Each key=value pair is separated from the others by a semicolon. In splatting, the keys are parameter names. The values are the values you want to send to those parameters. In a script, you can even use line breaks within the hashtable definition to make the block easier to read:

$parms = @{'class'='Win32_BIOS';
        'computername'='SERVER-R2';
           'filter'='drivetype=3';
   'credential'='Administrator'
          }

To pass those parameters along to the command, you use “@” again. This time, though, it’s acting as a splat operator. It may be confusing that a single piece of punctuation (the “@” symbol) can have two different uses, but it works:

Get-WmiObject @parms

You’ll notice a little trick here. The “@” sign is followed by the variable name, which doesn’t include the dollar sign. That’s probably worth a brief explanation. It can be a major “gotcha” in the shell that trips up a lot of people.

In Windows PowerShell, a variable name is just a sequence of letters, numbers and underscores. It’s usually possible to have spaces and other punctuation in a variable name, but it looks ugly. A dollar sign in front of the variable name tells the shell you don’t want to deal with the variable itself. You want to deal with its contents. So $var = 5 is placing the number “5” within the variable named var.

The “@” sign, when used as a splat operator, does something similar. It says, “Take whatever characters come next and assume they’re a variable name. Assume that the variable contains a hashtable, and that the keys are parameter names. Expand those out, and feed the values from the hashtable to those parameters.” That may sound like a long-winded explanation, but that’s what’s happening.

Some folks think that, particularly inside a script, this:

$parms = @{'class'='Win32_BIOS';
        'computername'='SERVER-R2';
           'filter'='drivetype=3';
           'credential'='Administrator'
          }
Get-WmiObject @parms

Looks nicer than this:

Get-WmiObject –computername SERVER-R2 –class Win32_LogicalDisk –filter "DriveType=3" –credential "Administrator"

It’s definitely a matter of personal preference. It’s easy to see the argument for the splatting method. Your parameters, both names and values, are neatly located in a single spot. You can format them so they line up and look neat and orderly (“neat and orderly” is a major theme of my classes).

So the next time you’re placing a command in a script, consider splatting. If nothing else, it sounds really cool.

Don Jones

Don Jones is a WindowsPowerShell MVP, author and trainer. You can reach him through his Web site, ConcentratedTech.com, which also contains information on his classes and conference appearances.

This month’s article has a companion video available at Magazine Extras - Concentrated Technology. You’ll also find additional free Windows PowerShell videos at YouTube - ConcentratedDon's Channel.

Time is running out to register for Don Jones’ live, exclusive, hands-on three-day Windows PowerShell workshop co-located with TechMentor Spring 2011. Visit TechMentorEvents.com for details.