我有一个脚本foo.ps1
和一个批处理文件foo.cmd
用于通过在文件资源管理器中双击cmd文件来启动脚本。
该脚本接受开关参数,但我不知道如何提供这种参数。简单的参数就可以了。
Foo.ps1:
param(
[Parameter()]
[Switch]$MySwitch,
[Parameter()]
[string]$Name
)
Write-Host "`$MySwitch : $MySwitch, `$Name : $name"
Foo.cmd:
Powershell -noprofile -NonInteractive -file "%~dp0foo.ps1" -Name "abc"
如果我只用"名称"调用脚本,它可以工作。但是如果我指定 MySwitch,它会停止工作:
Foo2.cmd:
Powershell -noprofile -NonInteractive -File "%~dp0foo.ps1" -Name "abc" -MySwitch:$false
错误是:
C:tempfoo.ps1 : Impossible de traiter la transformation d'argument sur le paramètre «MySwitch». Impossible de convertir la valeur «System.String» en type « System.Management.Automation.SwitchParameter». Les paramètres booléens acceptent seulement des valeurs booléennes et des nombres, tels que $True, $False, 1 ou 0.
+ CategoryInfo : InvalidData : (:) [foo.ps1], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,foo.ps1
在Windows PowerShell中,当使用powershell.exe
的s-File
参数时,无法传递布尔值 - 这已经在PowerShell(Core)7+中得到了纠正,其CLI为pwsh.exe
[1]。
使用 JosefZ 建议的解决方法:
使用-Command
(-c
)而不是-File
会使PowerShell将参数视为PowerShell源代码而不是文字参数,在这种情况下,$false
被正确识别(为简洁起见,省略其他CLI参数)。
powershell -c "& "%~dp0foo.ps1" -Name 'abc' -MySwitch:$false"
注意:
&
调用运算符必须用于调用脚本文件,因为它的路径是用引号括起来的。PowerShell期望命令行上嵌入的
使用"
字符作为"
进行转义(而不是`"
或""
,就像它在PowerShell中的工作方式一样)。-Command
,如果需要在嵌入的"..."
字符串中嵌入逐字"
,请使用`"
(原文如此)。- 虽然您可以将脚本路径括在
'...'
中,但为了避免转义的需要,如果扩展的目录文件路径 (%dp0
) 恰好包含'
字符本身,则此类调用将中断。
有关何时使用
-File
与-Command
和适用的不同语法规则,请参阅此答案。
关于概念说明:
你的代码已使用首选方式在 PowerShell 中传递布尔参数:
[switch]
参数(有时称为标志)。
开关参数暗示布尔值:如果指定了给定的开关 - 仅按名称 - (
-MySwitch
),则隐含$true
;如果完全不存在,则隐含$false
。也就是说,简单地省略-MySwitch:$false
也可以解决您的问题。- 相比之下,应避免使用
[bool]
类型参数(总是需要参数)。这篇文章将[bool]
与[switch]
参数进行了对比。
- 相比之下,应避免使用
虽然(PowerShell-内部)您(总是)可以传递显式值(如您尝试使用
-MySwitch:$false
,请注意所需的:
分隔符,空格不起作用) -仅在以下情况下需要这样做:如果要通过以编程方式确定值的变量传递布尔值。
在极少数情况下,开关默认为
$true
,您需要覆盖它。出于概念原因,最好避免在用户代码中将交换机参数默认为
$true
:如有必要,否定交换机的逻辑;例如Write-Host
的-NoNewLine
交换机。但是,PowerShell 的一些常见参数是开关参数,实际上可以通过其首选项变量对应项默认为
$true
。- 一个值得注意的例子是常见的
-Confirm
开关参数:相应的$ConfirmPreference
首选项变量的值使得有必要传递-Confirm:$false
才能选择退出确认提示,即使使用$ConfirmPreference
的默认值(High
)。
- 一个值得注意的例子是常见的
[1] PowerShell (Core) 7+ 在使用-File
时支持以下布尔值:$true
、$false
、true
、false
(以及$null
,但其解释不同:脚本(包括-File
)和函数将其解释为$false
,而 cmdlet 将其解释为$true
(!))。
请注意,对于-Command
- 因此在所有PowerShell代码中 -true
和false
不起作用,但0
和1
起作用.
不幸的是,如果传递不受支持的值,则在所有方案中都会收到相同的错误消息,这在-File
方案中误导性地表明0
和1
也可以工作。