Powershell - 如何按 ping 响应时间对 UNC 路径进行排序

发布于 2024-10-12 14:47:30 字数 575 浏览 1 评论 0原文

我正在尝试编写一个脚本,给出 UNC 共享列表,并按 ping 响应时间对它们进行排序。 我设法想出了一些感觉很像黑客的东西,我想知道是否有人有更好的想法如何纯粹以“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
}

I'm trying to make a script that would given a list of UNC shares order them by their ping response time.
I've managed to come up with something that feels quite like a hack and I'm wondering if anyone has any better idea how to do it purely in "powershell spirit"?

This is my ugly solution:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

网名女生简单气质 2024-10-19 14:47:30

当您只想排序时,只需使用 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。在这种情况下,您可以添加一个包含 ping 结果的 NoteProperty,但更有趣的是添加名为 ping 的脚本属性(或方法),该属性将实际执行 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 的替代方案(当您不想每次都重新 ping 时),您可以建立使用 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}}

这允许您获得截然不同的输出,因为您将多个对象组合在一起......

When all you want to do is sort, just use a ScriptBlock to sort by:

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

Or, you could use an average:

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

It's true that when you want to add data to an object, you should use Add-Member. In this case, you could add a NoteProperty with the result of the ping, but it's more interesting to add script property (or method) called ping that would actually execute the ping. That is, it will do the ping when you call the ping member:

$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

You can use the average with this method too:

$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

As an alternative to Add-Member (when you do NOT want to re-ping every time), you can build up objects using Select-Object, so you could create a Ping object, and then add the Share name back to it like so:

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

That allows you to have drastically different output because you're combining multiple objects together...

断念 2024-10-19 14:47:30

这是一个“折叠”的单行:

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

如果您想保存并显示响应时间,请将最后一行替换为:

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

Here's a "folded" one-liner:

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

If you want to save and display the ResponseTimes, replace that last line with:

sort | select @{l="Share";e={$_.split()[1]}},@{l="ResponseTime";e={"{0:F2}" -f $_.split()[0]}}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文