Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # GrokPing.ps1, requires 'GrokListener.ps1' be running on target https://pastebin.com/hnQi3k1s
- # Written with the assistance of Grok 3
- # https://x.com/i/grok/share/pfNjEtMQXtkWAGVixxL8UQ9Zv
- # Example output:
- # --- workstation-22 Ping Statistics (Final) ---
- # Packets: Sent = 60, Received = 60, Lost = 0 (0% loss)
- # Round Trip Times: Minimum = 21ms, Maximum = 54.97ms, Average = 33.77ms
- #
- #--- RTT Chart (Min: 21 ms, Max: 54.97 ms, Avg: 33.77 ms) ---
- #54.97 M| *
- # | *
- # | *
- # | *
- # | *
- # | *
- # | * *
- # | * *
- # | * * * * *
- # | * * * * * * *
- # | * * * * * * * * * *
- # | *** * * * *** * * * *
- #33.77 A| *** *** * * * **** * ** ** * *
- # | *** ***** * * * **** * ** ** ** *
- # |******* ****** ** * * * ******* ** ********
- # |******************* ** * ** ******** ************
- # |******************* ******* **********************
- # |******************* ******* **********************
- # |******************* ******************************
- #21.00 L|**************************************************
- #----------------------------------------------------------
- #M=Max, A=Avg, L=Min | Last 60 pings | 60 samples over ~120 seconds
- param (
- [string]$TargetIP = "workstation-22", # Hardcoded target (running GrokListener.ps1)
- [int]$Port = 5000, # Hardcoded port
- [int]$Count = 4, # Number of packets to send (ignored if Persistent is true)
- [int]$TimeoutMs = 1000, # Timeout for each packet in milliseconds
- [int]$DelayMs = 1000, # Delay between packets in milliseconds (default: 1 second)
- [switch]$Persistent, # Enable continuous pinging like ping -t
- [int]$WindowSize = 100, # Number of pings in the sliding window for the chart
- [int]$ChartHeight = 20, # Max height of the chart in rows
- [int]$ChartWidth = 50 # Max width of the chart in characters
- )
- $results = @()
- $sent = 0
- $received = 0
- $lost = 0
- $rttTimes = @() # Stores RTTs for the current window
- # Function to draw ASCII chart with min RTT at bottom, max RTT at top, and time scale
- function Draw-AsciiChart {
- param (
- [double[]]$RTTs,
- [int]$MaxHeight,
- [int]$MaxWidth,
- [int]$DelayMs # Pass DelayMs to calculate time span
- )
- if ($RTTs.Count -eq 0) { return }
- # Calculate min, max, average RTT for the window
- $minRtt = if ($RTTs.Count -gt 0) { [math]::Round(($RTTs | Measure-Object -Minimum).Minimum, 2) } else { 0 }
- $maxRtt = if ($RTTs.Count -gt 0) { [math]::Round(($RTTs | Measure-Object -Maximum).Maximum, 2) } else { 0 }
- $avgRtt = if ($RTTs.Count -gt 0) { [math]::Round(($RTTs | Measure-Object -Average).Average, 2) } else { 0 }
- # If all RTTs are the same, avoid division by zero
- $rttRange = $maxRtt - $minRtt
- if ($rttRange -eq 0) { $rttRange = 1 }
- # Scale RTTs to chart height, mapping minRtt to 1 and maxRtt to MaxHeight
- $scale = ($MaxHeight - 1) / $rttRange
- $minHeight = 1 # Min RTT at the bottom
- $maxHeight = $MaxHeight # Max RTT at the top
- $avgHeight = [math]::Floor(($avgRtt - $minRtt) * $scale) + 1
- $avgHeight = [math]::Min([math]::Max($avgHeight, 1), $MaxHeight)
- # Format RTT values with two-digit precision
- $minLabel = "{0:F2} L" -f $minRtt # e.g., "23.27 L"
- $avgLabel = "{0:F2} A" -f $avgRtt # e.g., "34.67 A"
- $maxLabel = "{0:F2} M" -f $maxRtt # e.g., "42.90 M"
- # Calculate time span for the samples (in seconds)
- $sampleCount = $RTTs.Count
- $timeSpanSeconds = [math]::Round(($sampleCount * $DelayMs) / 1000, 1)
- $timeScaleLabel = "$sampleCount samples over ~$timeSpanSeconds seconds"
- # Draw chart
- Write-Host "`n--- RTT Chart (Min: $minRtt ms, Max: $maxRtt ms, Avg: $avgRtt ms) ---"
- for ($row = $MaxHeight; $row -ge 1; $row--) {
- $line = ""
- if ($row -eq $maxHeight) { $line += $maxLabel.PadRight(6) + "|" }
- elseif ($row -eq $avgHeight) { $line += $avgLabel.PadRight(6) + "|" }
- elseif ($row -eq $minHeight) { $line += $minLabel.PadRight(6) + "|" }
- else { $line += (" " * 7) + "|" }
- for ($col = 0; $col -lt $MaxWidth; $col++) {
- $line += if ($col -lt $RTTs.Count) {
- $rttHeight = [math]::Floor(($RTTs[$col] - $minRtt) * $scale) + 1
- $rttHeight = [math]::Min([math]::Max($rttHeight, 1), $MaxHeight)
- if ($rttHeight -ge $row) { "*" } else { " " }
- } else { " " }
- }
- Write-Host $line
- }
- Write-Host ("-" * ($MaxWidth + 8))
- Write-Host ("M=Max, A=Avg, L=Min | Last $sampleCount pings | $timeScaleLabel")
- }
- Write-Host "Pinging $TargetIP on port $Port..."
- Write-Host "Persistent: $Persistent, Delay: $DelayMs ms, WindowSize: $WindowSize"
- try {
- while ($true) {
- # Break if not persistent and count is reached
- if (-not $Persistent -and $sent -ge $Count) {
- break
- }
- $sent++
- $startTime = Get-Date
- $tcpClient = New-Object System.Net.Sockets.TcpClient
- $tcpClient.ReceiveTimeout = $TimeoutMs
- $tcpClient.SendTimeout = $TimeoutMs
- try {
- # Attempt to connect
- $connectTask = $tcpClient.ConnectAsync($TargetIP, $Port)
- if ($connectTask.Wait($TimeoutMs)) {
- $stream = $tcpClient.GetStream()
- $writer = New-Object System.IO.StreamWriter($stream)
- $reader = New-Object System.IO.StreamReader($stream)
- # Send PING
- $writer.WriteLine("PING")
- $writer.Flush()
- # Wait for response
- $response = $reader.ReadLine()
- if ($response -eq "PONG") {
- $endTime = Get-Date
- $rtt = ($endTime - $startTime).TotalMilliseconds
- $rttTimes += $rtt
- $received++
- Write-Host "Reply from $TargetIP : time=$([math]::Round($rtt, 2))ms"
- $results += [PSCustomObject]@{
- Timestamp = $startTime
- TargetIP = $TargetIP
- Port = $Port
- RTT = [math]::Round($rtt, 2)
- Status = "Success"
- }
- } else {
- $lost++
- Write-Host "No reply from $TargetIP : Request timed out"
- $results += [PSCustomObject]@{
- Timestamp = $startTime
- TargetIP = $TargetIP
- Port = $Port
- RTT = $null
- Status = "Timed out"
- }
- }
- # Clean up
- $writer.Close()
- $reader.Close()
- } else {
- $lost++
- Write-Host "No reply from $TargetIP : Request timed out"
- $results += [PSCustomObject]@{
- Timestamp = $startTime
- TargetIP = $TargetIP
- Port = $Port
- RTT = $null
- Status = "Timed out"
- }
- }
- } catch {
- $lost++
- Write-Host "No reply from $TargetIP : Request timed out"
- $results += [PSCustomObject]@{
- Timestamp = $startTime
- TargetIP = $TargetIP
- Port = $Port
- RTT = $null
- Status = "Timed out"
- }
- } finally {
- $tcpClient.Close()
- }
- # Maintain sliding window
- if ($rttTimes.Count -gt $WindowSize) {
- $rttTimes = $rttTimes[-$WindowSize..-1]
- }
- # Calculate and display interim statistics and chart every 10 packets or on completion
- if ($sent % 10 -eq 0 -or (-not $Persistent -and $sent -eq $Count)) {
- $packetLossPercent = ($lost / $sent) * 100
- $avgRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Average).Average, 2) } else { 0 }
- $minRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Minimum).Minimum, 2) } else { 0 }
- $maxRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Maximum).Maximum, 2) } else { 0 }
- Write-Host "`n--- $TargetIP Ping Statistics (Interim at $sent packets) ---"
- Write-Host "Packets: Sent = $sent, Received = $received, Lost = $lost ($([math]::Round($packetLossPercent, 2))% loss)"
- Write-Host "Round Trip Times: Minimum = ${minRtt}ms, Maximum = ${maxRtt}ms, Average = ${avgRtt}ms"
- # Draw ASCII chart, passing DelayMs
- Draw-AsciiChart -RTTs $rttTimes -MaxHeight $ChartHeight -MaxWidth $ChartWidth -DelayMs $DelayMs
- }
- # Save results to CSV
- $results | Export-Csv -Path "PingResults.csv" -NoTypeInformation -Append
- # Wait before sending the next packet
- Start-Sleep -Milliseconds $DelayMs
- }
- }
- finally {
- # Final statistics and chart on exit
- $packetLossPercent = ($lost / $sent) * 100
- $avgRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Average).Average, 2) } else { 0 }
- $minRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Minimum).Minimum, 2) } else { 0 }
- $maxRtt = if ($rttTimes.Count -gt 0) { [math]::Round(($rttTimes | Measure-Object -Maximum).Maximum, 2) } else { 0 }
- Write-Host "`n--- $TargetIP Ping Statistics (Final) ---"
- Write-Host "Packets: Sent = $sent, Received = $received, Lost = $lost ($([math]::Round($packetLossPercent, 2))% loss)"
- Write-Host "Round Trip Times: Minimum = ${minRtt}ms, Maximum = ${maxRtt}ms, Average = ${avgRtt}ms"
- # Draw final ASCII chart
- Draw-AsciiChart -RTTs $rttTimes -MaxHeight $ChartHeight -MaxWidth $ChartWidth -DelayMs $DelayMs
- }
Advertisement
Add Comment
Please, Sign In to add comment