2014-10-22 2 views
1

У меня возникла проблема с тем, что мои результаты ping «катятся» на экране. Я использую этот код:Скрипт 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 

, который пытается свистеть сервер, и если он может это добавляет пользовательский объект в массив $ сбора с требуемой информацией. Если ping не удается, он также добавляет объект в коллекцию $, показывающую, что сервер недоступен.

Кроме того, у вас было $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 

Amazon не дал мне свистеть, поэтому он показывает как недостижимый.

Перейдем к вопросу о том, почему ваши желаемые результаты нецелесообразны ... Что вы описываете, показывает, что вы пинговали свои серверы и получаете результаты от них в течение нескольких раз. Для этого вам нужно будет сделать -count 1 и пропустить цикл ForEach дважды, так что он будет пинговать сервер 1 для 1 результата, затем сервер 2 для 1 результата, а затем сервер 3 для 1 результата. Затем он вернется и сервер ping 1 для второго результата, затем второй сервер для второго результата, а затем сервер 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 секунд (примерно вдвое).

+0

wow cpt очевидно для спасения :) как я об этом не думал – Paul

+0

Оба работают нормально. Я нашел этот скрипт где-то в Интернете. И отредактировал мои собственные предпочтения. Я плохо разбираюсь в сценариях. Но спасибо за поддержку – coachrules

1

Вместо

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

+0

Paul, я не знаю, как (я плохо разбираюсь в сценариях), но когда я попробую ваш. Я получаю двойной результат, даже счет 1. – coachrules

0

В надежде я не сделал это слишком сложно, я представляю это решение

$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, который у вас был. Я также сделал это, но с другим подходом, который, если ничего другого, покажет вам некоторые из Power in PowerShell. A разбить код

  1. Труба $servers в ForEach-Object. ForEach в работах отлично, однако я хотел пропустить сохранение переменных и просто вывести прямо на Export-CSV, поэтому я его и сменил.
  2. Итак, если вы используете Test-Connection на сервере, который по какой-либо причине не существует или ошибки, вам необходимо создать объект для его представления. Используя желаемые свойства, создайте объект с требуемыми значениями. Это выводится на трубу вместо использования временной переменной.
  3. Когда проверка соединения прошла успешно, нам нужно вывести число или переменные в соответствии с количеством возвратов.
  4. Продолжая с № 3, мы используем Select-Object для вывода желаемых значений. l обозначать ярлык и e для выражения.Да, вы можете просто использовать другую переменную $ props. Просто проиллюстрируем другой вариант.
  5. Поскольку мы изменили 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 
Смежные вопросы