Скрипт Powershell: создание цикла для ResponseTime
У меня возникла проблема с тем, как мои результаты пинга "выкатились" на экран. Я использую этот код:
$servers = "192.168.2.10","192.168.2.80","192.168.2.254"
$collection = $()
foreach ($server in $servers)
{
$status = @{ "ServerName" = $server; "TimeStamp" = (Get-Date -f s) }
$testconnection = (Test-Connection $server -Count 1 -ea 0)
$response = ($testconnection | select ResponseTime)
if ($response)
{
$status["Results"] = "Up"
$status["Responsetime"] = $response
}
else
{
$status["Results"] = "Down"
}
New-Object -TypeName PSObject -Property $status -OutVariable serverStatus
$collection += $serverStatus
}
$collection | Export-Csv -Path ".\ServerStatus.csv" -NoTypeInformation
Я хотел бы создать цикл для ResponseTime. Код, который я использую сейчас, дает один ответ. Когда я даю счет 2, он печатает ResponseTime рядом с каждым IP-адресом.
Выход:
TimeStamp Responsetime Results ServerName
--------- ------------ ------- ----------
2014-10-22T23:30:17 {@{ResponseTime=6}, @{ResponseTime=4}} Up 192.168.2.10
2014-10-22T23:30:18 Down 192.168.2.80
2014-10-22T23:30:25 {@{ResponseTime=1}, @{ResponseTime=3}} Up 192.168.2.254
То, что я хочу, это чтобы скрипт печатал каждый ResponseTime под друг другом так:
TimeStamp Responsetime Results ServerName
--------- ------------ ------- ----------
2014-10-22T23:11:50 @{ResponseTime=419} Up 192.168.2.10
2014-10-22T23:11:51 @{ResponseTime=415} Up 192.168.2.10
2014-10-22T23:11:51 Down 192.168.2.80
2014-10-22T23:11:52 @{ResponseTime=470} Up 192.168.2.254
2014-10-22T23:11:52 @{ResponseTime=7} Up 192.168.2.254
Или вот так:
TimeStamp Responsetime Results ServerName
--------- ------------ ------- ----------
2014-10-22T23:11:50 @{ResponseTime=419} Up 192.168.2.10
2014-10-22T23:11:51 Down 192.168.2.80
2014-10-22T23:11:51 @{ResponseTime=415} Up 192.168.2.254
2014-10-22T23:11:52 @{ResponseTime=470} Up 192.168.2.10
2014-10-22T23:11:51 Down 192.168.2.80
2014-10-22T23:11:52 @{ResponseTime=7} Up 192.168.2.254
Неважно, какой из них, я предпочитаю второй
Не могли бы вы помочь мне с этим вопросом. Даже если это невозможно, скажи мне тоже.
Спасибо Крис
3 ответа
Я перезвоню позже, не потому что другой ответ неверен в любом случае, они оба функциональны, но тем более, что никто не указал, что вы воссоздаете колесо.
Вы проверяете соединение и указываете на него ошибку, которая продолжает молча, оставляя вашу переменную нулевой. Затем вы должны проверить, имеет ли переменная результаты, и обработать ее одним способом, или она не обрабатывает другим способом. То, что вы только что сделали, - это ваш собственный сценарий Try/Catch. Если вы действительно используете ошибку для остановки, вы можете использовать встроенный Try/Catch. Рассмотрим этот подход:
$servers = "www.google.com","localhost","www.amazon.com"
$collection = @()
foreach ($server in $servers)
{
Try{
$testconnection = Test-Connection $server -Count 2 -ErrorAction Stop
$testconnection | ForEach{$collection += New-Object PSObject -Property ([ordered]@{
'TimeStamp' = Get-Date -Format s
'Server' = $server
'ResponseTime' = $_.responsetime
'Results' = 'Up'})
}
}
Catch{
$collection += New-Object PSObject -Property ([ordered]@{
'TimeStamp' = Get-Date -Format s
'Server' = $server
'ResponseTime' = $null
'Results' = 'Unreachable'
})
}
}
$collection #| Export-Csv -Path ".\ServerStatus.csv" -NoTypeInformation
Он пытается пропинговать сервер и, если может, добавляет пользовательский объект в массив $collection с нужной информацией. Если эхо-запрос не выполняется, он также добавляет объект в $collection, показывающий, что сервер недоступен.
Кроме того, у вас было $collection = $()
, Я предполагаю, что вы пытались создать пустой массив, что сделано правильно $collection = @()
(исправлено в предложенном мной коде). Теперь я прокомментировал Export-CSV, чтобы увидеть результаты. Вот что я увидел:
TimeStamp Server ResponseTime Results
--------- ------ ------------ -------
2014-10-22T17:54:22 www.google.com 9 Up
2014-10-22T17:54:22 www.google.com 12 Up
2014-10-22T17:54:23 localhost 0 Up
2014-10-22T17:54:23 localhost 0 Up
2014-10-22T17:54:27 www.amazon.com Unreachable
Амазон не позволил мне пропинговать его, поэтому он показывает, что он недоступен.
Переходя к тому, почему ваши желаемые результаты непрактичны... То, что вы описываете, показывает, как вы пингуете свои серверы и получаете результаты от них в непоследовательное время. Для этого вам придется сделать -count 1
и дважды выполните цикл ForEach, чтобы он пропинговал сервер 1 для 1 результата, затем сервер 2 для 1 результата, затем сервер 3 для 1 результата. Затем он возвращается и проверяет сервер 1 для второго результата, затем сервер 2 для второго результата, а затем сервер 3 для второго результата. Я полагаю, что если вы хотите сделать это, то это даст желаемые результаты, вам нужно будет сделать что-то вроде этого:
$servers = "www.google.com","localhost","www.amazon.com"
$collection = @()
$count = 2
for($i=1;$i -le $count;$i++){
ForEach($server in $servers){
do stuff to ping servers as described above, except change -count to 1
}
}
$collection | export-CSV '.\ServerStatus.csv' -notype
Это даст вам желаемые результаты, но это медленнее. Если вам придется запускать это на нескольких серверах, это будет заметно медленнее. Только для этих трех перечисленных серверов весь процесс прошел путь от 3,7240945 секунд до 7,6104075 секунд (примерно вдвое).
Вместо
$response = ($testconnection | select ResponseTime)
if ($response)
{
$status["Results"] = "Up"
$status["Responsetime"] = $response
}
делать
if($testconnection)
{
$testconnection | % {
$status = @{"ServerName" = $server; "TimeStamp" = (Get-Date -f s); "Results" = "Up"; "Responsetime"= $_.responsetime};
New-Object -TypeName PSObject -Property $status -OutVariable serverStatus;
$collection += $serverStatus }
}
else
{
$status = @{"ServerName" = $server; "TimeStamp" = (Get-Date -f s); "Results" = "Down"};
New-Object -TypeName PSObject -Property $status -OutVariable serverStatus;
$collection += $serverStatus
}
Проблема в том, что $testconnection
или в вашем случае $response
это массив, если количество Test-Connection
больше 1, поэтому вы должны пройтись по нему и добавить отдельные записи в свою коллекцию.
Кроме того, чтобы получить значение вместо тарабарщины, которую вы получаете, вы должны позвонить .responsetime
имущество.
В надежде, что я не усложняю, я представляю это решение.
$servers = "10.50.10.100","8.8.8.8","169.254.54.1"
$servers | ForEach-Object{
$server = $_
$timeStamp = (Get-Date -f s)
$testconnection = Test-Connection $server -Count 2 -ErrorAction 0
If(!$testconnection){
$props = @{
Server = $server
TimeStamp = $timeStamp
ResponseTime = ""
Results = "Down"
}
New-Object -TypeName PSObject -Property $props
} Else {
$testconnection | ForEach-Object{
$_ | Select-Object @{l='Server';e={$server}},@{l='TimeStamp';e={$timeStamp}},@{l='ResponseTime';e={$_.ResponseTime}},@{l='Results';e={"Up"}}
}
}
} | Export-Csv -Path ".\ServerStatus.csv" -NoTypeInformation
Итак, ваша логика все еще здесь, но, как вы можете видеть, некоторые вещи были изменены. Пол был прав, в том, что вам нужно было зацикливаться на каждом ResponseTime
элемент у вас был. Я также сделал это, но с другим подходом, который, если не сказать больше, покажет вам некоторые возможности PowerShell. Нарушение кода
- труба
$servers
вForEach-Object
, ForEach in работает нормально, но я хотел пропустить сохранение переменных и просто выводить их прямо вExport-CSV
вот почему я изменил это. - Так что если вы используете
Test-Connection
на сервере, который не существует или по какой-либо причине возникают ошибки, вам нужно создать объект для его представления. Используя нужные свойства, создайте объект с необходимыми значениями. Это вывод на канал вместо использования временной переменной. - Если проверка соединения прошла успешно, нам нужно вывести число или переменные, соответствующие количеству возвратов.
- Продолжая с № 3, мы используем
Select-Object
для вывода желаемых значений. Я стою за метку, а е за выражение. Да, вы можете просто использовать другую переменную $ props. Просто иллюстрирую еще один вариант. - Так как мы изменили
ForEach
на первом этапе мы можем просто вывести прямо вExport-CSV
Образец вывода
Server TimeStamp ResponseTime Results
------ --------- ------------ -------
10.50.10.100 2014-10-22T20:22:01 0 Up
10.50.10.100 2014-10-22T20:22:01 0 Up
8.8.8.8 2014-10-22T20:22:02 43 Up
8.8.8.8 2014-10-22T20:22:02 39 Up
169.254.54.1 2014-10-22T20:22:03 Down