Code like this,
try { $NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE" }
catch [GetWMICOMException]
{
"Error 1"
}
catch [System.UnauthorizedAccessException]
{
"Error 2"
}
get an error like:
Can't find type [GetWMICOMException]:
catch [COMException] Same
catch [System.Runtime.InteropServices.COMException] just ignored
How can I catch it?
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
First. The error is a non-terminating error, so it just notifies. If you want to catch a non-terminating error, use -ErrorAction Stop
. Also, I don't think COMException
is an exception you can catch. Try this instead:
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"
}
}
You can only catch terminating errors. Add '-ErrorAction Stop' to Get-WmiObject to convert the error to terminating error and try again. On a side note, I would also suggest that you test connectivity to the target system before you run wmi queries against it using a ping request, it can speed up execution especially if you query lots of computers (wmi timeout can slow your script).
try {
$NIC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computername -Credential $Credential -filter "IPEnabled = $TRUE"
}
catch
{
$_
}
I was running into the same issue, and ran across this page. Frode F has the right idea, but I was not satisfied with that answer, so I messed around until I got the behavior that I wanted. I thought I would add a bit in case anyone else runs across this page in the future :
Simpler version that will catch any 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"
}
More complex version that will only catch a COMException if it is the "GetWMICOMException" thrown by Get-WMIObject:
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"
}
I managed to handle any type of errors in ErrorAction mode "SilentlyContinue" using Try{}Catch and -ErrorVariable:
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)
}
User contributions licensed under CC BY-SA 3.0