Powershell:如何在命令行调用Powershell时将变量传递给开关参数?

40

通常,如果你想将开关参数的规定推迟到某个变量中,你可以将一个表达式传递给该开关参数,如WhatIf参数所示。

test.ps1

param ( [string] $source, [string] $dest, [switch] $test )
Copy-Item -Path $source -Destination $dest -WhatIf:$test

这使你在使用开关时具有很大的灵活性。但是,当你使用cmd.exe或其他东西调用powershell时,你最终会得到像这样的结果:

D:\test>powershell -file test.ps1 -source test.ps1 -dest test.copy.ps1 -test:$true

D:\test\test.ps1 : Cannot process argument transformation on
parameter 'test'. Cannot convert value "System.String" to type "System.Manageme
nt.Automation.SwitchParameter", parameters of this type only accept booleans or
 numbers, use $true, $false, 1 or 0 instead.
At line:0 char:1
+  <<<<
    + CategoryInfo          : InvalidData: (:) [test.ps1], ParentContainsError
   RecordException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,test.ps1
然而,使用-test:true-test:1时得到的结果相同。为什么会这样?Powershell的类型转换系统不应该自动将这些字符串识别为可转换为bool或开关的类型并进行转换吗?
这是否意味着当从其他系统(如构建系统)调用PowerShell脚本时,需要构造复杂的流程控制结构来确定命令字符串中是否包含开关,或者省略它?这似乎很繁琐且容易出错,这让我认为不是这种情况。
2个回答

30

这种行为已经被记录为一个错误在connect上。以下是解决方法:

powershell ./test.ps1 -source test.ps1 -dest test.copy.ps1 -test:$true

请注意,此答案已过时 - Microsoft Connect已停用,无法从链接中了解错误的状态。 - Spencer

23

使用 switch 的 IsPresent 属性。 示例:

function test-switch{
param([switch]$test)
  function inner{
    param([switch]$inner_test)
    write-host $inner_test
  }
  inner -inner_test:$test.IsPresent
}
test-switch -test:$true
test-switch -test
test-switch -test:$false

True
True
False

顺便说一下,我使用了函数而不是脚本,这样测试会更容易。


1
这实际上是我在第一个示例中尝试的内容 - 问题似乎是PowerShell在从cmd.exe调用脚本时不将参数评估为表达式,而是将"$true"作为不透明字符串。 - bwerks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接