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


103

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

Answers:


57

使用该参数时,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

-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

6
对于那些必须保留“ -File”参数并且不能更改为switch参数,但可以控制所发送的字符串值的人(如我),最简单的解决方案是将参数转换为使用[System.Convert] :: ToBoolean($ Unify); 然后,字符串值必须为“ True”或“ False”。
克里斯·海恩斯

187

更明确的用法可能是改用开关参数。然后,仅存在Unify参数将意味着已设置它。

像这样:

param (
  [int] $Turn,
  [switch] $Unify
)

21
这应该是公认的答案。为了进一步讨论,您可以像其他任何参数一样设置默认值,例如:[switch] $Unify = $false
Mario Tacke 2015年

我忽略了这个答案,因为我确信布尔是必经之路。它不是。“不能转换的‘假’输入‘System.Management.Automation.ParameterAttribute’交换机为我工作:交换机封装了布尔的功能,并停止这些样的错误。
TinyRacoon

2
@MarioTacke如果在调用脚本时未指定switch参数,则它将自动设置为$false。因此,无需显式设置默认值。
doubleDown

这个建议非常有效。能够将其中一个参数从[bool]更新为[switch],这成功地使我能够通过Task Scheduler传递参数。
JustaDaKaje

12

这是一个较旧的问题,但是在PowerShell文档中实际上对此有一个答案。我遇到了同样的问题,有一次RTFM实际上解决了它。几乎。

https://docs.microsoft.com/zh-cn/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的true / false语句之前没有'$',这对我有用


1
感谢你的分享!完美地解决了我的问题。
朱莉娅·施瓦茨

1
答案中的链接似乎已更改其内容。但是,我在这里
Slogmeister Extraordinaire

当前文档链接about_powershell.exe或只是梯级powershell -h
赛斯

令我感到惊讶的是,这种尴尬的解决方案曾经奏效-在Windows PowerShell v5.1中不起作用(既不带有也不带有Lead $)。还请注意,PowerShell Core中不再需要它。我已经要求对文档进行更正;参见github.com/MicrosoftDocs/PowerShell-Docs/issues/4964
mklement0

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

1
XLII皇帝的答案以及您对该-File参数的评论应涵盖原始问题的各个方面。我会留下我的答案,因为有人还会发现我提供默认值的提示很有用。
Filburt

菲尔伯特做得好。您的回答使我检查了我的脚本,该脚本已将默认值指定为必需值$ false(几年前我写了该内容,而忘记了所有内容)-因此,我什至不必在脚本上指定有问题的布尔参数命令行。优秀:)
Zeek2 '18

5

我认为,使用/设置布尔值作为参数的最佳方法是在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的参数中,您可以将布尔值作为简单字符串:)传递。


2

在PowerShell中,可以通过在变量前提到其类型来声明布尔参数。

    function GetWeb() {
             param([bool] $includeTags)
    ........
    ........
    }

您可以通过传递$ true来赋值。$假

    GetWeb -includeTags $true

仅仅像这样显式地传递命名的输入参数就可以了。谢谢艾哈迈德
史蒂夫·泰勒

0

Windows PowerShell v5.1 / PowerShell Core 7.0.0-preview.4开始,总结并补充现有的答案

大卫Mohundro的回答是理所当然的点,而不是[bool]参数,你应该使用[switch]参数在PowerShell中,其中,存在与不存在开关名称(中-Unify规定对指定的)意味着它的价值,这使得原来的问题消失。


但是,有时您可能仍需要显式传递switch ,尤其是在以编程方式构造命令行的情况下:


在PowerShell中的核心,将原来的问题(描述皇帝四十二的回答

也就是说,要$true显式传递给[switch]名为的参数,-Unify您现在可以编写:

pwsh -File .\RunScript.ps1 -Unify:$true  # !! ":" separates name and value, no space

下面的值可以使用:$falsefalse$truetrue,但注意,通过01工作。

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

注意:如果声明的是[bool]参数而不是参数[switch](通常不应这样做),则必须使用相同的语法。即使-Unify $false 可以使用,但目前无法使用-请参阅GitHub问题


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

  • 在建议的解决方法LarsWA的答案 -尽管它是基于官方的帮助主题写这篇文章的-确实没有工作V5.1

    • 这个GitHub问题要求更正文档,还提供了一个测试命令,该方法显示了解决方法的无效性。
  • 唯一有效的解决方法是使用-Command代替-File

:: # From cmd.exe
powershell -Command "& .\RunScript.ps1 -Unify:$true" 

随着-Command你有效地传递片的PowerShell代码,然后评估像往常一样-和PowerShell通过内部$true$false作品(但不是 truefalse现在一样也接受-File)。

注意事项

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

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

有关详细信息,请参见此答案此答案


0

将脚本传递给带有invoke-command的函数时,我遇到了类似的事情。我用单引号而不是双引号运行命令,因为它随后变成了字符串文字。'Set-Mailbox $sourceUser -LitigationHoldEnabled $false -ElcProcessingDisabled $true';


0

从bash在Linux上运行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

-3

您还可以使用0False1True。它实际上表明在错误消息中:

无法对参数“统一”进行参数转换。不能值转换"System.String"到类型"System.Boolean",这种类型的参数,只接受布尔值或数字,使用$true$false1或0代替。

有关更多信息,请参见MSDN上有关布尔值和运算符的文章。


10
那行不通。期望整数1或0,但是将其传递为整数将其-File解释为字符串,因此失败并出现相同的错误。
2015年

这个答案是错误的,因为建议不起作用
mjs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.