Цикл по серверам и вывод результатов вместе с ошибками

Я написал простой скрипт PowerShell для получения списка времени последней загрузки серверов и вывода результатов в виде таблицы. Результаты немедленно отображаются в окне сетки, но приходят к короткой паузе, когда сервер не отвечает на команду get, либо из-за того, что WMI не запущен, либо класс не зарегистрирован. Затем он отображает ошибку в PS и переходит на следующий сервер.

Теперь результаты бесполезны, если в окнах результатов не отображаются "не отвечающие" серверы.

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

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

Тип ошибки отображается в окне PS красным цветом:

  1. Get-WmiObject: класс не зарегистрирован (исключение из HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)) В строке:1 символ:12
  2. Get-WmiObject: сервер RPC недоступен. (Исключение из HRESULT: 0x800706BA) В строке:1 символ:12

Изменить: Как я могу вывести хорошие результаты вместе с именем сервера, если серверы, которые ответили с ошибкой?

2 ответа

Решение

Для достижения желаемого результата вам нужно запросить серверы индивидуально и создать собственный объект, если запрос не удался:

$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
    }
}

Запустите это в цикле

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

Используйте фоновые задания (или что-то подобное) вместо простого цикла, чтобы ускорить проверки, выполняя их параллельно, а не последовательно. Создайте каждую проверку как задание в фоновом режиме и проверяйте выполненные задания в цикле, пока все задания не будут завершены. Соберите выходные данные из выполненных заданий.

Вот полный сценарий, который проходит по серверам, перехватывает непрекращающиеся ошибки и выводит их в окно.

$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
Другие вопросы по тегам