# ========================================================= # MAX 网络工具箱 - 网络测速 # 下载测速 / Ping 延迟测试 # ========================================================= $Common = "C:\Setup\windows\lib\common.ps1" if (Test-Path $Common) { . $Common } # ========================================================= # 辅助函数 # ========================================================= function Get-PrimaryIPv4 { try { $route = Get-NetRoute -DestinationPrefix "0.0.0.0/0" -ErrorAction SilentlyContinue | Where-Object { $_.NextHop -ne "0.0.0.0" } | Sort-Object RouteMetric | Select-Object -First 1 if ($route) { $ip = Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $route.InterfaceIndex -ErrorAction SilentlyContinue | Where-Object { $_.IPAddress -notlike "127.*" -and $_.IPAddress -notlike "169.254.*" } | Select-Object -First 1 if ($ip) { return $ip.IPAddress } } } catch {} return "" } function Get-PingTime { param($PingItem) if ($PingItem.PSObject.Properties.Name -contains "Latency") { return [double]$PingItem.Latency } if ($PingItem.PSObject.Properties.Name -contains "ResponseTime") { return [double]$PingItem.ResponseTime } return $null } function Get-SafeName { param([string]$Url) $name = [System.IO.Path]::GetFileName($Url) if ([string]::IsNullOrWhiteSpace($name)) { $name = "custom.dat" } foreach ($c in [System.IO.Path]::GetInvalidFileNameChars()) { $name = $name.Replace($c, "_") } return $name } # ========================================================= # 功能函数 # ========================================================= function Measure-DownloadSpeed { param( [string]$Url, [string]$OutFile ) if ([string]::IsNullOrWhiteSpace($Url)) { Write-Err "URL 不能为空" return } $outDir = Split-Path $OutFile -Parent New-Item -ItemType Directory -Path $outDir -Force | Out-Null Remove-Item $OutFile -Force -ErrorAction SilentlyContinue Write-Section "下载测速" Write-Info "测试地址: $Url" Write-Host "" $start = Get-Date try { Invoke-WebRequest -Uri $Url -OutFile $OutFile -UseBasicParsing -TimeoutSec 180 -ErrorAction Stop } catch { Write-Err "下载失败: $($_.Exception.Message)" return } $end = Get-Date $seconds = ($end - $start).TotalSeconds if (-not (Test-Path $OutFile)) { Write-Err "未生成下载文件,测速失败" return } $bytes = (Get-Item $OutFile).Length Remove-Item $OutFile -Force -ErrorAction SilentlyContinue if ($bytes -le 0 -or $seconds -le 0) { Write-Err "测速数据无效" return } $sizeMB = [Math]::Round($bytes / 1MB, 2) $speedBps = $bytes / $seconds $speedMBps = [Math]::Round($speedBps / 1MB, 2) $speedMbps = [Math]::Round(($speedBps * 8) / 1000000, 2) Write-Host "" Write-Info "文件大小: $sizeMB MB" Write-Info "下载耗时: $([Math]::Round($seconds, 2)) 秒" Write-OK "下载速度: $speedMBps MB/s" Write-OK "带宽估算: $speedMbps Mbps" } function Test-PingTargets { param( [string[]]$Targets, [int]$Count = 4 ) Write-Section "Ping 延迟测试" foreach ($target in $Targets) { Write-Info "目标: $target" try { $pings = Test-Connection -ComputerName $target -Count $Count -ErrorAction Stop $times = @() foreach ($p in $pings) { $time = Get-PingTime -PingItem $p if ($null -ne $time) { $times += $time } } if ($times.Count -eq 0) { Write-Warn "未获取到延迟数据" Write-Host "" continue } $avg = [Math]::Round(($times | Measure-Object -Average).Average, 2) $min = ($times | Measure-Object -Minimum).Minimum $max = ($times | Measure-Object -Maximum).Maximum Write-Info "平均: ${avg}ms 最小: ${min}ms 最大: ${max}ms" if ($avg -lt 20) { Write-OK "评级: 优秀" } elseif ($avg -lt 50) { Write-OK "评级: 良好" } elseif ($avg -lt 100) { Write-Warn "评级: 一般" } else { Write-Err "评级: 较差" } } catch { Write-Err "Ping 失败: $($_.Exception.Message)" } Write-Host "" } } # ========================================================= # 主循环 # ========================================================= do { $ip = Get-PrimaryIPv4 Write-Header "网络测速" if ($ip) { Write-Info "本机 IP: $ip" } Write-Line Write-Section "测速选项" Write-Info "1. 快速测速 10MB" Write-Info "2. 标准测速 50MB" Write-Info "3. 自定义 URL 测速" Write-Info "4. Ping 延迟测试" Write-Info "5. 测试 dl.unvmax.com 连接" Write-Info "0. 退出" Write-Host "" $choice = Read-Host " 请选择" Write-Line switch ($choice) { "1" { Measure-DownloadSpeed ` -Url "https://speed.cloudflare.com/__down?bytes=10485760" ` -OutFile "C:\Setup\temp\speedtest-10mb.dat" Pause-Max } "2" { Measure-DownloadSpeed ` -Url "https://speed.cloudflare.com/__down?bytes=52428800" ` -OutFile "C:\Setup\temp\speedtest-50mb.dat" Pause-Max } "3" { $url = Read-Host " 请输入测试文件 URL" if (-not [string]::IsNullOrWhiteSpace($url)) { $safe = Get-SafeName -Url $url Measure-DownloadSpeed -Url $url -OutFile "C:\Setup\temp\speedtest-$safe" } Pause-Max } "4" { Test-PingTargets -Targets @( "119.29.29.29", "223.5.5.5", "8.8.8.8", "1.1.1.1", "baidu.com", "dl.unvmax.com" ) Pause-Max } "5" { Write-Section "连接测试 dl.unvmax.com:443" try { Test-NetConnection dl.unvmax.com -Port 443 | Out-Host Write-OK "连接测试完成" } catch { Write-Err "测试失败: $($_.Exception.Message)" } Pause-Max } "0" { Write-OK "已退出" break } default { Write-Warn "无效选项" Pause-Max } } } while ($choice -ne "0")