Skip to content

Commit 7f7666b

Browse files
authored
Add network speed and update visibility to reports (#4)
1 parent 06eb3c3 commit 7f7666b

1 file changed

Lines changed: 196 additions & 1 deletion

File tree

SystemTester.ps1

Lines changed: 196 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,135 @@ function Test-Network {
501501
} catch {
502502
Write-Host "Error getting network info" -ForegroundColor Red
503503
}
504+
505+
Test-NetworkSpeed
506+
Test-NetworkLatency
507+
}
508+
509+
function Test-NetworkSpeed {
510+
Write-Host "`n=== Network Speed Test ===" -ForegroundColor Green
511+
512+
$outputLines = @()
513+
$status = "SUCCESS"
514+
$durationMs = 0
515+
516+
# Gather link speed information for active adapters
517+
try {
518+
$adapters = Get-NetAdapter -ErrorAction Stop | Where-Object { $_.Status -eq "Up" }
519+
if ($adapters) {
520+
$outputLines += "Active Link Speeds:"
521+
foreach ($adapter in $adapters) {
522+
$outputLines += " $($adapter.Name): $($adapter.LinkSpeed)"
523+
}
524+
} else {
525+
$outputLines += "Active Link Speeds: No active adapters detected"
526+
}
527+
} catch {
528+
$status = "FAILED"
529+
$outputLines += "Active Link Speeds: Unable to query adapters ($($_.Exception.Message))"
530+
}
531+
532+
# Perform an outbound download test to estimate internet throughput
533+
$tempFile = $null
534+
try {
535+
$testUrl = "https://speed.hetzner.de/10MB.bin"
536+
$tempFile = [System.IO.Path]::GetTempFileName()
537+
Write-Host "Running internet download test (~10MB)..." -ForegroundColor Yellow
538+
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
539+
Invoke-WebRequest -Uri $testUrl -OutFile $tempFile -UseBasicParsing -TimeoutSec 120 | Out-Null
540+
$stopwatch.Stop()
541+
542+
$fileInfo = Get-Item $tempFile
543+
$sizeBytes = [double]$fileInfo.Length
544+
$duration = [math]::Max($stopwatch.Elapsed.TotalSeconds, 0.001)
545+
$sizeMB = [math]::Round($sizeBytes / 1MB, 2)
546+
$mbps = [math]::Round((($sizeBytes * 8) / 1MB) / $duration, 2)
547+
$mbPerSec = [math]::Round(($sizeBytes / 1MB) / $duration, 2)
548+
549+
$outputLines += "Internet Download Test:"
550+
$outputLines += " URL: $testUrl"
551+
$outputLines += " File Size: $sizeMB MB"
552+
$outputLines += " Time: $([math]::Round($duration,2)) sec"
553+
$outputLines += " Throughput: $mbps Mbps ($mbPerSec MB/s)"
554+
$durationMs = [math]::Round($stopwatch.Elapsed.TotalMilliseconds)
555+
} catch {
556+
if ($status -ne "FAILED") { $status = "FAILED" }
557+
$outputLines += "Internet Download Test: Failed - $($_.Exception.Message)"
558+
} finally {
559+
if ($tempFile -and (Test-Path $tempFile)) {
560+
Remove-Item $tempFile -ErrorAction SilentlyContinue
561+
}
562+
}
563+
564+
$script:TestResults += @{
565+
Tool="Network-SpeedTest"; Description="Local link speed and download throughput"
566+
Status=$status; Output=($outputLines -join "`n"); Duration=$durationMs
567+
}
568+
}
569+
570+
function Test-NetworkLatency {
571+
Write-Host "`n=== Network Latency (Test-NetConnection & PsPing) ===" -ForegroundColor Green
572+
573+
$targetHost = "8.8.8.8"
574+
$targetPort = 443
575+
$lines = @("Target: $targetHost:$targetPort")
576+
$status = "SUCCESS"
577+
578+
# Built-in Test-NetConnection results
579+
try {
580+
$tnc = Test-NetConnection -ComputerName $targetHost -Port $targetPort -InformationLevel Detailed
581+
if ($tnc) {
582+
$lines += "Test-NetConnection:"
583+
$lines += " Ping Succeeded: $($tnc.PingSucceeded)"
584+
if ($tnc.PingReplyDetails) {
585+
$lines += " Ping RTT: $($tnc.PingReplyDetails.RoundtripTime) ms"
586+
}
587+
$lines += " TCP Succeeded: $($tnc.TcpTestSucceeded)"
588+
}
589+
} catch {
590+
$status = "FAILED"
591+
$lines += "Test-NetConnection: Failed - $($_.Exception.Message)"
592+
}
593+
594+
# Sysinternals PsPing results
595+
try {
596+
$pspingPath = Join-Path $SysinternalsPath "psping.exe"
597+
if (Test-Path $pspingPath) {
598+
$args = @("-accepteula", "-n", "5", "$targetHost:$targetPort")
599+
Write-Host "Running PsPing latency test..." -ForegroundColor Yellow
600+
$pspingOutput = & $pspingPath $args 2>&1 | Out-String
601+
$lines += "PsPing Summary:"
602+
603+
$average = $null
604+
$minimum = $null
605+
$maximum = $null
606+
foreach ($line in $pspingOutput -split "`r?`n") {
607+
if ($line -match "Minimum = ([\d\.]+)ms, Maximum = ([\d\.]+)ms, Average = ([\d\.]+)ms") {
608+
$minimum = [double]$matches[1]
609+
$maximum = [double]$matches[2]
610+
$average = [double]$matches[3]
611+
}
612+
}
613+
614+
if ($average -ne $null) {
615+
$lines += " Min: $minimum ms"
616+
$lines += " Max: $maximum ms"
617+
$lines += " Avg: $average ms"
618+
} else {
619+
$lines += " Unable to parse latency results"
620+
}
621+
} else {
622+
$lines += "PsPing Summary: psping.exe not found in Sysinternals folder"
623+
}
624+
} catch {
625+
$status = "FAILED"
626+
$lines += "PsPing Summary: Failed - $($_.Exception.Message)"
627+
}
628+
629+
$script:TestResults += @{
630+
Tool="Network-Latency"; Description="Connectivity latency tests"
631+
Status=$status; Output=($lines -join "`n"); Duration=0
632+
}
504633
}
505634

506635
# Test: OS Health
@@ -1067,7 +1196,24 @@ function Test-WindowsUpdate {
10671196

10681197
try {
10691198
$result = $searcher.Search("IsInstalled=0")
1070-
$lines += "Pending: $($result.Updates.Count)"
1199+
$pendingCount = $result.Updates.Count
1200+
$lines += "Pending: $pendingCount"
1201+
1202+
if ($pendingCount -gt 0) {
1203+
$lines += "Pending Updates:"
1204+
$maxList = 10
1205+
for ($i = 0; $i -lt [math]::Min($pendingCount, $maxList); $i++) {
1206+
$update = $result.Updates.Item($i)
1207+
$classification = ($update.Categories | Select-Object -First 1).Name
1208+
if (-not $classification) { $classification = "Unspecified" }
1209+
$lines += " - $($update.Title) [$classification]"
1210+
}
1211+
if ($pendingCount -gt $maxList) {
1212+
$lines += " ... ($($pendingCount - $maxList) additional updates not listed)"
1213+
}
1214+
} else {
1215+
$lines += "Pending Updates: None"
1216+
}
10711217
} catch {
10721218
$lines += "Search failed: $($_.Exception.Message)"
10731219
}
@@ -1171,6 +1317,27 @@ function Generate-Report {
11711317
}
11721318
}
11731319

1320+
$netSpeed = $TestResults | Where-Object {$_.Tool -eq "Network-SpeedTest"} | Select-Object -Last 1
1321+
if ($netSpeed) {
1322+
$cleanReport += ""
1323+
$cleanReport += "NETWORK SPEED:"
1324+
$netSpeed.Output -split "`n" | ForEach-Object { $cleanReport += " $_" }
1325+
}
1326+
1327+
$netLatency = $TestResults | Where-Object {$_.Tool -eq "Network-Latency"} | Select-Object -Last 1
1328+
if ($netLatency) {
1329+
$cleanReport += ""
1330+
$cleanReport += "NETWORK LATENCY:"
1331+
$netLatency.Output -split "`n" | ForEach-Object { $cleanReport += " $_" }
1332+
}
1333+
1334+
$updateInfo = $TestResults | Where-Object {$_.Tool -eq "Windows-Update"} | Select-Object -Last 1
1335+
if ($updateInfo) {
1336+
$cleanReport += ""
1337+
$cleanReport += "WINDOWS UPDATE:"
1338+
$updateInfo.Output -split "`n" | ForEach-Object { $cleanReport += " $_" }
1339+
}
1340+
11741341
# ========================================
11751342
# ENHANCED RECOMMENDATIONS ENGINE
11761343
# ========================================
@@ -1228,6 +1395,34 @@ function Generate-Report {
12281395
}
12291396
}
12301397

1398+
# === NETWORK PERFORMANCE ===
1399+
if ($netSpeed -and $netSpeed.Output -match "Throughput: ([\d\.]+) Mbps") {
1400+
$throughputMbps = [float]$matches[1]
1401+
if ($throughputMbps -lt 25) {
1402+
$recommendations += "• WARNING: Internet throughput appears slow ($throughputMbps Mbps)"
1403+
$recommendations += " → Verify ISP plan and router performance"
1404+
$recommendations += " → Re-test when fewer applications are consuming bandwidth"
1405+
}
1406+
}
1407+
1408+
if ($netLatency -and $netLatency.Output -match "Avg: ([\d\.]+) ms") {
1409+
$avgLatency = [float]$matches[1]
1410+
if ($avgLatency -gt 100) {
1411+
$recommendations += "• NOTICE: High network latency detected (Avg $avgLatency ms)"
1412+
$recommendations += " → Check local network congestion"
1413+
$recommendations += " → Contact ISP if latency persists"
1414+
}
1415+
}
1416+
1417+
if ($updateInfo -and $updateInfo.Output -match "Pending: (\d+)") {
1418+
$pendingUpdates = [int]$matches[1]
1419+
if ($pendingUpdates -gt 0) {
1420+
$recommendations += "• ACTION: $pendingUpdates Windows update(s) pending installation"
1421+
$recommendations += " → Install updates via Settings > Windows Update"
1422+
$recommendations += " → Reboot system after installation completes"
1423+
}
1424+
}
1425+
12311426
# === STORAGE CAPACITY ===
12321427
$storageInfo = $TestResults | Where-Object {$_.Tool -eq "Storage-Overview"}
12331428
if ($storageInfo) {

0 commit comments

Comments
 (0)