Ubidibity

GrokPing.ps1

Jul 29th, 2025 (edited)
593
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PowerShell 10.68 KB | Software | 0 0
  1. # GrokPing.ps1, requires 'GrokListener.ps1' be running on target https://pastebin.com/hnQi3k1s
  2. # Written with the assistance of Grok 3
  3. # https://x.com/i/grok/share/pfNjEtMQXtkWAGVixxL8UQ9Zv
  4. # Example output:
  5. # --- workstation-22 Ping Statistics (Final) ---
  6. # Packets: Sent = 60, Received = 60, Lost = 0 (0% loss)
  7. # Round Trip Times: Minimum = 21ms, Maximum = 54.97ms, Average = 33.77ms
  8. #
  9. #--- RTT Chart (Min: 21 ms, Max: 54.97 ms, Avg: 33.77 ms) ---
  10. #54.97 M|                                                 *
  11. #       |                                                 *
  12. #       |                                                 *
  13. #       |                                                 *
  14. #       |                                                 *
  15. #       |                                                 *
  16. #       |     *                                           *
  17. #       |     *                                           *
  18. #       |     *              *       *              *     *
  19. #       |     *   *   *      *       *              *     *
  20. #       |     *   *   *      *       * *        *   *  *  *
  21. #       |   ***   *   *      *       ***        *   *  *  *
  22. #33.77 A|   ***   *** *      *  *    **** *    **  **  *  *
  23. #       |   ***   *****    * *  *    **** *    **  ** **  *
  24. #       |*******  ******  ** *  * *  *******   **  ********
  25. #       |******************* ** * ** ********  ************
  26. #       |******************* ******* **********************
  27. #       |******************* ******* **********************
  28. #       |******************* ******************************
  29. #21.00 L|**************************************************
  30. #----------------------------------------------------------
  31. #M=Max, A=Avg, L=Min | Last 60 pings | 60 samples over ~120 seconds
  32.  
  33. param (
  34.     [string]$TargetIP = "workstation-22",                   # Hardcoded target (running GrokListener.ps1)
  35.     [int]$Port = 5000,                                      # Hardcoded port
  36.     [int]$Count = 4,                                        # Number of packets to send (ignored if Persistent is true)
  37.     [int]$TimeoutMs = 1000,                                 # Timeout for each packet in milliseconds
  38.     [int]$DelayMs = 1000,                                   # Delay between packets in milliseconds (default: 1 second)
  39.     [switch]$Persistent,                                    # Enable continuous pinging like ping -t
  40.     [int]$WindowSize = 100,                                 # Number of pings in the sliding window for the chart
  41.     [int]$ChartHeight = 20,                                 # Max height of the chart in rows
  42.     [int]$ChartWidth = 50                                   # Max width of the chart in characters
  43. )
  44.  
  45. $results = @()
  46. $sent = 0
  47. $received = 0
  48. $lost = 0
  49. $rttTimes = @()  # Stores RTTs for the current window
  50.  
  51. # Function to draw ASCII chart with min RTT at bottom, max RTT at top, and time scale
  52. function Draw-AsciiChart {
  53.     param (
  54.         [double[]]$RTTs,
  55.         [int]$MaxHeight,
  56.         [int]$MaxWidth,
  57.         [int]$DelayMs  # Pass DelayMs to calculate time span
  58.     )
  59.  
  60.     if ($RTTs.Count -eq 0) { return }
  61.  
  62.     # Calculate min, max, average RTT for the window
  63.     $minRtt = if ($RTTs.Count -gt 0) { [math]::Round(($RTTs | Measure-Object -Minimum).Minimum, 2) } else { 0 }
  64.     $maxRtt = if ($RTTs.Count -gt 0) { [math]::Round(($RTTs | Measure-Object -Maximum).Maximum, 2) } else { 0 }
  65.     $avgRtt = if ($RTTs.Count -gt 0) { [math]::Round(($RTTs | Measure-Object -Average).Average, 2) } else { 0 }
  66.  
  67.     # If all RTTs are the same, avoid division by zero
  68.     $rttRange = $maxRtt - $minRtt
  69.     if ($rttRange -eq 0) { $rttRange = 1 }
  70.  
  71.     # Scale RTTs to chart height, mapping minRtt to 1 and maxRtt to MaxHeight
  72.     $scale = ($MaxHeight - 1) / $rttRange
  73.     $minHeight = 1  # Min RTT at the bottom
  74.     $maxHeight = $MaxHeight  # Max RTT at the top
  75.     $avgHeight = [math]::Floor(($avgRtt - $minRtt) * $scale) + 1
  76.     $avgHeight = [math]::Min([math]::Max($avgHeight, 1), $MaxHeight)
  77.  
  78.     # Format RTT values with two-digit precision
  79.     $minLabel = "{0:F2} L" -f $minRtt  # e.g., "23.27 L"
  80.     $avgLabel = "{0:F2} A" -f $avgRtt  # e.g., "34.67 A"
  81.     $maxLabel = "{0:F2} M" -f $maxRtt  # e.g., "42.90 M"
  82.  
  83.     # Calculate time span for the samples (in seconds)
  84.     $sampleCount = $RTTs.Count
  85.     $timeSpanSeconds = [math]::Round(($sampleCount * $DelayMs) / 1000, 1)
  86.     $timeScaleLabel = "$sampleCount samples over ~$timeSpanSeconds seconds"
  87.  
  88.     # Draw chart
  89.     Write-Host "`n--- RTT Chart (Min: $minRtt ms, Max: $maxRtt ms, Avg: $avgRtt ms) ---"
  90.     for ($row = $MaxHeight; $row -ge 1; $row--) {
  91.         $line = ""
  92.         if ($row -eq $maxHeight) { $line += $maxLabel.PadRight(6) + "|" }
  93.         elseif ($row -eq $avgHeight) { $line += $avgLabel.PadRight(6) + "|" }
  94.         elseif ($row -eq $minHeight) { $line += $minLabel.PadRight(6) + "|" }
  95.         else { $line += (" " * 7) + "|" }
  96.         for ($col = 0; $col -lt $MaxWidth; $col++) {
  97.             $line += if ($col -lt $RTTs.Count) {
  98.                 $rttHeight = [math]::Floor(($RTTs[$col] - $minRtt) * $scale) + 1
  99.                 $rttHeight = [math]::Min([math]::Max($rttHeight, 1), $MaxHeight)
  100.                 if ($rttHeight -ge $row) { "*" } else { " " }
  101.             } else { " " }
  102.         }
  103.         Write-Host $line
  104.     }
  105.     Write-Host ("-" * ($MaxWidth + 8))
  106.     Write-Host ("M=Max, A=Avg, L=Min | Last $sampleCount pings | $timeScaleLabel")
  107. }
  108.  
  109. Write-Host "Pinging $TargetIP on port $Port..."
  110. Write-Host "Persistent: $Persistent, Delay: $DelayMs ms, WindowSize: $WindowSize"
  111.  
  112. try {
  113.     while ($true) {
  114.         # Break if not persistent and count is reached
  115.         if (-not $Persistent -and $sent -ge $Count) {
  116.             break
  117.         }
  118.  
  119.         $sent++
  120.         $startTime = Get-Date
  121.         $tcpClient = New-Object System.Net.Sockets.TcpClient
  122.         $tcpClient.ReceiveTimeout = $TimeoutMs
  123.         $tcpClient.SendTimeout = $TimeoutMs
  124.  
  125.         try {
  126.             # Attempt to connect
  127.             $connectTask = $tcpClient.ConnectAsync($TargetIP, $Port)
  128.             if ($connectTask.Wait($TimeoutMs)) {
  129.                 $stream = $tcpClient.GetStream()
  130.                 $writer = New-Object System.IO.StreamWriter($stream)
  131.                 $reader = New-Object System.IO.StreamReader($stream)
  132.  
  133.                 # Send PING
  134.                 $writer.WriteLine("PING")
  135.                 $writer.Flush()
  136.  
  137.                 # Wait for response
  138.                 $response = $reader.ReadLine()
  139.                 if ($response -eq "PONG") {
  140.                     $endTime = Get-Date
  141.                     $rtt = ($endTime - $startTime).TotalMilliseconds
  142.                     $rttTimes += $rtt
  143.                     $received++
  144.                     Write-Host "Reply from $TargetIP : time=$([math]::Round($rtt, 2))ms"
  145.                     $results += [PSCustomObject]@{
  146.                         Timestamp = $startTime
  147.                         TargetIP = $TargetIP
  148.                         Port = $Port
  149.                         RTT = [math]::Round($rtt, 2)
  150.                         Status = "Success"
  151.                     }
  152.                 } else {
  153.                     $lost++
  154.                     Write-Host "No reply from $TargetIP : Request timed out"
  155.                     $results += [PSCustomObject]@{
  156.                         Timestamp = $startTime
  157.                         TargetIP = $TargetIP
  158.                         Port = $Port
  159.                         RTT = $null
  160.                         Status = "Timed out"
  161.                     }
  162.                 }
  163.  
  164.                 # Clean up
  165.                 $writer.Close()
  166.                 $reader.Close()
  167.             } else {
  168.                 $lost++
  169.                 Write-Host "No reply from $TargetIP : Request timed out"
  170.                 $results += [PSCustomObject]@{
  171.                     Timestamp = $startTime
  172.                     TargetIP = $TargetIP
  173.                     Port = $Port
  174.                     RTT = $null
  175.                     Status = "Timed out"
  176.                 }
  177.             }
  178.         } catch {
  179.             $lost++
  180.             Write-Host "No reply from $TargetIP : Request timed out"
  181.             $results += [PSCustomObject]@{
  182.                 Timestamp = $startTime
  183.                 TargetIP = $TargetIP
  184.                 Port = $Port
  185.                 RTT = $null
  186.                 Status = "Timed out"
  187.             }
  188.         } finally {
  189.             $tcpClient.Close()
  190.         }
  191.  
  192.         # Maintain sliding window
  193.         if ($rttTimes.Count -gt $WindowSize) {
  194.             $rttTimes = $rttTimes[-$WindowSize..-1]
  195.         }
  196.  
  197.         # Calculate and display interim statistics and chart every 10 packets or on completion
  198.         if ($sent % 10 -eq 0 -or (-not $Persistent -and $sent -eq $Count)) {
  199.             $packetLossPercent = ($lost / $sent) * 100
  200.             $avgRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Average).Average, 2) } else { 0 }
  201.             $minRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Minimum).Minimum, 2) } else { 0 }
  202.             $maxRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Maximum).Maximum, 2) } else { 0 }
  203.  
  204.             Write-Host "`n--- $TargetIP Ping Statistics (Interim at $sent packets) ---"
  205.             Write-Host "Packets: Sent = $sent, Received = $received, Lost = $lost ($([math]::Round($packetLossPercent, 2))% loss)"
  206.             Write-Host "Round Trip Times: Minimum = ${minRtt}ms, Maximum = ${maxRtt}ms, Average = ${avgRtt}ms"
  207.  
  208.             # Draw ASCII chart, passing DelayMs
  209.             Draw-AsciiChart -RTTs $rttTimes -MaxHeight $ChartHeight -MaxWidth $ChartWidth -DelayMs $DelayMs
  210.         }
  211.  
  212.         # Save results to CSV
  213.         $results | Export-Csv -Path "PingResults.csv" -NoTypeInformation -Append
  214.  
  215.         # Wait before sending the next packet
  216.         Start-Sleep -Milliseconds $DelayMs
  217.     }
  218. }
  219. finally {
  220.     # Final statistics and chart on exit
  221.     $packetLossPercent = ($lost / $sent) * 100
  222.     $avgRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Average).Average, 2) } else { 0 }
  223.     $minRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Minimum).Minimum, 2) } else { 0 }
  224.     $maxRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Maximum).Maximum, 2) } else { 0 }
  225.  
  226.     Write-Host "`n--- $TargetIP Ping Statistics (Final) ---"
  227.     Write-Host "Packets: Sent = $sent, Received = $received, Lost = $lost ($([math]::Round($packetLossPercent, 2))% loss)"
  228.     Write-Host "Round Trip Times: Minimum = ${minRtt}ms, Maximum = ${maxRtt}ms, Average = ${avgRtt}ms"
  229.  
  230.     # Draw final ASCII chart
  231.     Draw-AsciiChart -RTTs $rttTimes -MaxHeight $ChartHeight -MaxWidth $ChartWidth -DelayMs $DelayMs
  232. }
Advertisement
Add Comment
Please, Sign In to add comment