如何在PowerShell中将开关参数作为变量/通过splatting传递



如果在调用命令或脚本时有多个参数需要一个值,我知道你可以这样传递:

$parameters = @{
name = "John"
last_name = "Doe"
}

但是,如果命令或脚本实际上只是期望-T指示类似于标志的东西,但参数本身不需要值。如何在变量中设置?

$optionalT = ""
if ($itNeedsTheT) $optionalT = "-T"
command $optionalT

如果我这样做,它会抱怨以下消息:

Unknown argument 'T' on command line.

tl;dr

# Pass the $itNeedsT Boolean - which indicates whether the -T switch should
# be passed - as the switch's *value*.
command -T:$itNeedsTheT  

如果$itNeedsTheT$false,则上述内容与省略-T-通常相同(详细信息请继续阅读(。

请注意,需要使用:将开关名称与值分开。


正如boxdog在评论中指出的那样,在与splatting(@parameters(一起使用的哈希表中,您使用布尔值来表示开关参数([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

也就是说,粗略地说:

  • 使用$true通过开关
  • 使用$false而不是通过开关

这允许您保留一个无条件包含开关参数的哈希表定义,但其值可以通过编程确定。

洞穴

严格来说,哈希表条目Recurse = $true转换为参数-Recurse:$true,而Recurse = $false不会转换为省略该参数,而是转换为传递-Recurse:$false

大多数情况下,省略开关-Foo并将其与值$false(即-Foo:$false(一起传递是等效

但是,命令可以检测差异,有时会有不同的行为

一个值得注意的例子是-Confirm公共(开关(参数:省略-Confirm意味着尊重$ConfirmPreference首选变量,而-Confirm:$false意味着应该覆盖该首选变量(并且应该请求而不是确认(。

如果您想在PowerShell脚本或函数中自己进行这种区分,除了检查$Foo(-Foo(开关参数变量的值之外,还可以调用$PSBoundParameters.ContainsKey('Foo')

如果您正在处理这样一个命令,并且希望以编程方式强制开关参数的省略,您将别无选择,只能在单独的步骤中有条件地为该开关添加一个条目:

# 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

最后,请注意,作为通过splatting以编程方式指定开关值的替代方案,您可以直接将动态值传递给开关

# Dynamically determine if -Recurse should be turned on.
$recurseIfTrue = $true
Get-ChildItem -Path . -Recurse:$recurseIfTrue

请注意,需要使用:将开关名称与其值分隔开来

这是必要的,因为使用习惯的空格将参数名称与其值分开会导致PowerShell将布尔值解释为下一个参数,因为开关参数通常不接受

尽管很少使用,但这种基于:的语法适用于所有参数类型。

当splating时,使用非条件参数创建哈希表(值可以是可变的(,但在创建哈希表后添加可选参数:

$parameters = @{
Name = "John"
LastName = "Doe"
Age = $age
Enabled = $true
}
if( $favoriteThing ){
$parameters.FavoriteThing = $favoriteThing
}
command @parameters

如果在splatting中处理一个开关,您可以将其视为一个布尔参数,如上图所示,只需根据您是否希望在命令中启用该开关,为其指定一个值$true$false即可。您可以看到一个将-Confirm标志设置为$false:的非飞溅示例

Install-Package some_package -Confirm:$false

最新更新