mut*_*gan 93 powershell scripting
我必须从批处理文件中调用PowerShell脚本.脚本的一个参数是布尔值:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify $false
Run Code Online (Sandbox Code Playgroud)
该命令失败,并显示以下错误:
Cannot process argument transformation on parameter 'Unify'. Cannot convert value "System.String" to type "System.Boolean", parameters of this type only accept booleans or numbers, use $true, $false, 1 or 0 instead.
At line:0 char:1
+ <<<< <br/>
+ CategoryInfo : InvalidData: (:) [RunScript.ps1], ParentContainsErrorRecordException <br/>
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,RunScript.ps1
Run Code Online (Sandbox Code Playgroud)
截至目前,我在我的脚本中使用字符串进行布尔转换.但是如何将布尔参数传递给PowerShell?
Dav*_*dro 166
更明确的用法可能是使用开关参数.然后,只有Unify参数的存在意味着它被设置.
像这样:
param (
[int] $Turn,
[switch] $Unify
)
Run Code Online (Sandbox Code Playgroud)
Emp*_*LII 55
看来powershell.exe在-File使用参数时没有完全评估脚本参数.特别是,$false参数被视为字符串值,与下面的示例类似:
PS> function f( [bool]$b ) { $b }; f -b '$false'
f : Cannot process argument transformation on parameter 'b'. Cannot convert value
"System.String" to type "System.Boolean", parameters of this type only accept
booleans or numbers, use $true, $false, 1 or 0 instead.
At line:1 char:36
+ function f( [bool]$b ) { $b }; f -b <<<< '$false'
+ CategoryInfo : InvalidData: (:) [f], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,f
Run Code Online (Sandbox Code Playgroud)
而不是使用-File你可以尝试-Command,它会将调用评估为脚本:
CMD> powershell.exe -NoProfile -Command .\RunScript.ps1 -Turn 1 -Unify $false
Turn: 1
Unify: False
Run Code Online (Sandbox Code Playgroud)
正如David建议的那样,使用switch参数也会更加惯用,通过消除显式传递布尔值的需要来简化调用:
CMD> powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify
Turn: 1
Unify: True
Run Code Online (Sandbox Code Playgroud)
Fil*_*urt 11
尝试将参数类型设置为[bool]:
param
(
[int]$Turn = 0
[bool]$Unity = $false
)
switch ($Unity)
{
$true { "That was true."; break }
default { "Whatever it was, it wasn't true."; break }
}
Run Code Online (Sandbox Code Playgroud)
如果未提供输入,则此示例默认$Unity为$false.
用法
.\RunScript.ps1 -Turn 1 -Unity $false
Run Code Online (Sandbox Code Playgroud)
这是一个较旧的问题,但在PowerShell文档中实际上有一个答案.我有同样的问题,一旦RTFM实际解决了它.几乎.
-File参数的文档指出"在极少数情况下,您可能需要为switch参数提供布尔值.要在File参数的值中为switch参数提供布尔值,请将参数名称和值括起来花括号,如下所示:-File.\ Get-Script.ps1 {-All:$ False}"
我不得不这样写:
PowerShell.Exe -File MyFile.ps1 {-SomeBoolParameter:False}
Run Code Online (Sandbox Code Playgroud)
因此,在PowerShell 4.0上,在真/假声明之前没有'$',这对我有用
从 bash 在 Linux 上运行 powershell 脚本也会出现同样的问题。解决方法与 LarsWA 的答案几乎相同:
在职的:
pwsh -f ./test.ps1 -bool:true
Run Code Online (Sandbox Code Playgroud)
不工作:
pwsh -f ./test.ps1 -bool=1
pwsh -f ./test.ps1 -bool=true
pwsh -f ./test.ps1 -bool true
pwsh -f ./test.ps1 {-bool=true}
pwsh -f ./test.ps1 -bool=$true
pwsh -f ./test.ps1 -bool=\$true
pwsh -f ./test.ps1 -bool 1
pwsh -f ./test.ps1 -bool:1
Run Code Online (Sandbox Code Playgroud)
我认为,使用/设置布尔值作为参数的最佳方法是在PS脚本中使用,如下所示:
Param(
[Parameter(Mandatory=$false)][ValidateSet("true", "false")][string]$deployApp="false"
)
$deployAppBool = $false
switch($deployPmCmParse.ToLower()) {
"true" { $deployAppBool = $true }
default { $deployAppBool = $false }
}
Run Code Online (Sandbox Code Playgroud)
所以现在您可以像这样使用它:
.\myApp.ps1 -deployAppBool True
.\myApp.ps1 -deployAppBool TRUE
.\myApp.ps1 -deployAppBool true
.\myApp.ps1 -deployAppBool "true"
.\myApp.ps1 -deployAppBool false
#and etc...
Run Code Online (Sandbox Code Playgroud)
因此,在cmd的参数中,您可以将布尔值作为简单字符串:)传递。
总结和补充现有的答案,从 Windows PowerShell v5.1(最新也是最后一个版本)/PowerShell(核心)7.3.3 开始:
David Mohundro 的回答正确地指出,您应该在 PowerShell 中使用参数,而不是[bool][switch]参数,其中开关名称的存在与不存在-Unify(指定与未指定)意味着它的值,这使得原始问题消失。
但是,有时您可能仍然需要显式传递开关值,特别是当您以编程方式构建命令行时:
在PowerShell Core 7+中,原来的问题(在皇帝四十二的回答中描述)已得到修复。
也就是说,要$true显式传递给[switch]名为的参数,-Unify您现在可以编写:
pwsh -File .\RunScript.ps1 -Unify:$true # !! ":" separates name and value, no space
Run Code Online (Sandbox Code Playgroud)
可以使用以下值:$false、false、$true、true,但请注意传递0或1不起作用。
请注意开关名称与值如何分隔,并且两者之间:不能有空格。
注意:如果您声明一个[bool]参数而不是 a [switch](通常不应该这样做),则必须使用相同的语法。尽管-Unify $false 应该可以工作,但目前还不能 - 请参阅GitHub 问题 #10838。
在Windows PowerShell中,最初的问题仍然存在,并且鉴于 Windows PowerShell 不再被积极开发,因此不太可能得到解决。
LarsWA 的答案中建议的解决方法- 尽管它是基于截至撰写本文时已更正的官方帮助主题-在 v5.1 中不起作用
使用-Command代替-File是唯一有效的解决方法:
:: # From cmd.exe
powershell -Command "& .\RunScript.ps1 -Unify:$true"
Run Code Online (Sandbox Code Playgroud)
您可以-Command有效地传递一段PowerShell 代码,然后像往常一样对其进行评估 - 在 PowerShell 内部传递$true和$false可以工作(但不是 trueand false,因为现在也接受 with -File)。
注意事项:
使用-Command可能会导致对参数进行额外的解释,例如它们是否包含$字符。(其中-File,参数是文字)。
使用-Command可能会导致不同的退出代码。
| 归档时间: |
|
| 查看次数: |
154911 次 |
| 最近记录: |