繁体   English   中英

PowerShell 测试-连接-高效方法

[英]PowerShell Test-Connection -efficient Method

一枚铜牌 = Newbi,多年来一直在这个网站上搜索,所以一百万迟来的感谢,再次!

刚刚完成了几个不同的 PowerShell 5.1 版脚本,它们定期在相同的 2000 台设备上执行测试连接。

输出到 csv 文件

而且它们都很慢,在将其调整到最基本的部分时,速度会有所提高。

我已将脚本缩放到最小,仅 IPADDRESS 和 NAME

我已经对一个批处理文件(ping 123.456.789.001 >> PingTest.txt)进行了一些比较测试,这些测试似乎比我的 PS 脚本运行得更快(明天将运行一个完整的苹果对苹果的测试),但有信心的是PS代码中的错误。

我正在查看 arrays 以及管道的工作原理,但恐怕我把车放在马前了,或者 PS 如何处理 csv 格式和/或 ZCD69B4957F016CD818DZB3FED6 中的 ping 列表有什么问题

下面是我最有效的当前脚本,

以下链接是否指向正确的方向? 特别是 asJob 开关

PowerShell 批量测试连接


$info = "" | Select IPaddress,Name
$OutputFile = new-item -itemType File -path  C:\Temp\Results.csv -force -value "IPaddress,Name`r`n" | out-null
 
Import-csv C:\Temp\GetList.csv | ForEach-Object {
if ($_.IPaddress) {
 
if (-Not (Test-Connection -ComputerName $_.IPaddress -Quiet -Count 2 -ErrorAction SilentlyContinue)) {
$info.IPaddress = $_.IPaddress
$info.Name = $_.Name

add-content -value "$($info.IPaddress),$($info.Name)"  -path C:\Temp\Results.CSV
}
}
} 

export-csv 更快,谢谢。 我不确定我是否将它放在正确的位置,但它可以工作,明天将对其进行一些测试。 不过,我可能必须包括通过测试,但我仍然对 get-job cmdlet 有所了解。

$info = "" | Select IPaddress,Name,Status

Import-csv c:\Temp\GetList.csv | ForEach-Object {
if($_.Ipaddress) {

if (-Not(Test-Connection -ComputerName $_.IPaddress -Quiet -Count 2 -ErrorAction SilentlyContinue)) {

$info.IPaddress = $_.IPaddress
$info.Name = $_.Name
$info.Status = "Failed"
$info | export-csv C:\Temp\Results1.csv -Force -Notypeinformation -Append
}
}
}
$list = Import-Csv C:\Temp\GetList.csv
ForEach ($item In $list) {
  Start-Job -ScriptBlock {
    param($item)
    if (Test-Connection -Computername $item.IPaddress -Quiet -Count 1) {
      Add-Content -value "$($item.IPaddress),$($item.Name),$($item.Stauts)" -Path C:\Temp\xlistlist.csv
      $list | Export-csv c:\Temp\xCSvreults.csv -Force -NoTypeInformation -Append
    }
  } -argumentlist $list
}

谢谢圣地亚哥,我在这里做了一些探索,只是没时间了。 感谢您提供的代码示例,他们为我清除了一些问题:-) – 12 月 2 日 3:59 有计算机

您介意添加一些内联评论,以便我可以跟进吗? 只是试着更好地理解多线程(使用运行空间)。 – 亚伯拉罕·齐纳拉 12 月 2 日 4:58 1

@AbrahamZinala 是否有您难以理解的特定部分? 我不是这方面的专家,也不想提供虚假信息。 可能会更好地拿起所有你不理解的部分并提出一个新问题 – Santiago Squarzon 12 月 2 日 12:19

不,伙计,对不起,我想通了哈哈 - 亚伯拉罕 Zinala 12 月 2 日 13:43 1

@AbrahamZinala 唯一难以理解的部分是 [powershell] 实例部分 imo,您可以将其视为 Start-Job,但速度更快且 memory 消耗更少,您可以使用 .AddScript({...}) 添加脚本块然后是带有.AddParameters([hashtablehere]) 的参数。 将 PSInstance 保存在一个变量中很重要,这样我们就可以从中获取 output 并且它的处理程序 (Status = $psinstance.BeginInvoke()) 知道实例何时完成。 rest 只是纯蓝图,一旦你有一个你可以复制粘贴它:P – Santiago Squarzon 12 月 2 日 13:50

@HaveComputer 我不知道你的评论是什么意思。 – Santiago Squarzon 12 月 5 日 1:10 提出的 2 个解决方案工作得更快,但是我的代码缺少。 – 12 月 5 日 1:16 有电脑

@HaveComputer 我知道,根据硬件和带宽,这可以快 50 倍甚至更多。 ——圣地亚哥中队

这是一个可以使用运行空间的好地方,我很想测试Test-Connection -AsJob 性能是否比这更好,但由于某种原因,它在 Linux 的 PS Core 上不可用。

下面的代码使用我的专用网络 IP 范围扫描 254 个 IP 大约需要 10 秒。 可以进行很多调整,即您可以围绕$Threshold变量进行调整,它当前一次运行 100 个运行空间, Test-ConnectionCountTimeoutSeconds已设置为2 ,您也可以对其进行调整。

$results变量可以使用Export-Csv

# Change this value for tweaking
$Threshold = 100
$RunspacePool = [runspacefactory]::CreateRunspacePool(1, $Threshold)
$RunspacePool.Open()

# This is for testing, use your CSV here instead
# => $list = Import-Csv C:\Temp\GetList.csv
$list = 1..254 | ForEach-Object {
    [pscustomobject]@{
        IPAddress = "192.168.1.$_"
        Hostname = "ExampleHost$_"
    }
}

$scriptBlock = {
    param($ip, $hostname)

    $params = @{
        Quiet = $true
        Count = 2
        TimeoutSeconds = 2
        ComputerName = $ip
    }

    $status = Test-Connection @params

    [pscustomobject]@{
        Hostname = $hostname
        IPAddress = $ip
        Status = ('Failed','Success')[[int]$status]
    }
}

$runspaces = foreach($line in $list)
{
    $params = @{
        ip = $line.IPAddress
        hostname = $line.Hostname
    }

    $psinstance = [powershell]::Create().AddScript($scriptBlock).AddParameters($params)
    $psinstance.RunspacePool = $RunspacePool
    
    [pscustomobject]@{
        Instance = $psinstance
        Status = $psinstance.BeginInvoke()
    }
}

while($runspaces.Status.IsCompleted -contains $false)
{
    Start-Sleep -Milliseconds 500
}

$results = $runspaces.ForEach({ $_.Instance.EndInvoke($_.Status) })
$RunspacePool.Dispose()

$results示例:

Hostname       IPAddress     Status
--------       ---------     ------
ExampleHost1   192.168.1.1   Success
ExampleHost2   192.168.1.2   Failed
ExampleHost3   192.168.1.3   Success
ExampleHost4   192.168.1.4   Failed
ExampleHost5   192.168.1.5   Success
ExampleHost6   192.168.1.6   Failed
ExampleHost7   192.168.1.7   Failed
ExampleHost8   192.168.1.8   Failed
ExampleHost9   192.168.1.9   Failed
ExampleHost10  192.168.1.10  Failed
...
...
Start-Job -ScriptBlock { Test-Connection -computername  (Get-Content -Path “C:\Temp\GetList.csv”) }
~~~

its lacking the fundamentals, works, DE fast, thank you gent's 

仍在处理我的代码,我确实发现这个读取正在处理它,运行空间读取。

https://devblogs.microsoft.com/scripting/beginning-use-of-powershell-runspaces-part-1/

有趣,有点长,所以我推荐一种饮料:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM