如何在 PowerShell 中通过 splatting 将 switch 参数作为变量传递?

问题描述 投票:0回答:2

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

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

但是,如果命令或脚本实际上只是期望

-T
指示类似标志的内容,但参数本身不需要值。我如何将其设置为变量?

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

command $optionalT

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

Unknown argument 'T' on command line.
powershell variables switch-parameter parameter-splatting
2个回答
19
投票

tl;博士

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

如果

$itNeedsTheT
$false
,则以上与 省略
-T
- 通常 相同(请继续阅读了解详情)。

请注意需要使用

:
将开关名称与值分开。


正如 boxdog 在评论中指出的那样,在与 splatting (

@parameters
) 一起使用的哈希表中,您使用 Boolean 值来表示开关参数(类型为
[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
并传递值
$false
- 即
-Foo:$false
- 是等价

但是,命令可以检测差异,有时表现不同

一个值得注意的例子是

-Confirm
公共(开关)参数: 省略
-Confirm
意味着尊重
$ConfirmPreference
偏好变量,而
-Confirm:$false
意味着偏好变量应该被 覆盖(并且确认应该被要求)。

如果您想在 PowerShell 脚本或函数中自己进行区分,除了检查

$PSBoundParameters.ContainsKey('Foo')
(
$Foo
) 开关参数变量的值之外,还可以调用
-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

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

# Dynamically determine if -Recurse should be turned on.
$recurseIfTrue = $true

Get-ChildItem -Path . -Recurse:$recurseIfTrue

注意 需要使用

:
将开关名称与其值分开

这是必要的,因为使用习惯的 whitespace 将参数名称与其值分开会导致 PowerShell 将布尔值解释为 next 参数,因为 switch 参数通常不采用 values

虽然很少使用,但这种基于

:
的语法适用于 all 参数类型。


5
投票

splatting时,创建带有非条件参数的哈希表(值可以是可变的),但在创建哈希表后添加可选参数:

$parameters = @{
  Name = "John"
  LastName = "Doe"
  Age = $age
  Enabled = $true
}

if( $favoriteThing ){
  $parameters.FavoriteThing = $favoriteThing
}

command @parameters

如果在splatting中处理开关,您可以将其视为布尔参数,如上所示,只需给它一个值

$true
$false
,具体取决于您是否希望在命令上启用开关。您可以查看一个非 splat 示例,将
-Confirm
标志设置为
$false
:

Install-Package some_package -Confirm:$false
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.