如何阻止在Powershell中填充`$Error`的强制转换错误?

mnemlml8  于 2023-04-30  发布在  Shell
关注(0)|答案(2)|浏览(123)

我有以下代码:

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

我不想那样我想完全控制错误,因为错误本身也是函数逻辑的一部分(因为这意味着重启肯定不是挂起的)。我想控制它,就像使用-ErrorAction ignore而不是silentlycontinue和cmdlet一样。
我尝试使用以下命令:

$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

谢谢

nr7wwzry

nr7wwzry1#

你可以考虑redirect(错误)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 }
        }
    }
}

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

$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 }
        }
    }
}
uemypmqf

uemypmqf2#

只要安装了sccm客户端(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

相关问题