Загрузка данных
# 1. Полный обход ошибок SSL/TLS и сертификатов
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$logPath = "$env:USERPROFILE\Desktop\network_6hours_test.txt"
$stats = @{}
# Исключительно легитимные и доступные в РФ ресурсы (DNS, CDN, медиа, ритейл)
$targets = @(
# Публичные DNS (надежный базовый тест связности)
'8.8.8.8', '1.1.1.1', '77.88.8.8',
# Крупнейшие отечественные экосистемы и сервисы
'yandex.ru', 'vk.com', 'mail.ru', 'dzen.ru', 'rutube.ru', 'ok.ru', '2gis.ru', 'kinopoisk.ru',
# Торговые площадки и ритейл (с префиксом www для корректного SSL)
'www.ozon.ru', 'www.wildberries.ru', 'www.avito.ru', 'dns-shop.ru', 'citilink.ru',
# Провайдеры и инфраструктурные узлы
'mts.ru', 'megafon.ru', 'beeline.ru', 'rostelecom.ru', 'selectel.ru'
)
foreach ($t in $targets) {
$stats[$t] = [PSCustomObject]@{ Sent = 0; Lost = 0; Times = [System.Collections.Generic.List[int]]::new() }
}
$startTime = Get-Date
$durationHours = 6
$endTime = $startTime.AddHours($durationHours)
$speeds = [System.Collections.Generic.List[double]]::new()
Write-Host "ТЕСТ ЗАПУЩЕН НА $durationHours ЧАСОВ (до $($endTime.ToString('HH:mm:ss')))" -ForegroundColor Cyan
Write-Host "Лог сохранится на Рабочий стол: $logPath`n" -ForegroundColor Yellow
while ((Get-Date) -lt $endTime) {
$now = Get-Date -Format 'HH:mm:ss'
# Замер чистой скорости через нейтральный CDN Selectel
$speedMbps = 0
$swSpeed = [System.Diagnostics.Stopwatch]::StartNew()
try {
$wc = New-Object System.Net.WebClient
$data = $wc.DownloadData("https://speedtest.selectel.ru/10MB")
$swSpeed.Stop()
if ($swSpeed.ElapsedMilliseconds -gt 0) {
$speedMbps = [math]::Round((($data.Length * 8) / 1000000) / ($swSpeed.ElapsedMilliseconds / 1000), 2)
$speeds.Add($speedMbps)
}
} catch { $swSpeed.Stop() }
Write-Host "=== ОПРОС [$now] | СКОРОСТЬ КАНАЛА: $speedMbps Мбит/с ===" -ForegroundColor Cyan
foreach ($target in $targets) {
$item = $stats[$target]
$url = if ($target -match '^\d+\.\d+\.\d+\.\d+$') { "http://$target" } else { "https://$target" }
$currentLost = 0
$currentTimes = @()
for ($i = 0; $i -lt 3; $i++) {
$item.Sent++
$sw = [System.Diagnostics.Stopwatch]::StartNew()
try {
$req = [System.Net.HttpWebRequest]::Create($url)
$req.Timeout = 2500
$req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
$req.Method = "GET"
$req.AllowAutoRedirect = $false
$resp = $req.GetResponse()
$sw.Stop()
$lat = [int]$sw.ElapsedMilliseconds
$item.Times.Add($lat)
$currentTimes += $lat
$resp.Close()
}
catch [System.Net.WebException] {
$sw.Stop()
# Если сервер вернул Любой ответ (даже 301, 302, 403, SSL-Warning) — узел ДОСТУПЕН, потерь НЕТ
if ($_.Response -or $_.Status -eq [System.Net.WebExceptionStatus]::TrustFailure -or $_.Status -eq [System.Net.WebExceptionStatus]::SecureChannelFailure) {
$lat = [int]$sw.ElapsedMilliseconds
if ($lat -gt 0) { $item.Times.Add($lat); $currentTimes += $lat }
if ($_.Response) { $_.Response.Close() }
} else {
# Реальный таймаут или обрыв физического соединения
$item.Lost++
$currentLost++
}
}
catch {
$sw.Stop()
$item.Lost++
$currentLost++
}
}
$lossPerc = [math]::Round(($currentLost / 3) * 100)
$avgLat = if ($currentTimes.Count -gt 0) { [math]::Round(($currentTimes | Measure-Object -Average).Average) } else { 0 }
if ($lossPerc -eq 100) {
Write-Host "[$now] $($target,-20) : Loss = 100% | TIMEOUT / DROPPED" -ForegroundColor Red
} elseif ($lossPerc -gt 0) {
Write-Host "[$now] $($target,-20) : Loss = $lossPerc% | Latency = ${avgLat}ms" -ForegroundColor Yellow
} else {
Write-Host "[$now] $($target,-20) : Loss = 0% | Latency = ${avgLat}ms" -ForegroundColor Green
}
}
Start-Sleep -Seconds 3
}
# --- ФОРМИРОВАНИЕ ФИНАЛЬНОГО ОТЧЕТА ПО ИСТЕЧЕНИИ 6 ЧАСОВ ---
$finishTime = Get-Date
$avgTotalSpeed = if ($speeds.Count -gt 0) { [math]::Round(($speeds | Measure-Object -Average).Average, 2) } else { 0 }
$report = @()
$report += "========================================================================="
$report += " ИТОГОВЫЙ ОТЧЕТ ТЕСТИРОВАНИЯ СВЯЗИ (6 ЧАСОВ) "
$report += "========================================================================="
$report += "Начало теста: $($startTime.ToString('yyyy-MM-dd HH:mm:ss'))"
$report += "Завершение теста: $($finishTime.ToString('yyyy-MM-dd HH:mm:ss'))"
$report += "Средняя скорость канала: $avgTotalSpeed Мбит/с"
$report += "=========================================================================`n"
$report += String::Format("{0,-22} | {1,-18} | {2,-20}", "Сервис / Узел", "Потери пакетов %", "Задержка (avg/max ms)")
$report += "-------------------------------------------------------------------------"
foreach ($target in ($targets | Sort-Object)) {
$item = $stats[$target]
$total = $item.Sent
$lost = $item.Lost
$totalLossPerc = if ($total -gt 0) { [math]::Round(($lost / $total) * 100, 1) } else { 0 }
$avgLat = if ($item.Times.Count -gt 0) { [math]::Round(($item.Times | Measure-Object -Average).Average) } else { 0 }
$maxLat = if ($item.Times.Count -gt 0) { ($item.Times | Measure-Object -Maximum).Maximum } else { 0 }
$report += String::Format("{0,-22} | {1,5}% ({2,4}/{3,-4}) | {4,5} / {5,-5} ms", $target, $totalLossPerc, $lost, $total, $avgLat, $maxLat)
}
$report | Out-File -FilePath $logPath -Encoding utf8
Write-Host "`nТЕСТ УСПЕШНО ЗАВЕРШЕН. Итоговый отчет сохранен в файл: $logPath" -ForegroundColor Green