PowerShell 脚本中的布尔参数值

XMa*_*pot 4 powershell boolean-operations

我想了解 PowerShell 脚本如何处理布尔参数值。

我有一个带有 4 个参数的脚本,其中 2 个是布尔变量。当我运行脚本并将这些参数之一设置为 $False 时,脚本仍然认为该变量设置为 $True。

版本 1:BooleanTest.ps1(使用 BOOLEAN 参数)

param(
    [Parameter(Mandatory=$True, Position=1)][string]$param1,
    [Parameter(Mandatory=$True, Position=2)][string]$param2,
    [Parameter(Mandatory=$True, Position=3)][bool]$param3,
    [Parameter(Mandatory=$True, Position=4)][bool]$param4
)

write-output $param1, $param2, $param3, $param4
Run Code Online (Sandbox Code Playgroud)

从命令提示符运行此脚本将返回以下内容:

>BooleanTest.ps1 -param1 "String1" -param2 "String2" -param3 $True -param4 $False
String1
String2
$True
$True
Run Code Online (Sandbox Code Playgroud)
我还尝试调整此脚本以使用开关参数:

版本 2:BooleanTest.ps1(使用 SWITCH 参数)

param(
    [Parameter(Mandatory=$True, Position=1)][string]$param1,
    [Parameter(Mandatory=$True, Position=2)][string]$param2,
    [switch]$param3,
    [switch]$param4
)

write-output $param1, $param2, $param3, $param4
Run Code Online (Sandbox Code Playgroud)

从命令提示符运行此版本将返回:

>BooleanTest.ps1 -param1 "String1" -param2 "String2" -param3:$True -param4:$False
String1
String2

IsPresent
---------
     True
    False
Run Code Online (Sandbox Code Playgroud)

根据这些试验,我有以下问题:

  • 在版本 1 中,为什么当我将第四个变量声明为 $False 时,它​​会错误地返回为 $True?
  • 在版本 2 中,为什么返回“IsPresent”列表?
  • switch 语句如何工作?传入变量后,我是否需要运行额外的代码来分配 True/False 值,或者我可以按原样使用该参数吗?

我已经阅读了各种帮助和故障排除文章,但似乎没有任何关于将布尔值传递给脚本的明确文档。如果有任何信息能够帮助我了解在这种情况下应用的正确技术,我将不胜感激。

我的系统设置:
操作系统:Windows 10
PowerShell 版本:PowerShell 7.1.5

Ben*_*est 5

版本1

这对我有用。我得到以下输出:

String1
String2
True
False
Run Code Online (Sandbox Code Playgroud)

我不确定运行此命令时会发生什么,但这是您提供的预期输出。


版本2

您没有使用布尔类型,而是使用开关类型。switch行为很像布尔值,但不是布尔值。在确定真实性时,最终考虑的是真实性的价值IsPresent,而不是真实性的默认行为。当提供或不提供该switch值时$false,其计算结果为$false。如果该switch值是$true或已提供,则其计算结果为$true

注意:我所说的IsPresent是与 进行比较时考虑switchboolIsPresent尽管您可以查看以了解如何做出决定,但这过于简单化并且在技术上是不正确的。如果您想要更高级的解释,请继续阅读。

魔术背后的实际原因和“秘密武器”是因为类型SwitchParameter[switch]是 的类型加速器SwitchParameter重载了和比较运算符,以及在和之间强制转换运算符。这些重载允许和在比较过程中在功能上表现得像相同类型,并允许两者之间的隐式转换(类型转换),尽管它们是完全不同的ValueTypes==!=boolswitchswitchbool

大多数时候,bool和之间的差异switch并不重要。在 99% 的情况下,您可以以相同的方式进行比较,除了当您实际需要检查两者的属性时可能用于调试的代码。

它们在默认输出方面也有所不同,当写入控制台时switch有不同的显示格式化程序,它将输出格式化为IsPresent默认显示的表格,与bool类型不同。然而,这是一个非常小的差异。

它们的主要区别在于使用它们的时间和方式。


何时使用switch

switch最适合与参数定义一起使用。这种方式对于 PowerShell 来说是惯用的,您不需要为参数提供$true或值。$false您只需指定它们或不喜欢这样:

BooleanTest2.ps1 -param1 "String1" -param2 "String2" -param3
Run Code Online (Sandbox Code Playgroud)

这将输出与您当前调用版本 2 布尔测试相同的输出。尽管正如您所发现的,您可以提供$trueor$false值,当您需要switch根据另一个条件有条件地提供 时,这会很方便。

何时使用bool

相反,使用boolfor 参数则不太常见,并且不被认为是惯用的。您必须以与任何其他类型相同的方式提供参数和值。实际上,只要有记录,这通常不是问题,但需要考虑。bool最常在脚本中未定义函数参数的任何其他地方使用。