Contents

Splatting parameters in PowerShell

How to pass in multiple arguments in PowerShelll


My preferred way of passing in parameters in PowerShell!

Splatting parameters in PowerShell

Something I really like about PowerShell is the verbosity of the language. By looking at a script written in PowerShell you can quickly tell what a line of code is suppossed to do. For example, the cmdlet Move-Item, moves an item from one location to another and its parameters (e.g. Path and Destination) are also self descriptive. This makes it very easy for someone to pick up the language. However, a downside to the verbosity is that one cmdlet with multiple arguments can turn into a full paragraph. This can be very annoying because your line of code will no longer fit on the screen. One technique that can help making your code cleaner and prevent the long line of code is splatting. Ever since I learned about splatting I have become kind of addicted to using it. In this post I will be showing you what splatting is, some of its use cases and most likely get you to use it as well!

Backticks

Before we are going to look at splatting lets have a look at the backticks technique. You may have seen the backtick character ( ` ) being used in a lot of scripts that you find on the internet. The backtick character is used in PowerShell as an escape character. If you put the backtick character at the end of a line it will escape the carriage return which will result in continuatation to the next line. This makes it handy to use if you have a cmdlet to which you want to pass in a bunch of arguments. Because you can pass in each argument on another line, like this:

1
2
3
4
5
6
7
8
9
Set-AzKeyVaultSecret `
  -VaultName 'Contoso' `
  -Name 'ITSecret' `
  -SecretValue $Secret `
  -Expires $Expires `
  -NotBefore $NotBefore `
  -ContentType $ContentType `
  -Disable `
  -Tags $Tags 

Even though this multilined appproach is easier to read then having this all written out on a single line there are some downsides to the backtick approach and hence I do not like to use it. First of all the backtick character can be hard to read/spot and second of all it is easy to mess up. Having a space behind the character will cause it to escape the space and hence break your logic.

Instead lets have a look at splatting parameters through an array.

Splatting array

The splatting array technique allows you to do a similar multiline approach for parameters without using the backtick. Before I am going to describe what this technique is all about lets first look at what this would look like for the example above:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$secretArgs = @(
  'Contoso'
  'ITSecret'
  $Secret
  $true
  $Expires
  $NotBefore
  $ContentType
  $Tags
)
Set-AzKeyVaultSecret @secretArgs

First we are creating an array $secretArgs which contains all of the values that we want to pass in to our cmdlet. Then we pass them in to the cmdlet by calling our array using the splatting operator (@). Notice that the array is declared over multiple lines, this doesn’t have to be the case. You can also pass them in on one-line. What is required however, is that all the parameters have to be declared in the array based on their position in the cmdlet. This means that you can’t just swap input parameters around.

This brings us to our lord and savior, splatting.

Splatting

Yet again, lets look at an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$secretArgs = @{
    VaultName   = 'Contoso'
    Name        = 'ITSecret'
    SecretValue = $Secret
    Expires     = $Expires
    NotBefore   = $NotBefore
    ContentType = $ContentType
    Disable     = $true
    Tags        = $Tags
}
Set-AzKeyVaultSecret @secretArgs

Instead of creating an array we are creating a hash table which contains key value pairs of all the arguments that we want to pass into our cmdlet. With this approach it doesn’t matter in what order we list the parameters. The only thing that matters is that the parameter names that we give does have to match with the input parameters of the cmdlet. E.g. an error will occur if there is a typo.

Overwriting splatting parameters

Another thing that I like about splatting is that you can reuse the parameters in a lot of scenarios. Which helps following the Don’t Repeat Yourself (DRY) principle. In case I have a usecase where based on some logic I don’t want to disable, or re-enable a secret I could just run the same cmdlet as in the splatting example and add an additional argument, like so:

1
Set-AzkeyVaultSecret @secretArgs -Disable $false

Although Disable was set to $true in my $secretArgs, the secret won’t be disabled.

Splatting multiple hash tables

You can also pass in multiple splatting arguments. E.g.:

1
Set-AzKeyVaultSecret @secretArgs @envArgs

Perhaps for these kind of scenarios the Set-AzKeyVaultSecret cmdlet is not the best example but I usually use this approach in my scripts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Param(
    [Parameter(Mandatory=$true)]
    [ValidateSet('Dev','Prod')]
    [string]$Environment
)

switch($Environment) {
  'Dev' {
      $envArgs = @{
        VaultName = 'contosodev'
        Tags      = $Tags
      }
  }
  'Prod' {
      $envArgs = @{
        VaultName = 'contosoprod'
        Tags      = $Tags
      }
  }
}

$secretArgs = @{
    Name        = 'ITSecret'
    SecretValue = $Secret
    Expires     = $Expires
    NotBefore   = $NotBefore
    ContentType = $ContentType
    Disable     = $true
}
Set-AzKeyVaultSecret @secretArgs @envArgs

In such a scenario $envArgs would be declared based on the parameters passed into the script (the environment in this case) and the $secretArgs based on the logic processing within the script.

Conclusion

In this post I showed you how you can pass in arguments over multiple lines in PowerShell. I showed the backtick-, array splatting- and splatting techniques, explained the ups- and downs to each technique and which technique I prefer to use.

I hope you found this post useful. Have a very nice day! 👍