为什么此代码将开关参数传递给 PowerShell 函数失败



这个问题是关于传递开关参数的。让我们看看代码。我有这个PowerShell 3.0功能:

#test1.ps1
param(
    [switch] $param1 = $false
)
Write-Host "param1: $($param1.IsPresent)"
Write-Host

我有一个主要的PowerShell函数,它以四种不同的方式调用test.ps1:

#Test0.ps1
cls
$param1 = $True
# 1
.test1.ps1 -param1
# 2
.test1.ps1 -param1:$true
# 3
$potato = "-param1:`$$($param1)"
Write-Host "Parameter value: $potato" 
.test1.ps1 $potato
# 4
$command = ".test1.ps1 -param1:`$$($param1)"
Write-Host "Command: $command" 
iex $command
exit

为什么第三种方法失败了?我知道我可以做第四种方式,但我很想了解为什么第三种方式失败了。

这是输出。结果,所有参数都应该为真,但第三个参数为假...

param1: True
param1: True
Parameter value: -param1:$True
param1: False
Command: .test1.ps1 -param1:$True
param1: True

发生的情况是:

  1. 解析器查看提供的参数:"-param1:$true"
  2. 无法将其绑定到参数 param1 ,因为您提供的值是string,而不是开关/布尔值
  3. 位置 0 处不需要特定的参数类型,忽略参数

如果将param1位置设置为位置,则可以看到PowerShell如何无法正确绑定它:

function test-parambinding {param([Parameter(Position=0)][switch]$param1);$param1.IsPresent}
test-parambinding "-param1:`$true"

在其他任何事情发生之前,您会看到抛出的ParameterArgumentTransformationException

> Mathias 解释了为什么传递参数的第 3 种方式失败了,但还有另一种传递参数的方法可以让您大致完成您在这里尝试的事情。

我在这里使用了一个函数,因为它在调用它时键入的次数要少一些,但是您的脚本文件将正常工作:

PS C:> function test1() {
param(
    [switch] $param1 = $false
)
Write-Host "param1: $($param1.IsPresent)"
Write-Host
}
PS C:> $param1 = $True
PS C:> $potato = @{'param1'=$param1}
PS C:> $potato
Name                           Value                                                                                                  
----                           -----                                                                                                  
param1                         True                                                                                                   

PS C:> test1 @potato
param1: True

因此,不要将参数和值作为单个字符串传递,而是创建一个哈希,其中参数名称作为键,参数作为值。然后使用 @ 拼接运算符调用函数或脚本。(有关更多详细信息,请参阅help about_Splatting)。

最新更新