Files
scripts/diag2.ps1
2026-07-30 09:04:58 +00:00

92 lines
4.5 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# diag2.ps1 - полное чтение библиотек игр: ловим сбойные и "медленные" файлы
# Запускать, если diag1 не дал однозначного ответа. Время: 10-25 мин на ~150 ГБ SATA SSD.
# Запуск: powershell -NoProfile -ExecutionPolicy Bypass -File C:\diag2.ps1
$ErrorActionPreference = 'Continue'
$out = "$env:USERPROFILE\Desktop\diag2.txt"
Start-Transcript -Path $out -Force | Out-Null
# Порог "медленного" чтения. Для SATA SSD норма 300-550 МБ/с.
# Ниже 80 МБ/с на крупном файле = контроллер уходит в ретраи (потеря заряда в ячейках).
$SLOW_MBS = 80
$MIN_MB_FOR_SPEED = 8 # файлы мельче не оцениваем по скорости - оверхед искажает
$libs = @()
foreach ($drv in (Get-Volume | Where-Object { $_.DriveLetter -and $_.FileSystem -eq 'NTFS' }).DriveLetter) {
foreach ($cand in @("${drv}:\steam\steamapps\common", "${drv}:\SteamLibrary\steamapps\common", "${drv}:\Program Files (x86)\Steam\steamapps\common")) {
if (Test-Path $cand) { $libs += $cand }
}
}
"Библиотеки: $($libs -join ', ')"
# Проверяем проблемные игры; если их нет - всю библиотеку
$targets = @()
foreach ($l in $libs) {
$targets += Get-ChildItem $l -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match 'Counter-Strike|Tsushima|Rome|Serious Sam' }
}
if (-not $targets) { $targets = $libs | ForEach-Object { Get-Item $_ } }
"Проверяю: $(($targets | ForEach-Object { $_.Name }) -join ' | ')`n"
$files = $targets | ForEach-Object { Get-ChildItem $_.FullName -Recurse -File -ErrorAction SilentlyContinue }
$totalGB = [math]::Round(($files | Measure-Object -Sum Length).Sum / 1GB, 1)
"Файлов: $($files.Count), объём: $totalGB ГБ`n"
$buf = New-Object byte[] 4194304
$bad = @(); $slow = @(); $i = 0
$swAll = [Diagnostics.Stopwatch]::StartNew()
foreach ($f in $files) {
$i++
if ($i % 200 -eq 0) { Write-Progress -Activity "Чтение" -Status "$i / $($files.Count)" -PercentComplete ($i * 100 / $files.Count) }
try {
$fs = [IO.File]::Open($f.FullName, 'Open', 'Read', 'Read')
$sw = [Diagnostics.Stopwatch]::StartNew()
$total = 0
while (($n = $fs.Read($buf, 0, $buf.Length)) -gt 0) { $total += $n }
$sw.Stop(); $fs.Close()
$mb = $total / 1MB
if ($mb -ge $MIN_MB_FOR_SPEED -and $sw.Elapsed.TotalSeconds -gt 0) {
$spd = $mb / $sw.Elapsed.TotalSeconds
if ($spd -lt $SLOW_MBS) {
$slow += [pscustomobject]@{ MBs = [math]::Round($spd, 1); MB = [math]::Round($mb, 1); Path = $f.FullName }
"SLOW {0,7:N1} MB/s {1,8:N1} MB {2}" -f $spd, $mb, $f.FullName
}
}
} catch {
$bad += [pscustomobject]@{ Path = $f.FullName; Err = $_.Exception.Message }
"FAIL $($f.FullName)`n -> $($_.Exception.Message)"
}
}
$swAll.Stop()
Write-Progress -Activity "Чтение" -Completed
"`n" + ('=' * 70)
"ИТОГ: прочитано $totalGB ГБ за $([math]::Round($swAll.Elapsed.TotalMinutes,1)) мин"
"Средняя скорость: $([math]::Round($totalGB * 1024 / $swAll.Elapsed.TotalSeconds, 1)) МБ/с"
"Ошибок чтения: $($bad.Count)"
"Медленных файлов (<$SLOW_MBS МБ/с): $($slow.Count)"
('=' * 70)
if ($bad) {
"`n--- ФАЙЛЫ С ОШИБКОЙ ЧТЕНИЯ (прямое доказательство сбойных секторов):"
$bad | Format-List
}
if ($slow) {
"`n--- ТОП-30 МЕДЛЕННЫХ (ретраи контроллера / потеря заряда в ячейках):"
$slow | Sort-Object MBs | Select-Object -First 30 | Format-Table -AutoSize
}
if (-not $bad -and -not $slow) {
"`nЧисто: все файлы читаются на полной скорости. Версия про накопитель слабеет -"
"переходим к питанию и драйверу (стресс GPU с логом HWiNFO)."
}
"`n--- SMART ПОСЛЕ ПРОГОНА (сравнить C5/05/BB с diag1: рост = диск сыплется прямо сейчас)"
$sm = "C:\Program Files\smartmontools\bin\smartctl.exe"
if (Test-Path $sm) {
& $sm --scan 2>&1 | ForEach-Object { if ($_ -match '^(\S+)\s') { "`n=== $($Matches[1])"; & $sm -A $Matches[1] 2>&1 } }
}
Stop-Transcript | Out-Null
Write-Host "`nОтчёт сохранён: $out" -ForegroundColor Green