Powershell - как сортировать UNC-пути по времени отклика ping - PullRequest
1 голос
/ 17 января 2011

Я пытаюсь создать скрипт, который бы давал список общих ресурсов UNC, упорядочив их по времени отклика. Мне удалось придумать что-то, что выглядит как хак, и мне интересно, есть ли у кого-нибудь идея, как сделать это чисто в духе powershell?

Это мое уродливое решение:

$shares = Get-Content unc_shares.txt | where {Test-Path $_}
$servers = $shares | ForEach-Object {$_.Substring(2, $_.IndexOf("\", 3) - 2)}

$sortedServers = ($servers |
  ForEach-Object -Process {(Get-WmiObject Win32_PingStatus -filter "Address='$_'")} |
  sort ResponseTime |
  select Address)

foreach($server in $sortedServers)
{
  $shares | where {$_.Contains($server.Address)} | Out-File $sortedListPath -append
}

Ответы [ 2 ]

4 голосов
/ 17 января 2011

Когда все, что вы хотите сделать, это отсортировать, просто используйте ScriptBlock для сортировки по:

cat .\uncshares.txt | Sort { Test-Connection -Count 1 -CN $_.split('\')[2] }

Или вы можете использовать среднее значение:

cat .\uncshares.txt | Sort { Test-Connection -Count 3 -CN $_.split('\')[2] | Measure ResponseTime -Average | Select -Expand Average }

Это правда, что когда вы хотите добавить данные в объект, вы должны использовать Add-Member. В этом случае вы можете добавить NoteProperty с результатом ping, но более интересно добавить свойство сценария (или метод) с именем ping, которое фактически выполнит ping. То есть он будет выполнять пинг при вызове члена пинга:

$Shares = cat .\uncshares.txt | Add-Member ScriptProperty Ping -Passthru -Value {
            Test-Connection $this.split('\')[2] -Count 1 | 
            Select -Expand ResponseTime }

# Each time you sort by it, it will re-ping, notice the delay:
$Shares | Sort Ping

Вы также можете использовать среднее с этим методом:

$Shares = cat .\uncshares.txt | Add-Member ScriptProperty Ping -Passthru -Value {
            (Test-Connection $this.split('\')[2] -Count 3 | 
             Measure ResponseTime -Average).Average }

# But this will take even longer:
$Shares | Sort Ping

В качестве альтернативы Add-Member (когда вы НЕ хотите каждый раз повторять эхо-запрос), вы можете создавать объекты с помощью Select-Object, чтобы вы могли создать объект Ping и затем добавить имя общего ресурса обратно в это так:

$unc = cat .\uncshares.txt

## Gotta love backslashes in regex. Not...
$unc -replace '\\\\([^\\]+)\\.*','$1' | 
    Test-Connection -Count 1 -CN {$_} | 
    Sort ResponseTime | 
    Select @{n='Server';e={$_.Address}},
           @{n='Share'; e={$unc -match $_.Address}},
           @{n='Ping';  e={$_.ResponseTime}}

Это позволяет вам получать совершенно разные выходные данные, потому что вы комбинируете несколько объектов вместе ...

0 голосов
/ 17 января 2011

Вот «сложенный» однострочный:

   @(foreach ($unc in $list){
      test-connection $unc.split("\")[2] |
       measure responsetime -average |
        % {$_.average.tostring() + " $unc"}}) |
         sort |% {$_.split()[1]}

Если вы хотите сохранить и отобразить ResponseTimes, замените последнюю строку на:

sort | select @{l="Share";e={$_.split()[1]}},@{l="ResponseTime";e={"{0:F2}" -f $_.split()[0]}}
...