0

像这样的代码,

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

catch [GetWMICOMException]
{
    "Error 1"
}
catch [System.UnauthorizedAccessException]
{
    "Error 2"
}

收到如下错误:

找不到类型 [GetWMICOMException]:

捕捉 [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
4

4 回答 4

2

第一的。该错误是非终止错误,因此它只是通知。如果要捕获非终止错误,请使用-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"
    }
}
于 2013-01-30T08:32:40.353 回答
2

我遇到了同样的问题,并遇到了这个页面。Frode F 的想法是对的,但我对这个答案并不满意,所以我一直在搞砸,直到得到我想要的行为。我想我会添加一点,以防其他人在未来遇到这个页面:

  • 正如弗罗德所说,您必须使用 -ErrorAction Stop 来捕获此异常,因为它是非终止的
  • 如果使用完全限定名称 [System.Runtime.InteropServices.COMException],则可以捕获 COMException
  • 如果您只想在错误记录显示 GetWMICOMException 时捕获 COMException,就像在 Get-WMIObject 抛出时一样,您可以使用 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"
}

如果它是 Get-WMIObject 抛出的“GetWMICOMException”,则只会捕获 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"
}
于 2014-03-19T00:44:42.087 回答
1

您只能捕获终止错误。将“-ErrorAction Stop”添加到 Get-WmiObject 以将错误转换为终止错误并重试。附带说明一下,我还建议您在使用 ping 请求对其运行 wmi 查询之前测试与目标系统的连接,它可以加快执行速度,尤其是在您查询大量计算机时(wmi 超时会减慢您的脚本)。

try { 
    $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE" 
}
catch
{
    $_
}
于 2013-01-30T08:33:46.093 回答
0

我设法使用 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)
    }
于 2014-07-05T23:53:20.197 回答