2016-03-22 60 views
2

假设我们有以下SwitchTest.ps脚本使用PowerShell的调用(&)运算符来调用PowerShell脚本与开关参数

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",我该怎么办?

+2

一个字符串总是一个字符串......如果要执行存储在一个字符串中的命令,建议使用'iex'作为@briantist。 –

+0

看看这篇文章是否有助于清除它:[在PowerShell中运行可执行文件](http://windowsitpro.com/powershell/running-executables-powershell)。 –

+1

我觉得来自文档的这句话是你不想在这里的:_因为调用操作符不解析命令,它不能解释命令参数._我倾向于与Briantist一起。这不是它的目的。为什么使用调用操作符时应该只能在调用脚本时忽略它(测试以防万一)? – Matt

回答

3

请原谅我,如果我是非基地,但如果你想有条件设置该标志,放弃呼叫运营商,只使用splatting。

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

PS M:\Scripts> .\switchTest.ps1 @params 
Flag: True 
Str: Bagels 
+0

美丽,即使与呼叫操作员(我喜欢保持,所以我有一致的代码,无论我是否调用PS脚本或“正常”EXE)splatting工程。 –

1

你看到的行为正是我所期待的。

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

+0

我知道'iex'工作,我问为什么'&'不,并且如果有任何解决方法。 –

3

您提出了一个很好的问题,并设置了一个非常好的测试用例。让我们留下没有参数的标志,所以它默认为$ Null。当您自己指定-Flag时,PowerShell将使用开关参数。但是,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 
相关问题