如何从命令提示符将布尔值传递给PowerShell脚本

时间:2011-02-22 14:31:17

标签: scripting powershell

我必须从批处理文件中调用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?

10 个答案:

答案 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实际解决了它。几乎。

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe

-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)

从Windows PowerShell v5.1 / PowerShell Core 7.0.0-preview.4开始,

总结和补充现有答案

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 $falsefalse$true,但是请注意,传递true0确实可以有效。

请注意,开关名称是如何与1的值分开的,并且两者之间必须没有空格。

注意:如果声明一个:参数而不是一个[bool](通常不应该这样做),则必须使用相同的语法。即使[switch] 应该有效,但目前不起作用-请参见this GitHub issue


Windows PowerShell 中,原始问题仍然存在,并且-由于不再积极开发Windows PowerShell-不太可能得到解决。

  • LarsWA's answer中建议的解决方法-即使在撰写本文时它基于the official help topic-在v5.1中是否有效

    • This GitHub issue要求更正文档,并提供测试命令以显示变通办法的无效性。
  • 使用-Unify $false代替-Command是唯一有效的解决方法

-File

使用:: # From cmd.exe powershell -Command "& .\RunScript.ps1 -Unify:$true" ,您可以有效地传递一段PowerShell代码,然后按常规进行评估-在PowerShell中,传递-Command$true的工作原理(但不是 $falsetrue,现在也被false接受)。

注意事项

  • 使用-File可能导致对参数的其他解释,例如它们包含-Command字符。 (对于$,参数为 literal )。

  • 使用-File可能会导致不同的退出代码

有关详细信息,请参见this answerthis 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使用False1使用True。它实际上建议在错误消息中:

  

无法处理参数&#39;统一&#39;的参数转换。无法将值"System.String"转换为"System.Boolean"类型,此类型的参数仅接受布尔值或数字,请使用$true$false 1或0。

有关详细信息,请查看Boolean Values and Operators上的此MSDN文章。