Цикл по серверам и вывод результатов вместе с ошибками
Я написал простой скрипт 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 красным цветом:
- Get-WmiObject: класс не зарегистрирован (исключение из HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)) В строке:1 символ:12
- 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