powershell Catch块在以下时间后未将警告消息打印到控制台

gmxoilav  于 2023-01-26  发布在  Shell
关注(0)|答案(1)|浏览(138)

我正在编写一个简单的脚本来检查本地用户帐户。我想使用try_catch错误来处理错误,但我不明白为什么脚本中的catch块不会打印脚本中的警告消息。欢迎提供任何指导。

function checkAccount($user)
{
    try {
       Get-CimInstance Win32_UserAccount| Where-Object -Property Name -Contains $user |Select-Object -ExpandProperty Name -ErrorAction Stop
    }
    catch {
        Write-Warning -Message "Oops, ran into an issue"
    }
}
e5nqia27

e5nqia271#

  • 在您的管道中有两个命令可以报告非终止错误-Get-CimInstanceSelect-Object [1] -所以您应该将-ErrorAction Stop与这两个命令一起使用。
  • 更简单的替代方法是将整个函数的首选项变量$ErrorActionPreference设置为'Stop'
function checkAccount($user)
{
    # Make all errors in this scope (and descendant scopes) (script)-terminating, 
    # which enables them to be caught with try / catch.
    $ErrorActionPreference = 'Stop'
    try {
       Get-CimInstance Win32_UserAccount | 
         Where-Object -Property Name -eq $user | 
         Select-Object -ExpandProperty Name
    }
    catch {
        Write-Warning -Message "Oops, ran into an issue"
    }
}

还要注意,我已经用-eq替换了-Contains,因为-contains操作符用于测试 * 集合 * 是否包含给定值,而您正在 * 逐个 * 处理用户帐户。
相反,如果您的目的是执行 substring 匹配,则使用-like *$user*

注意事项

  • scriptmodules导入的高级(类似于cmdlet)函数 * 不会 * 看到首选项变量,除非它们碰巧在 global 作用域中定义-有关此问题行为的讨论,请参见GitHub issue #4568

相反,如果您的目的只是*测试 * 给定的用户帐户是否存在,则可以如下定义函数,使用approved verbTest,并相应地使函数返回[bool]值($true$false):

function Test-Account($user)
{
    [bool] (
      Get-CimInstance Win32_UserAccount | 
         Where-Object -Property Name -eq $user
    )
}
  • 在正常情况下,所涉及的命令不会报告错误,因此不需要显式的错误处理。
  • [bool]强制转换利用了PowerShell的to-Boolean转换规则,以及(非基元)对象转换为$true,而 * 缺少输出 * 或$null转换为$false的事实-有关转换规则的摘要,请参阅this answer的底部部分。

[1]Get-CimInstance通常应仅报告类名无效的错误,Select-Object -ExpandProperty应仅报告属性名不存在的错误(与-Property不同)。Where-Object调用不应报告错误,因为它不强制指定属性的存在(但是,如果使用 invalid syntax,则任何cmdlet调用都将报告 statement-terminating 错误)。

相关问题