7

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

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

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

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

command $optionalT

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

Unknown argument 'T' on command line.
4

2 回答 2

8

tl;博士

# 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通过开关。

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

警告

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

大多数情况下,省略一个开关-Foo并用值传递它$false- 即-Foo:$false- 是等效的。

但是,命令可以检测到差异,有时会采取不同的行动:

一个值得注意的例子是-Confirmcommon (switch) 参数:省略 -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

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

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

Get-ChildItem -Path . -Recurse:$recurseIfTrue

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

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

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

于 2019-10-22T16:12:44.600 回答
3

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

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

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

command @parameters

如果在 splatting 中处理开关,您可以将其视为如上所示的布尔参数,只需给它一个值$true$false取决于您是否希望在命令上启用该开关。-Confirm您可以看到将标志设置为的非 splat 示例$false

Install-Package some_package -Confirm:$false
于 2019-10-22T15:13:15.757 回答