我正在尝试使用-match语句处理多个安装程序的返回代码。我希望下面的代码两次返回"Installer(s) ran successfully",但是-match语句不能处理包含值0的整数数组…
$InstallerExitCodes = @()
$InstallerExitCodes += 0 # Pretend this is (Start-Process -PassThru -Wait installer.exe).ExitCode which returns 0 (success)
If ($InstallerExitCodes -match "^(0|3010)$") {
Write-Output "Installer(s) ran successfully" # This does not run
}
$InstallerExitCodes += 3010 # Pretend this is (Start-Process -PassThru -Wait installer.exe).ExitCode which returns 3010 (success with reboot required)
If ($InstallerExitCodes -match "^(0|3010)$") {
Write-Output "Installer(s) ran successfully" # This does
}
它当然匹配0
-问题不在于正则表达式比较,而在于if
语句。
PowerShell的标量比较运算符有两种模式操作:
- 标量模式:当左侧操作数不可枚举时,如
1 -eq 1
, PowerShell返回比较的布尔结果-即表达式的计算结果为$true
或$false
。 - 过滤模式:当左侧操作符是可枚举时,比较操作符的作用类似于过滤器:
1,2,3 -gt 1
不返回$true
或$false
,它返回由2
和3
组成的数组,因为它们满足-gt 1
约束。
由于$InstallerExitCodes
被显式声明为数组,因此-match
在过滤模式下工作,表达式的结果不再是$true
或$false
(简化):
PS C:> @(0) -match '^0$'
0
if()
上下文使PowerShell将表达式结果转换为[bool]
,由于0
是一个false值,因此if
条件失败。
更改if条件以检查结果筛选器模式表达式的计数:
if(@($InstallerExitCodes -match "^(0|3010)$").Count -ge 1){
# success!
}
或使用包含操作符来测试:
if($InstallerExitCodes -contains 0 -or $InstallerExitCodes -contains 3010){
# success!
}
或者,您知道,单独测试退出码,而不是作为集合:-)