PowerShell Parameters Splatting and Defaults Explained
| technology | system admin - Ross Heintzkill

PowerShell Parameters Splatting and Defaults Explained

PowerShell is an awesome tool. If your device is running Windows 10, you've got PowerShell. If your job involves working with Windows devices, you've got to know PowerShell. PowerShell's cmdlets are simple, single-function tools built directly into the shell. Each cmdlet is useful on its own, but it's when you combine them that you can automate and manage really complex tasks and operations on your network devices.

When you start getting into those complex tasks, you might start writing long lines of code that specify a lot of inputs. Fortunately, one of PowerShell's strengths is how easy it is to pass parameter values to a command – cmdlets are designed to be written quickly. But when you start adding more and more parameters and values to a command, you run the risk of having a really, really long command. Having a long command displayed on one line can lead to headaches in debugging and checking your work, whether your editor gives you line breaks or whether you end up scrolling horizontally.

In this blog post, we're going to talk about the solution to the problem you face when your lines of code run on and on: splatting. PowerShell splatting lets you supply multiple parameters to a command – shortening your code and making it far more manageable. Not only that, but we'll also cover defaults. Working together, PowerShell splatting and parameter defaults can speed up your coding while making it much more versatile.

What is PowerShell Splatting?

Quick Definition: Splatting is a PowerShell feature that allows you to bundle up the parameters you want to supply to a command and pass them in a table, rather than one long line of code. Without PowerShell splatting, your commands can be hard to read and navigate. With PowerShell splatting, you give each parameter that can go into your command a line of its own, making it a lot easier to update, read and use.

What are PowerShell Defaults?

Quick Definition: PowerShell defaults are the values your PowerShell parameters automatically default to, but what makes them interesting and valuable is that you can manipulate those defaults. As of PowerShell v3, with PowerShell defaults, you're able to edit the base set of parameters that you use most with different commands. Because the defaults are easily overridden when you need to, by setting defaults, you're saving yourself the time of inputting the values whenever you use the commands or call the parameters without restricting yourself or your code.

An Overview of PowerShell Parameters Splatting and Defaults [VIDEO]

In this video, Don Jones covers PowerShell Parameters, specifically, Splatting and Defaults. These parameters can make your PowerShell code more readable, save time, and result in better overall consistency. These are phenomenal functions that are essential for any IT professional working in PowerShell.

Systems Administrators Need to Know Splatting

Splatting and parameter defaults were introduced in PowerShell version 3, which was released way back in September 2012. On top of that, they're two of the more useful and valuable features to ever improve PowerShell. And yet, somehow, there are still many systems administrators who don't recognize the terms or make use of them.

Admittedly, splatting is a weird name, and defaults isn't quite what most people think it is. So, that might have something to do with their lack of popularity. No matter the reason why more systems administrators don't know the features, they can make your PowerShell experience much, much better. PowerShell splatting and defaults will make your code more readable, can help save you time, and they can make things more consistent as you use the shell.

PowerShell Commands Without Splatting Get Long

At their core, both splatting and defaults were designed to give you different ways to pass parameters to a command. In order to demonstrate splatting, we should have a line of code we can return to throughout. Imagine a snippet of code like this:

$params = @{        'Class'='Win32_Service';
                        'ComputerName'='localhost';
                        'Filter'="State='Running'";
                        'NameSpace'="root\CIMv2"}

The format is simple: key=value. The key is the name of a parameter. In this splatting, we've got "Class", "ComputerName", "Filter", and "NameSpace" — just like in our single line of code from earlier. The value that they're set equal to is whatever value you'd normally pass that parameter. So, you can see we've pulled in the same values as was written above, "Win32_Service", "localhost", "State='Running'", and
"root\CIMv2".

The second step in splatting is to run the command and follow it with an "@", as well as the variable name. Here's what that looks like:

Get-WmiObject @params

Note that the variable doesn't contain the "$" here. This is what's actually splatting the variable.

We always recommend practicing new concepts in as realistic an environment as possible. In other words, don't just read about PowerShell commands and splatting.  Actually try it out. Our recommendation is that you write out everything you see above into PowerShell and compare them.

The next step is to compare the two ways of executing the commands. If you're in PowerShell and want to run only line 1, you can do that by highlighting Line 1, right-clicking it and going to "Run Selection" F8 is the default shortcut. What you should see is a series of successful results from that command.

Now, before we run the splatted command, what do you think will happen when you highlight them and click "Run Selection"? Should they look exactly the same, or will there be slight differences in the output?

Only one way to find out. Highlight the splatted parameters and the command beneath them, and run the selection. You should see the exact same results. Was that your guess?

That's the beauty of splatting in PowerShell: the cmdlet is the same and the parameters are the same, the only thing that's different is the mechanism that's delivering the values of those parameters to the cmdlet. There's, effectively, no difference between running a PowerShell cmdlet with splatting and without splatting.

Can You Add Other Parameters Outside of Splatting?

The simple answer is yes. It's easy to add other parameters to a command that you've already done splatting on.

If you're following along with us in PowerShell, comment out Line 1 to save time on running code in the future. We're going to change a few more things in our splatting and don't want to accidentally run both. Once you've done that, let's add a new parameter behind @params and run the code. That should look like this:

$params = @{        'Class'='Win32_Service';
                        'ComputerName'='localhost';
                        'Filter'="State='Running'";
                         'NameSpace'="root\CIMv2"}
Get-WmiObject @params -EnableAllPrivileges%end_cli_code% 

After adding "EnableAllPrivileges" to our command, we can run this code and get a successful result. In other words, you can have a sort of a base set of parameters that you use over and over again with many different commands, and then you can also add per-command parameters to customize how things will work.

How Do You Set Default Values for Parameters in PowerShell?

Setting parameter value defaults was a feature that was added in PowerShell version 3. As we explore setting parameter defaults, you'll probably see what makes it so closely related to splatting.

The way that parameter defaults work is with a variable called "PSDefaultParameterValues". It's blank by default, and we can see what data is attached to it by typing:

$PSDefaultParameterValues

In this case, a "success" will look like nothing. But we're about to change that. As you make use of PowerShell defaults, you'll want to rely on a help file that can help with formatting and inputs for setting parameter defaults. You can find the help file by typing:

help about_parameters_default*

Reading that file should help explain the syntax for setting parameter defaults in PowerShell. But, in summary, here's the basic syntax for parameter defaults:

$PSDefaultParameterValues=@{"<CmdletName>:<ParameterName>"="<DefaultValue>"}

Using PowerShell defaults is simple enough: following that syntax, you supply what values you want to be default for a cmdlet's parameters. Since these fields can accept wildcards, you can also do much of this for multiple commands at once.

Note: we're going to update the line of code one step at a time, but you wouldn't enter each of these lines of code into PowerShell. We'll show you each step and then the final line of code at the end.

The first step is to update the cmdlet name:

  $PSDefaultParameterValues=@{"Get-WmiObject:<ParameterName>"="<DefaultValue>"}

Pay attention to where quotation marks are as you update these values. We've added "Get-WmiObject" as the cmdlet we want to change parameters for. Next up, parameter:

$PSDefaultParameterValues=@{"Get-WmiObject:ComputerName"="<DefaultValue>"}

We've set the parameter name whose default value we want to specify. We're targeting the "ComputerName" parameter for the "Get-WmiObject" cmdlet. Next, value:

$PSDefaultParameterValues=@{"Get-WmiObject:ComputerName"="localhost"}

Now we've given it the default value the parameter should output. Since the ComputerName parameter accepts string, we've just given it the string "localhost".

Those were the individual steps, but when you enter this line of code into PowerShell, you'll only enter it once. It will look like this:

$PSDefaultParameterValues=@{"Get-WmiObject:ComputerName"="localhost"}

Now that we've set the defaults, let's return to our variable from earlier and check our work. To do that, type:

$PSDefaultParameterValues 

If everything's gone well, you should now see that Get-WmiObject ComputerName is under the "Name" column header and under "Value" is localhost.

Can You Override Parameter Default Values in PowerShell?

The great thing about setting default values for your parameters is that you can always override them when you need to. Setting default values is meant to save you time when you're coding, if you were locked into your default selections, you'd almost certainly be wasting time in the long run.

First, let's check that our default values worked. To do that, let's type:

Get-WmiObject -Class win32_bios

If it succeeds, we can rest assured that our default value of "localhost" was used by the command. But to override our parameter default value in PowerShell, we just enter the parameter and the new value. To do that, type:

Get-WmiObject -Class win32_bios -ComputerName NOTONLINE

We used "NOTONLINE" as our computer name so that we get an error. That error is proof that we have overridden the default.

Can You Add Parameter Values to PowerShell's Defaults After Setting Them?

After you set the default values for your parameters, adding new ones is as easy as using the Add method. Above, we created a brand new set for our parameters, but adding defaults after you've already established a set is easy. To use the Add method, type:

$PSDefaultParameterValues.Add("Get-WmiObject:Class"="Win32_BIOS")

Error. Oops, while we were writing this, we made a mistake. And rather than retroactively fix it, we might as well explain the problem, it might help you add defaults of your own in the future. Most things about the line of code above are correct. You can use the Add method to modify parameters with default values. But what we messed up is how the Add method differs from creating a new set of parameter values. Here's the correct way to type that:

$PSDefaultParameterValues.Add("Get-WmiObject:Class","Win32_BIOS")

The Add method needs a comma, not an equals sign, between the parameter and the inputted value. Typing this should return a success. To check, let's look at our defaults again by typing:

$PSDefaultParameterValues

We should now have two values in there: ComputerName and Class.

What that means is, if we type:

Get-WmiObject

The return should always be querying the BIOS on localhost. Unless we override the default values, which we also know how to do now. Admittedly, this may not be a perfect example of when you might want to establish defaults, but the point is that you can. And now you know the syntax for setting defaults in PowerShell, overriding them, as well as adding parameters to your preset PowerShell defaults.

Can PowerShell Defaults Be Applied for Just One Script?

One last thing to keep in mind when dealing with PowerShell splatting and defaults is that PowerShell has a system of scope. In other words, if you do all of this default parameter value definition in a script, then it will only take effect for that script.

We'll quickly demonstrate what it'd look like to set up at the beginning of a script a bunch of default values that we want to be valid throughout that script. For example, say somebody specified a computer name, you're going to run several different operations, and you want all of those to run against that computer name.

You'll start with a param block which specifies a computer name. Following that, the first line of your script will specify that for all cmdlets within that script, every parameter will be given a default value of whatever "ComputerName" was assigned for that device. That script might wind up looking something like this:

param($computername)
$PSDefaultParameterValues = @{"*:ComputerName"=$computername}

Note: don't forget to wrap the default values in a hash table with the @{ }.

These lines of code only execute for this script, but now, within this script, the "ComputerName" parameter doesn't need to be specified on a per-computer basis. Again, this is a small example, but should illustrate how versatile defaults and splatting can be.

Wrapping Up

PowerShell is more than just a powerful and versatile command line tool for managing and automating system tasks — mastering it is essential knowledge for systems administrators. No matter where you are in your career, you can improve your skills with PowerShell and your job prospects with training.

CBT Nuggets' Microsoft PowerShell Reference training can help you learn the language and how to master it. Or you can prepare for your MCSA: Windows Server 2016 exams with CBT Nuggets' online PowerShell training.

Download

Download

Ultimate Systems Administration Cert Guide

A 158-page guide to every Microsoft, VMware, Citrix, AWS, Google, and Linux certification, and how they fit into your career.

By submitting this form you agree that you have read, understood, and are able to consent to our privacy policy.

LEARNING ON MOBILE

Learn anytime anywhere with our mobile apps.

I have read and understood the privacy policy and am able to consent to it.

© 2021 CBT Nuggets. All rights reserved. Terms | Privacy Policy | Accessibility | Sitemap | 1550 Valley River Drive, Eugene, OR 97401 | 541-284-5522
CBT Nuggets