我必须从批处理文件中调用PowerShell脚本。脚本的一个参数是布尔值:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify $false
命令失败,并显示以下错误:
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
截至目前,我在脚本中使用字符串进行布尔转换。但是如何将布尔参数传递给PowerShell?
答案 0 :(得分:148)
更明确的用法可能是使用开关参数。然后,只有Unify参数的存在才意味着它被设置了。
像这样:
param (
[int] $Turn,
[switch] $Unify
)
答案 1 :(得分:48)
使用-File
参数时,powershell.exe似乎无法完全评估脚本参数。特别是,$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
您可以尝试-File
而不是使用-Command
,这会将调用评估为脚本:
CMD> powershell.exe -NoProfile -Command .\RunScript.ps1 -Turn 1 -Unify $false
Turn: 1
Unify: False
正如David所暗示的那样,使用switch参数也会更加惯用,通过消除显式传递布尔值的需要来简化调用:
CMD> powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify
Turn: 1
Unify: True
答案 2 :(得分: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 }
}
如果未提供任何输入,此示例默认$Unity
为$false
。
<强>用法强>
.\RunScript.ps1 -Turn 1 -Unity $false
答案 3 :(得分:5)
这是一个较旧的问题,但在PowerShell文档中实际上有一个答案。我有同样的问题,一旦RTFM实际解决了它。几乎。
-File参数的文档说明了这一点 “在极少数情况下,您可能需要为switch参数提供布尔值。要在File参数的值中为switch参数提供布尔值,请将参数名称和值括在花括号中,如下所示: -File。\ Get-Script.ps1 {-All:$ False}“
我必须这样写:
PowerShell.Exe -File MyFile.ps1 {-SomeBoolParameter:False}
所以在真实/虚假陈述之前没有'$',这对我有效,在PowerShell 4.0上
答案 4 :(得分:3)
我认为,使用/设置布尔值作为参数的最佳方法是在PS脚本中使用它,如下所示:
Param(
[Parameter(Mandatory=$false)][ValidateSet("true", "false")][string]$deployApp="false"
)
$deployAppBool = $false
switch($deployPmCmParse.ToLower()) {
"true" { $deployAppBool = $true }
default { $deployAppBool = $false }
}
所以现在你可以像这样使用它:
.\myApp.ps1 -deployAppBool True
.\myApp.ps1 -deployAppBool TRUE
.\myApp.ps1 -deployAppBool true
.\myApp.ps1 -deployAppBool "true"
.\myApp.ps1 -deployAppBool false
#and etc...
因此,在cmd的参数中,您可以将布尔值作为简单的字符串传递:)。
答案 5 :(得分:1)
在PowerShell中,可以通过在变量前先提及其类型来声明布尔参数。
// Load your Account Sid and Auth Token somehow, for example, from the environment
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const twilio = require('twilio')
const client = twilio(accountSid, authToken);
app.post('/calls', (req, res) => {
const callSid = req.body.CallSid;
client.calls(callSid)
.recordings
.create()
.then(recording => console.log('Recording started')
.catch(err => console.error('Recording failed. ', err);
const twiml = new twilio.twiml.VoiceResponse();
const numberToDial = process.env.NUMBER_TO_DIAL;
twiml.say(`Hi, you're calling ${numberToDial}.`);
twiml.dial(numberToDial);
res.set('Content-Type', 'text/xml');
res.send(twiml.toString());
});
您可以通过传递$ true来赋值。 $ false
function GetWeb() {
param([bool] $includeTags)
........
........
}
答案 6 :(得分:0)
要总结和补充现有答案:
David Mohundro's answer正确地指出,您应该在PowerShell中使用而不是[bool]
参数,而应该使用[switch]
parameters ,其中 存在与不存在<开关名称的/ em>(指定的-Unify
与未指定的 )表示它的值,这使原来的问题消失了。
但是,有时候,您可能仍需要显式传递开关值 ,特别是如果您正在以编程方式构造命令行 时:
在PowerShell Core 中,原始问题(在Emperor XLII's answer中进行了描述)已已修复< / em> 。
也就是说,要将$true
显式传递给名为[switch]
的{{1}}参数,您现在可以编写:
-Unify
可以使用以下值:pwsh -File .\RunScript.ps1 -Unify:$true # !! ":" separates name and value, no space
,$false
,false
,$true
,但是请注意,传递true
或0
确实可以不有效。
请注意,开关名称是如何与1
的值分开的,并且两者之间必须没有空格。
注意:如果声明一个:
参数而不是一个[bool]
(通常不应该这样做),则必须使用相同的语法。即使[switch]
应该有效,但目前不起作用-请参见this GitHub issue。
在 Windows PowerShell 中,原始问题仍然存在,并且-由于不再积极开发Windows PowerShell-不太可能得到解决。
LarsWA's answer中建议的解决方法-即使在撰写本文时它基于the official help topic-在v5.1中不是否有效
使用-Unify $false
代替-Command
是唯一有效的解决方法:
-File
使用:: # From cmd.exe
powershell -Command "& .\RunScript.ps1 -Unify:$true"
,您可以有效地传递一段PowerShell代码,然后按常规进行评估-在PowerShell中,传递-Command
和$true
的工作原理(但不是 $false
和true
,现在也被false
接受)。
注意事项:
使用-File
可能导致对参数的其他解释,例如它们包含-Command
字符。 (对于$
,参数为 literal )。
使用-File
可能会导致不同的退出代码。
有关详细信息,请参见this answer和this answer。
答案 7 :(得分:0)
当使用invoke-command将脚本传递给函数时,我有类似的事情。我用单引号而不是双引号运行命令,因为它随后变成了字符串文字。 'Set-Mailbox $sourceUser -LitigationHoldEnabled $false -ElcProcessingDisabled $true';
答案 8 :(得分:0)
在Linux上从bash运行powershell脚本会遇到相同的问题。解决的方法几乎与LarsWA的答案相同:
工作:
pwsh -f ./test.ps1 -bool:true
不起作用:
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
答案 9 :(得分:-3)
您还可以0
使用False
,1
使用True
。它实际上建议在错误消息中:
无法处理参数&#39;统一&#39;的参数转换。无法将值
"System.String"
转换为"System.Boolean"
类型,此类型的参数仅接受布尔值或数字,请使用$true
,$false
, 1或0。
有关详细信息,请查看Boolean Values and Operators上的此MSDN文章。