如何阻止在PowerShell中将错误传递到`$Error`中的错误?

huangapple go评论66阅读模式
英文:

How to stop casting error from populating `$Error` in Powershell?

问题

以下是代码部分的中文翻译:

function Test-PendingReboot {
    try {
        $util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'
        $status = $util.DetermineIfRebootPending()
        if (($null -ne $status) -and $status.RebootPending) {
            return $true
        }
    } catch {}
    return $false
}

这段代码是一个函数的一部分,如您所见,它用于检查系统是否有未完成的重启任务。

只有当重启任务待处理时,才会发生到[wmiclass]的强制类型转换。

这个函数正常工作,但有一个副作用,即在未有重启任务时,强制类型转换错误会被记录在$Error自动变量中。您可以通过以下方式检查:

$error.clear()
Test-PendingReboot
$error

这将打印如下内容(False只是调用的返回值):

False

Cannot convert value "\.\root\ccm\clientsdk:CCM_ClientUtilities" to type "System.Management.ManagementClass". Error: "Invalid parameter "
At C:\_\t.ps1:26 char:89
+ … re'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') } …
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastToWMIClass

我不想让这种情况发生。我希望能完全控制错误处理,因为错误本身也是函数逻辑的一部分(因为它表示未来肯定不会有重启任务)。我希望能像在使用cmdlet时使用-ErrorAction ignore一样控制它。

我尝试使用以下方法:

$ErrorActionPreference = 'ignore'
$util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'

甚至以下方法(是的,有点疯狂):

$ErrorActionPreference = 'ignore'
$util = Invoke-Command -ScriptBlock { $ErrorActionPreference = 'ignore'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') } -ea Ignore

但都没有起作用...

我开始怀疑,这是否可能?

请注意:这段代码只是一个示例,我的问题是,一般情况下,如何阻止强制类型转换错误进入$Error

英文:

i have the following code:

function Test-PendingReboot {
    try {
        $util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'
        $status = $util.DetermineIfRebootPending()
        if (($null -ne $status) -and $status.RebootPending) {
            return $true
        }
    } catch {}
    return $false
}

which is part of a function that, as you can see, checks if a system reboot is pending.

That casting to [wmiclass] is possible only when a reboot is pending.

The function works correctly, but with the side effect of the casting error (when a reboot is not pending) going into the $Error automatic variable. You can check with:

$error.clear()
Test-PendingReboot
$error

This will print the following (False is just the return value of the call):

False

Cannot convert value "\.\root\ccm\clientsdk:CCM_ClientUtilities" to type "System.Management.ManagementClass". Error: "Invalid parameter "
At C:\_\t.ps1:26 char:89
+ … re'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') } …
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastToWMIClass

I don't want that.
I want to have complete control over the error, as the error itself is also part of the logic of the function (because it means that a reboot is certainly not pending).
I want to control it as when using -ErrorAction ignore instead of silentlycontinue with a cmdlet.

I tried using the following:

$ErrorActionPreference = 'ignore'
$util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'

or even the following (yes that's mad):

$ErrorActionPreference = 'ignore'
$util = Invoke-Command -ScriptBlock { $ErrorActionPreference = 'ignore'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') } -ea Ignore

but nothing works...

I'm starting to doubt, Is it even possible?

PLEASE NOTE: this piece of code is just an example, my question is, in general, how to stop casting error from getting into $Error?


thanks

答案1

得分: 1

你可以考虑重定向(错误)

function Test-PendingReboot {
    $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } 2>&1
    $util.ForEach{
        if ($_ -is [System.Management.Automation.ErrorRecord]) {
            "Your error: $_"
        }
        else {
            $status = $_.DetermineIfRebootPending()
            if ($null -ne $status) { $status.RebootPending }
        }
    }
}

要完全拦截错误,您可以考虑启动一个昂贵且繁琐的新PowerShell会话:

$Result = PowerShell {
    $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } 2>&1
    $util.ForEach{
        if ($_ -is [System.Management.Automation.ErrorRecord]) {
            "Your error: $_"
        }
        else {
            $status = $_.DetermineIfRebootPending()
            if ($null -ne $status) { $status.RebootPending }
        }
    }
}
英文:

You might consider to redirect the (error) stream:

function Test-PendingReboot {
    $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } *>&1
    $util.ForEach{
        if ($_ -is [System.Management.Automation.ErrorRecord]) {
            "Your error: $_"
        }
        else {
            $status = $_.DetermineIfRebootPending()
            if ($null -ne $status) { $status.RebootPending }
        }
    }
}

To completely intercept the error, you might consider to start an expensive and cumbersome new PowerShell session:

$Result = PowerShell {
    $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } *>&1
    $util.ForEach{
        if ($_ -is [System.Management.Automation.ErrorRecord]) {
            "Your error: $_"
        }
        else {
            $status = $_.DetermineIfRebootPending()
            if ($null -ne $status) { $status.RebootPending }
        }
    }
}

答案2

得分: 0

这个从不例外,只要安装了 SCCM 客户端 (get-package 'configuration manager client'):

# 或者使用 Invoke-WmiMethod
$myargs = @{ namespace = 'root\ccm\clientsdk'
             class = 'CCM_ClientUtilities'
             name = 'DetermineIfRebootPending' }
Invoke-CimMethod @myargs | select RebootPending

RebootPending
-------------
False
英文:

This never has an exception as long as sccm client is installed (get-package 'configuration manager client'):

# or Invoke-WmiMethod
$myargs = @{ namespace = 'root\ccm\clientsdk'
             class = 'CCM_ClientUtilities'
             name = 'DetermineIfRebootPending' }
Invoke-CimMethod @myargs | select RebootPending

RebootPending
-------------
False

huangapple
  • 本文由 发表于 2023年3月31日 16:40:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75896501.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定