PowerShell for Windows Admins

Jan 27 2015   1:47PM GMT

WMI errors

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tags:
Powershell
WMI

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

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: