WMI errors

Most PowerShell users will have done something like this:

£> Get-WmiObject -ClassName Win32_ComputerSystem
Domain              : WORKGROUP
Manufacturer        : Microsoft Corporation
Model               : Surface Pro 2
Name                : RSSURFACEPRO2
PrimaryOwnerName    :
TotalPhysicalMemory : 8506093568

Or you can use a computername to access a remote system

£> $computer = $env:COMPUTERNAME
£> Get-WmiObject -ClassName Win32_ComputerSystem -ComputerName $computer

Domain              : WORKGROUP
Manufacturer        : Microsoft Corporation
Model               : Surface Pro 2
Name                : RSSURFACEPRO2
PrimaryOwnerName    :
TotalPhysicalMemory : 8506093568

But if you try to access a remote machine that doesn’t exist

£> $computer = ‘WillNotBeFound’
£> Get-WmiObject -ClassName Win32_ComputerSystem -ComputerName $computer
Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At line:1 char:1
+ Get-WmiObject -ClassName Win32_ComputerSystem -ComputerName $computer
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

 

You’ve heard of try – catch  so you do something like this

$computer = ‘WillNotBeFound’

try {
  Get-WmiObject -ClassName Win32_ComputerSystem -ComputerName $computer -ErrorAction Stop
}
catch {
  Write-Warning “An error occurred”
}

OR your catch may do something to record the error.

$computer = ‘WillNotBeFound’

try {
  Get-WmiObject -ClassName Win32_ComputerSystem -ComputerName $computer -ErrorAction Stop
}
catch {
  Write-Warning “An error occurred for machine: $computer”
}

If you make the warning message specific

$computer = ‘WillNotBeFound’

try {
  Get-WmiObject -ClassName Win32_ComputerSystem -ComputerName $computer -ErrorAction Stop
}
catch {
  Write-Warning “The RPC server is unavailable for machine: $computer”
}

What happens if you have a different error. Lets say you copy the code and change the class. You test the code

$computer = $env:COMPUTERNAME

try {
  Get-WmiObject -ClassName Win32_LogicalDsik -ComputerName $computer -ErrorAction Stop
}
catch {
  Write-Warning “The RPC server is unavailable for machine: $computer”
}

And get a message

WARNING: The RPC server is unavailable for machine: RSSURFACEPRO2

What you should see is

Get-WmiObject : Invalid class “Win32_LogicalDsik”
At line:1 char:1
+ Get-WmiObject -ClassName Win32_LogicalDsik -ComputerName $computer
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidType: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

 

Because the class is mistyped.

You could try and create a number of catch statements – one for each error type.  Good luck with that. Its a lot of work.  A better approach, in my mind is to extract the error information you need

$computer = $env:COMPUTERNAME

try {
  Get-WmiObject -ClassName Win32_LogicalDsik -ComputerName $computer -ErrorAction Stop
}
catch {
$errordata = @”
  Computer = $computer
  Exception = $($error[0].Exception)
  ErrorId = $($error[0].FullyQualifiedErrorId)
“@
 
  Write-Warning $errordata
}

If you look in the PowerShell automatic variable $error – you’ll find its a collection of error messages.  $error[0] contains the last error.  So now you get

£> $computer = $env:COMPUTERNAME

try {
  Get-WmiObject -ClassName Win32_LogicalDsik -ComputerName $computer -ErrorAction Stop
}
catch {
$errordata = @”
  Computer = $computer
  Exception = $($error[0].Exception)
  ErrorId = $($error[0].FullyQualifiedErrorId)
“@
 
  Write-Warning $errordata
}

WARNING:   Computer = RSSURFACEPRO2
  Exception = System.Management.ManagementException: Invalid class “Win32_LogicalDsik”
  ErrorId = GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

 

For a set of computers

$computers = $env:COMPUTERNAME, ‘WillNotBefound’

foreach ($computer in $computers){
try {
  Get-WmiObject -ClassName Win32_computersystem -ComputerName $computer -ErrorAction Stop
}
catch {
$errordata = @”
  Computer = $computer
  Exception = $($error[0].Exception)
  ErrorId = $($error[0].FullyQualifiedErrorId)
“@
 
  Write-Warning $errordata
}
}

You get the data where you can contact the machine – otherwise a warning message that the server is unavailable.  Rather than outputting a warning message create an object from the error data and save to a CSV file

Advertisements
This entry was posted in PowerShell and WMI. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s