【问题标题】:Using the PowerShell call (&) operator to call PowerShell scripts with switch parameters使用 PowerShell 调用 (&) 运算符调用带有开关参数的 PowerShell 脚本
【发布时间】:2016-03-23 09:36:25
【问题描述】:

假设我们有以下SwitchTest.ps 脚本

param(
    [switch]$Flag = $false
)

echo "Flag: $Flag"

以下按预期工作:

& ".\SwitchTest.ps1" -Flag
Flag: True

但事实并非如此

& ".\SwitchTest.ps1" "-Flag"
Flag: False

此外,如果我们将SwitchTest.ps 修改为如下所示:

param(
    [switch]$Flag = $false,
    [string]$Str = $null
)

echo "Flag: $Flag"
echo "Str: $Str"

我们得到了这个预期的行为:

& ".\SwitchTest.ps1" -Flag
Flag: True
Str: 

还有这个意想不到的:

& ".\SwitchTest.ps1" "-Flag"
Flag: False
Str: -Flag

我试过-Flag true-Flag $true-Flag:$true...没有雪茄。看起来开关参数在引用时被“跳过”(即当它是正确的字符串时) - 为什么?如果我想以编程方式构建"-Flag",该怎么办?

【问题讨论】:

  • 字符串永远是字符串......如果要执行存储在字符串中的命令,请按照@briantist 的建议使用iex
  • 看看这篇文章是否有助于清除它:Running Executables in PowerShell.
  • 我觉得文档中的这句话是你不想在这里的:因为调用运算符不解析命令,它无法解释命令参数。我我倾向于站在布赖恩蒂斯特一边。这不是它的用途。为什么在调用脚本时可以省略调用运算符(测试以防万一)?
  • 如果它是一个脚本块呢?那你不需要使用呼叫接线员吗?
  • 我现在明白我的错误了。我试图使用纯字符串调用 PS 构造(我错误地认为所有参数都归结为字符串)。我需要一个用于 PS 构造的 PS 机制(在本例中为 splatting)。

标签: powershell


【解决方案1】:

您提出了一个非常好的问题,并设置了一个非常好的测试用例。让我们留下不带参数的标志,因此它默认为 $Null。当您单独指定 -Flag 时,PowerShell 使用 switch 参数。但是,PowerShell 将"-Flag" 解释为字符串,因此会尝试查找与字符串变量匹配的参数,并将该字符串(包括-,因为它位于双引号中)传递给与[String] 类型匹配的参数。最后,由于您将字符串"-Flag" 发送到字符串变量,Flag 变量保留为其默认值$Null$False。好问题。

这是您可以用来测试的代码。

#Put this in a script file, e.g. ParamTest.ps1
Flag: False
Str: -Flag

param(
    [switch]$Flag,
    [string]$Str = $null
)

Write-Output "Flag: $Flag"
Write-Output "Str: $Str"

像上面一样执行:

 & ".\SwitchTest.ps1" "-Flag"

但是现在您已经了解了 PowerShell 如何分配传入的参数,请尝试以下操作来触发 Flag 参数,就像您原本打算做的那样:

& .\ParamScript.ps1 "-Flag" -Flag

【讨论】:

    【解决方案2】:

    如果我不在基地,请原谅我,但如果您想有条件地设置该标志,请放弃呼叫操作员并使用 splatting。

    PS M:\Scripts> $params = @{Flag=$true;Str="Bagels"}
    
    PS M:\Scripts> .\switchTest.ps1 @params
    Flag: True
    Str: Bagels
    

    【讨论】:

    • 漂亮的飞溅效果甚至可以与调用运算符一起使用(我喜欢保留它,因此无论我是调用 PS 脚本还是“普通”exe,我都有一致的代码)。
    【解决方案3】:

    您看到的行为正是我所期望的。

    如果您想以编程方式构建它,请使用Invoke-Expression

    【讨论】:

    • 我知道iex 有效,我在问为什么& 无效,是否有任何解决方法。
    猜你喜欢
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 2014-02-18
    • 1970-01-01
    • 2020-12-04
    相关资源
    最近更新 更多