简体   繁体   English

如何将开关参数作为变量/通过 PowerShell 中的喷溅传递?

[英]How to pass a switch parameter as a variable / via splatting in PowerShell?

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.但是,如果命令或脚本实际上只是期望-T指示类似标志的东西,但参数本身不需要值。 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.

When splatting, create the hashtable with non-conditional parameters (the values can be variable), but add the optional parameters after the hashtable is created: splatting 时,使用非条件参数创建哈希表(值可以是可变的),但在创建哈希表后添加可选参数:

$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.如果在 splatting 中处理开关,您可以将其视为 boolean 参数,如上所示,只需根据您是否希望在命令上启用开关,为其赋值$true$false You can see a non-splat example of this to set a -Confirm flag to $false :您可以看到将-Confirm标志设置为$false的非 splat 示例:

Install-Package some_package -Confirm:$false

tl;dr tl;博士

# 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).如果$itNeedsTheT$false ,则上述内容与通常省略-T相同(请继续阅读以了解详细信息)。

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] ).正如boxdog在评论中指出的那样,在与喷溅 ( @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

That is, loosely speaking:也就是说,粗略地说:

  • use $true to pass the switch使用$true传递开关
  • use $false to not pass the switch.使用$false通过开关。

This allows you to keep a single hashtable definition that unconditionally includes the switch parameter, but whose value can determine programmaticaly.这允许您保留单个哈希表定义,该定义无条件地包含 switch 参数,但其值可以通过编程方式确定。

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 .严格来说,哈希表条目Recurse = $true转换为参数-Recurse:$true并且Recurse = $false不会转换为省略参数,它转换为传递-Recurse:$false

In most cases, omitting a switch -Foo and passing it with value $false - ie -Foo:$false - are equivalent .大多数情况下,省略开关-Foo并以$false值传递它 - 即-Foo:$false - 是等效的。

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).一个值得注意的例子是-Confirm通用(开关)参数:省略-Confirm表示尊重$ConfirmPreference首选项变量,而-Confirm:$false表示应覆盖首选项变量(并且不应请求确认)。

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.如果您想在 PowerShell 脚本或 function 中自己做出这种区分,除了检查$Foo ( -Foo ) 开关参数变量的值之外,您还可以调用$PSBoundParameters.ContainsKey('Foo')

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 :最后,请注意,作为通过 splatting 以编程方式指定开关值的替代方法,您可以直接将动态值传递给开关

# 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 .这是必要的,因为使用惯用的空格将参数名称与其值分开会导致 PowerShell 将 Boolean 解释为下一个参数,因为开关参数通常不采用values

Although rarely used, this : -based syntax works with all parameter types.虽然很少使用,但这种基于:的语法适用于所有参数类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM