Kee*_*tle 1 variables error-handling powershell
我有一个我创建的 powershell 脚本,如果模块尚未导入,它会尝试导入模块。
Try {
Import-Module -Name 'ModuleName' -ErrorAction Stop -ErrorVariable ModFail
}
Catch {
Write-Error "Module failed to be loaded."
}
Run Code Online (Sandbox Code Playgroud)
稍后在脚本中,我试图检查模块是否无法导入,但检查错误变量。对于未通过 errorvariable 参数设置的其他变量,我仅使用以下内容来检查其是否为空。
If ($null -eq $var) {
Do stuff
}
Run Code Online (Sandbox Code Playgroud)
但是使用我使用 errorvariable 设置的变量这样做是行不通的。
if ($null -ne $Modfail) {
Do stuff
}
Run Code Online (Sandbox Code Playgroud)
在测试变量是否实际上为空时,上述评估为真。这与我想要的相反。当我运行变量时,它确实为空并且正在运行
$modfail | Gm
Run Code Online (Sandbox Code Playgroud)
失败,因为它是空的。为什么会这样?如果我在 errorvariable 参数之外设置变量或者不设置它,它会返回正确的。即使它有空格,它也应该在管道到 Get-Member 时以正确的字符串返回?
在-ErrorVariable 常见的参数,像所有的-*Variable常用参数,报告从相关数据流作为收集输出的System.Collections.ArrayList实例。
(除非有一个句法问题与调用),一个System.Collections.ArrayList是总是创建并分配给指定变量,即使没有对象被输出至目标流; 也就是说,在 的情况下-ErrorAction,如果没有发生错误,则会创建一个空 System.Collections.ArrayList- 这与 不同$null。
因此,if ($null -ne $Modfail) ...不是正确的测试,因为它总是会返回$true(根据定义$null,任何对象都不是,无论其类型或内容如何)。
相反,使用if ($Modfail.Count -gt 0) ...或者更简单地依赖于一个空集合被隐式强制转换为$false[1]的事实:if ($Modfail) ...
至于:
$modfail | Get-Member失败,因为它是空的。为什么会这样?
每当您通过管道发送集合时,它都会被枚举。枚举空数组不会枚举任何内容,在这种情况下Get-Member(理所当然地)会抱怨缺少输入。
(如果数组不为空,您应该会看到有关 的信息System.Management.Automation.ErrorRecord,即存储在 中的元素的类型$ModFail)。
如果你想检查集合本身有Get-Member,使用Get-Member -InputObject $Modfail-你会发现它的类型 System.Collections.ArrayList(如非泛型集合,它的元素都没有预定类型)。
[1] 请注意,根据单个元素的值,也可以强制使用单元素集合;但是,对于由 所创建的集合,其中包含非空实例,这不是问题;有关背景信息,请参阅此答案的底部部分。$false-ErrorVariableSystem.Management.Automation.ErrorRecord