If you have multiple parameters which require a value when calling a command or a script, I know you can pass it like this:
$parameters = @{
name = "John"
last_name = "Doe"
}
But if the command or script actually just expect -T
to indicate something like a flag, but the parameter itself doesn't require a value. How can I set that in a variable?
$optionalT = ""
if ($itNeedsTheT) $optionalT = "-T"
command $optionalT
If I do it like that it complains with the following message:
Unknown argument 'T' on command line.
Here is the basic syntax for using splatting. You use the regular PowerShell command ( <CommandName> ) followed by the variable name indicating the splatted values ( @<SplattedValues> ). Not all parameters need to be included in the splat. You can pass other parameters ( <parameters> ) before or after the splat.
Passing arguments in PowerShell is the same as in any other shell: you just type the command name, and then each argument, separated by spaces. If you need to specify the parameter name, you prefix it with a dash like -Name and then after a space (or a colon), the value.
To create a switch parameter in a function, specify the switch type in the parameter definition. Switch parameters are easy to use and are preferred over Boolean parameters, which have a less natural syntax for PowerShell. For example, to use a switch parameter, the user types the parameter in the command.
When splatting, create the hashtable with non-conditional parameters (the values can be variable), but add the optional parameters after the hashtable is created:
$parameters = @{
Name = "John"
LastName = "Doe"
Age = $age
Enabled = $true
}
if( $favoriteThing ){
$parameters.FavoriteThing = $favoriteThing
}
command @parameters
If dealing with a switch in splatting, you can treat it as a boolean parameter like shown above, just give it a value of $true
or $false
depending on whether you want the switch to be enabled on the command or not. You can see a non-splat example of this to set a -Confirm
flag to $false
:
Install-Package some_package -Confirm:$false
tl;dr
# Pass the $itNeedsT Boolean - which indicates whether the -T switch should
# be passed - as the switch's *value*.
command -T:$itNeedsTheT
If $itNeedsTheT
is $false
, the above is the same as omitting -T
- usually (read on for details).
Note the need to use :
to separate the switch name from the value.
As boxdog points out in a comment, in a hashtable used with splatting (@parameters
), you use a Boolean value to represent a switch parameter (a flag-like parameter of type [switch]
) .
# Dynamically determine if -Recurse should be turned on.
$recurseIfTrue = $true
# Define the hashtable for splatting...
$parameters = @{
Path = '.'
Recurse = $recurseIfTrue # turn the -Recurse switch on or off
}
# ... and pass it to the target command.
# *Loosely speaking*, the following command is the same as either:
# Get-ChildItem -Path '.' -Recurse # if $recuseIfTrue was $true
# or:
# Get-ChildItem -Path '.' # if $recuseIfTrue was $false
Get-ChildItem @parameters
That is, loosely speaking:
$true
to pass the switch$false
to not pass the switch.This allows you to keep a single hashtable definition that unconditionally includes the switch parameter, but whose value can determine programmaticaly.
Caveat:
Strictly speaking, hashtable entry Recurse = $true
translates to parameter -Recurse:$true
and Recurse = $false
doesn't translate into omitting the parameter, it translates to passing -Recurse:$false
.
In most cases, omitting a switch -Foo
and passing it with value $false
- i.e. -Foo:$false
- are equivalent.
However, commands can detect the difference and sometimes act differently:
A notable example is the -Confirm
common (switch) parameter: omitting -Confirm
means that the $ConfirmPreference
preference variable is respected, whereas -Confirm:$false
means that the preference variable should be overridden (and confirmation should not be requested).
If you want to make this distinction yourself in a PowerShell script or function, you can call $PSBoundParameters.ContainsKey('Foo')
in addition to checking the $Foo
(-Foo
) switch parameter variable's value.
If you're dealing with such a command and you want to programmatically enforce omission of a switch parameter, you'll have no choice but to conditionally add an entry for this switch, in a separate step:
# Dynamically determine if -Recurse should be turned on.
$recurseIfTrue = $true
# A 'Recurse' key now can NOT be included unconditionally,
# if you want to *omit* -Recurse in case $recurseIfTrue is $false
$parameters = @{
Path = '.'
}
# Add a 'Recurse' entry only if the switch should be passed.
if ($recurseIfTrue) {
$parameters.Recurse = $true
}
Get-ChildItem @parameters
Finally, note that as an alternative to specifying a switch value programmatically via splatting, you can pass a dynamic value to a switch directly:
# Dynamically determine if -Recurse should be turned on.
$recurseIfTrue = $true
Get-ChildItem -Path . -Recurse:$recurseIfTrue
Note the need to use :
to separate the switch name from its value.
This is necessary, because using the customary whitespace to separate the parameter name from its value would cause PowerShell to interpret the Boolean as the next argument, given that switch parameters normally do not take values.
Although rarely used, this :
-based syntax works with all parameter types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With