如何将开关参数作为变量/通过 PowerShell 中的 splatting 传递?
How to pass a switch parameter as a variable / via splatting in PowerShell?
如果您有多个参数在调用命令或脚本时需要一个值,我知道您可以这样传递它:
$parameters = @{
name = "John"
last_name = "Doe"
}
但是如果命令或脚本实际上只是希望 -T
指示类似标志的东西,但参数本身不需要值。我如何在变量中设置它?
$optionalT = ""
if ($itNeedsTheT) $optionalT = "-T"
command $optionalT
如果我这样做,它会抱怨以下消息:
Unknown argument 'T' on command line.
splatting时,创建非条件参数的hashtable(值可以是可变的),但在创建hashtable后添加可选参数:
$parameters = @{
Name = "John"
LastName = "Doe"
Age = $age
Enabled = $true
}
if( $favoriteThing ){
$parameters.FavoriteThing = $favoriteThing
}
command @parameters
如果在splatting中处理一个switch,你可以把它当作一个布尔参数,如上所示,只需要给它一个$true
或$false
的值,这取决于你是否想要switch是否在命令上启用。您可以看到一个非 splat 示例,将 -Confirm
标志设置为 $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
如果$itNeedsTheT
是$false
,以上同省略-T
-通常(继续阅读以了解详细信息)。
注意需要使用 :
将开关名称与值分开。
与 boxdog points out in a comment, in a hashtable used with 一样,您 使用 布尔值 值来表示开关参数 (类型为标志的参数[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
到不通过开关。
这允许您保留一个单一的哈希表定义,该定义无条件地包含 switch 参数,但其值可以通过编程方式确定。
警告:
严格来说,哈希表条目 Recurse = $true
转换为参数 -Recurse:$true
和 Recurse = $false
不转换为 省略 参数,它转换为传递 -Recurse:$false
.
在大多数情况下,省略一个开关-Foo
并用值[=15传递它=] - 即 -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
注意 需要使用 :
将开关名称与其值分开[=109=]。
这是必要的,因为使用习惯的 空格 将参数名称与其值分开会导致 PowerShell 将布尔值解释为 next 参数,因为 switch 参数通常不采用 values.
虽然很少使用,但这种基于 :
的语法适用于 所有 参数类型。
如果您有多个参数在调用命令或脚本时需要一个值,我知道您可以这样传递它:
$parameters = @{
name = "John"
last_name = "Doe"
}
但是如果命令或脚本实际上只是希望 -T
指示类似标志的东西,但参数本身不需要值。我如何在变量中设置它?
$optionalT = ""
if ($itNeedsTheT) $optionalT = "-T"
command $optionalT
如果我这样做,它会抱怨以下消息:
Unknown argument 'T' on command line.
splatting时,创建非条件参数的hashtable(值可以是可变的),但在创建hashtable后添加可选参数:
$parameters = @{
Name = "John"
LastName = "Doe"
Age = $age
Enabled = $true
}
if( $favoriteThing ){
$parameters.FavoriteThing = $favoriteThing
}
command @parameters
如果在splatting中处理一个switch,你可以把它当作一个布尔参数,如上所示,只需要给它一个$true
或$false
的值,这取决于你是否想要switch是否在命令上启用。您可以看到一个非 splat 示例,将 -Confirm
标志设置为 $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
如果$itNeedsTheT
是$false
,以上同省略-T
-通常(继续阅读以了解详细信息)。
注意需要使用 :
将开关名称与值分开。
与 boxdog points out in a comment, in a hashtable used with [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
到不通过开关。
这允许您保留一个单一的哈希表定义,该定义无条件地包含 switch 参数,但其值可以通过编程方式确定。
警告:
严格来说,哈希表条目 Recurse = $true
转换为参数 -Recurse:$true
和 Recurse = $false
不转换为 省略 参数,它转换为传递 -Recurse:$false
.
在大多数情况下,省略一个开关-Foo
并用值[=15传递它=] - 即 -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
注意 需要使用 :
将开关名称与其值分开[=109=]。
这是必要的,因为使用习惯的 空格 将参数名称与其值分开会导致 PowerShell 将布尔值解释为 next 参数,因为 switch 参数通常不采用 values.
虽然很少使用,但这种基于 :
的语法适用于 所有 参数类型。