Loop through servers and output results along with errors


I wrote a simple PowerShell script to retrieve a list of servers' last boot time and output the results to grid view. The results are immediately shown in the grid window but and comes to a short pause whenever a server is not responding to the get command, either due to WMI not running or class not registered. It then displays the error in PS and move to the next server.

Now, the results aren't helpful unless the "not responding" servers are shown in the results windows.

$servers = ('serverx','serverb')

Get-WmiObject -Class Win32_OperatingSystem -ComputerName $servers |
    select csname, @{LABEL='LastBootUpTime';EXPRESSION={$_.ConvertToDateTime($_.LastBootupTime)}},
        @{LABEL='UpTime';EXPRESSION={(Get-Date) - $_.ConvertToDateTime($_.LastBootupTime)}},
        @{LABEL='OS';EXPRESSION={$_.Caption}} |

Errors type shown in PS window in Red:

  1. Get-WmiObject : Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)) At line:1 char:12
  2. Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) At line:1 char:12

Edit: How do I can i output the good results along with the server name if the servers that responded with an error?

asked on Stack Overflow Mar 21, 2018 by Laurent • edited Mar 21, 2018 by Laurent

2 Answers


For your desired result you need to query the servers individually and construct a custom object if the query fails:

$svr = 'serverx'
try {
    Get-WmiObject Win32_OperatingSystem -Computer $svr -EA Stop |
        select csname, @{n='LocalTime';e={...}},
            @{n='UpTime';e={...}}, @{n='OS';e={...}}
} catch {
    New-Object -Type PSObject -Property @{
        csname    = $svr
        LocalTime = $null
        UpTime    = $null
        OS        = $null

Run this in a loop

$servers | ForEach-Object {
} | Out-GridView

Use background jobs (or something similar) instead of a plain loop to speed up the checks by running them in parallel rather than sequentially. Spawn each check as a job in the background and check for completed jobs in a loop until all jobs have completed. Collect the output from completed jobs.

answered on Stack Overflow Mar 21, 2018 by Ansgar Wiechers • edited Mar 22, 2018 by Ansgar Wiechers

Here is the full script that loops through the servers, catches non-terminating error and output to a window.

$svr = ('localhost','fail')

$Output = Foreach ($server in $svr)  
try {
  Get-WmiObject Win32_OperatingSystem -ComputerName $server -EA STOP |
        select csname, @{n='LocalTime';e={$_.ConverttoDateTime($_.lastbootuptime)}},
            @{n='UpTime';e={....}}, @{n='OS';e={"...."}} 
} catch {
    New-Object -Type PSObject -Property @{
        Csname    = $server
        LocalTime = $null
        UpTime    = $null
        OS        = "Error" #$null


$output | Out-GridView
answered on Stack Overflow Mar 22, 2018 by Laurent

User contributions licensed under CC BY-SA 3.0