簡體   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