Powershell Can';t捕获GetWMicomeException

Powershell Can';t捕获GetWMicomeException,powershell,Powershell,代码是这样的 try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE" } catch [GetWMICOMException] { "Error 1" } catch [System.UnauthorizedAccessEx

代码是这样的

try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE" }

catch [GetWMICOMException]
{
    "Error 1"
}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}
得到如下错误:

找不到类型[GetWMicomeException]:

捕获[COMException]相同

catch[System.Runtime.InteropServices.COMException]刚刚被忽略

我怎样才能抓住它

Get-WmiObject : RPC server was unavailable. (Exception HRESULT: 0x800706BA)
F:\PowerShell Scripts\Project1.NetReconfigurer\proj1.ps1:36 :33
+             $NIC = Get-WmiObject <<<<  Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE"

+ CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get WmiObject:RPC服务器不可用。(异常HRESULT:0x800706BA)
F:\PowerShell脚本\Project1.NetReconfigurer\proj1.ps1:36:33

+$NIC=首先获取WmiObject。该错误是一个非终止错误,因此它只是通知。如果要捕获非终止错误,请使用
-ErrorAction Stop
。另外,我不认为
COMException
是您可以捕捉到的异常。请尝试以下方法:

try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE -ErrorAction Stop}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}
catch [Exception]
{
    if ($_.Exception.GetType().Name -eq "COMException") {
        "Error 1"
    }
}

首先。该错误是一个非终止错误,因此它只是通知。如果要捕获非终止错误,请使用
-ErrorAction Stop
。另外,我不认为
COMException
是您可以捕捉到的异常。请尝试以下方法:

try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE -ErrorAction Stop}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}
catch [Exception]
{
    if ($_.Exception.GetType().Name -eq "COMException") {
        "Error 1"
    }
}

您只能捕获终止错误。添加“-ErrorAction Stop”以获取WMIOObject以将错误转换为终止错误,然后重试。另一方面,我还建议您在使用ping请求对目标系统运行wmi查询之前测试与目标系统的连接,它可以加快执行速度,特别是在查询大量计算机时(wmi超时会减慢脚本)


您只能捕获终止错误。添加“-ErrorAction Stop”以获取WMIOObject以将错误转换为终止错误,然后重试。另一方面,我还建议您在使用ping请求对目标系统运行wmi查询之前测试与目标系统的连接,它可以加快执行速度,特别是在查询大量计算机时(wmi超时会减慢脚本)


我遇到了同一个问题,并且浏览了这一页。弗罗德·F的想法是正确的,但我对这个答案并不满意,所以我胡闹直到我得到了我想要的行为。我想我会添加一点,以防将来有其他人看到此页面:

  • 正如Frode所说,您必须使用-ErrorAction Stop来捕获此异常,因为它是非终止的
  • 如果使用完全限定名[System.Runtime.InteropServices.COMException],则可以捕获COMException
  • 如果只想在错误记录显示GetWMIComeException时捕获COMException,就像Get-WMIOObject抛出时一样,可以使用If语句检查错误记录,如果不是要查找的异常,则重新抛出该异常。在这种情况下,这样做可能有点过分,因为try块只包含一个命令。Get WMIObject是否会引发任何其他类型的COM异常是值得怀疑的。但是,在try块中有长管道或多个命令的情况下,这可能很有用
更简单的版本将捕获任何COMException:

try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -Filter "IPEnabled = $TRUE" -ErrorAction Stop}

catch [System.Runtime.InteropServices.COMException]
{
    "Error 1"
}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}
更复杂的版本,仅当COMException是Get-WMIoObject引发的“Get-WMIcomeException”时才会捕获该COMException:

try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -Filter "IPEnabled = $TRUE" -ErrorAction Stop}

catch [System.Runtime.InteropServices.COMException]
{
    if ($_.FullyQualifiedErrorId.StartsWith("GetWMICOMException")
    {
        "Error 1"
    }
    else { throw }
}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}

我遇到了同一个问题,并且浏览了这一页。弗罗德·F的想法是正确的,但我对这个答案并不满意,所以我胡闹直到我得到了我想要的行为。我想我会添加一点,以防将来有其他人看到此页面:

  • 正如Frode所说,您必须使用-ErrorAction Stop来捕获此异常,因为它是非终止的
  • 如果使用完全限定名[System.Runtime.InteropServices.COMException],则可以捕获COMException
  • 如果只想在错误记录显示GetWMIComeException时捕获COMException,就像Get-WMIOObject抛出时一样,可以使用If语句检查错误记录,如果不是要查找的异常,则重新抛出该异常。在这种情况下,这样做可能有点过分,因为try块只包含一个命令。Get WMIObject是否会引发任何其他类型的COM异常是值得怀疑的。但是,在try块中有长管道或多个命令的情况下,这可能很有用
更简单的版本将捕获任何COMException:

try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -Filter "IPEnabled = $TRUE" -ErrorAction Stop}

catch [System.Runtime.InteropServices.COMException]
{
    "Error 1"
}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}
更复杂的版本,仅当COMException是Get-WMIoObject引发的“Get-WMIcomeException”时才会捕获该COMException:

try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -Filter "IPEnabled = $TRUE" -ErrorAction Stop}

catch [System.Runtime.InteropServices.COMException]
{
    if ($_.FullyQualifiedErrorId.StartsWith("GetWMICOMException")
    {
        "Error 1"
    }
    else { throw }
}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}

我使用Try{}Catch和-ErrorVariable设法在ErrorAction模式“SilentlyContinue”中处理任何类型的错误:

    foreach ($Server in $Server_List)
    {
        $ErrorVar = $null
        $Server_Model = $null

        try
        {
            $Server_Info= Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Server -Credential $Credential -ErrorAction SilentlyContinue -ErrorVariable ErrorVar | Select Model
        }
        catch [System.UnauthorizedAccessException] # here $ErrorVar.Exception doesn't exist but $ErrorVar.ErrorRecord.Exception
        {
            $Msg = "Powershell cmdlet on $Server : DCOM unauthorized access"
            $Msg | Write-Warning
        }

        if ($ErrorVar.Exception)
        {
            switch ($ErrorVar)
            {
                { $_.Exception.GetType().Name -eq "COMException" }
                {
                    $Msg = "Powershell cmdlet on $Server : RPC server is unavailable"
                    $Msg | Write-Warning

                    break
                }
                { $_.Exception.GetType().Name -eq "ManagementException" }
                {
                    $Msg = "Powershell cmdlet on $Server : user credentials cannot be used for local connections.`nRetrying without credential."
                    $Msg | Write-Warning
                    $Server_Info = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Server | Select Model # when the script is hosted on a computer within the Server_List

                    break
                }
                default
                {
                    $Msg = "Powershell cmdlet on $Server : unexpected error"
                    $Msg | Write-Warning
                }
            }
        }

        if ($Server_Info)
        {
                $Server_Info_Pso =  New-Object PSObject -Property @{
                    HostName = $Server
                    Model = $Server_Info.Model
                }
        }
        else
        {           
            $Server_Info_Pso =  New-Object PSObject -Property @{
                HostName = $Server
                Model = 'Unavailable'
            }
        }

        $Server_Info_PsoCol = $Server_Info_PsoCol + @($Server_Info_Pso)
    }

我使用Try{}Catch和-ErrorVariable设法在ErrorAction模式“SilentlyContinue”中处理任何类型的错误:

    foreach ($Server in $Server_List)
    {
        $ErrorVar = $null
        $Server_Model = $null

        try
        {
            $Server_Info= Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Server -Credential $Credential -ErrorAction SilentlyContinue -ErrorVariable ErrorVar | Select Model
        }
        catch [System.UnauthorizedAccessException] # here $ErrorVar.Exception doesn't exist but $ErrorVar.ErrorRecord.Exception
        {
            $Msg = "Powershell cmdlet on $Server : DCOM unauthorized access"
            $Msg | Write-Warning
        }

        if ($ErrorVar.Exception)
        {
            switch ($ErrorVar)
            {
                { $_.Exception.GetType().Name -eq "COMException" }
                {
                    $Msg = "Powershell cmdlet on $Server : RPC server is unavailable"
                    $Msg | Write-Warning

                    break
                }
                { $_.Exception.GetType().Name -eq "ManagementException" }
                {
                    $Msg = "Powershell cmdlet on $Server : user credentials cannot be used for local connections.`nRetrying without credential."
                    $Msg | Write-Warning
                    $Server_Info = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Server | Select Model # when the script is hosted on a computer within the Server_List

                    break
                }
                default
                {
                    $Msg = "Powershell cmdlet on $Server : unexpected error"
                    $Msg | Write-Warning
                }
            }
        }

        if ($Server_Info)
        {
                $Server_Info_Pso =  New-Object PSObject -Property @{
                    HostName = $Server
                    Model = $Server_Info.Model
                }
        }
        else
        {           
            $Server_Info_Pso =  New-Object PSObject -Property @{
                HostName = $Server
                Model = 'Unavailable'
            }
        }

        $Server_Info_PsoCol = $Server_Info_PsoCol + @($Server_Info_Pso)
    }

-错误动作停止,我用它来描述ping。好主意,但是,正如我所认为的,防火墙可以阻止ping,但是wmi请求仍然可以接受。代码中没有错误操作:),无论如何,RPC错误也可能是由防火墙引起的。为此,我们可以通过添加停止来删除辅助函数。-错误操作停止我正在使用它关于ping。好主意,但是,正如我所认为的,防火墙可以阻止ping,但wmi请求仍然可以接受。代码中没有错误操作:),无论如何,RPC错误也可能是由防火墙引起的。为此,我们可以通过添加停止来删除辅助功能。