igneum/relay/playbooks/freeze-check.ps1

36 lines
4 KiB
PowerShell

# A freeze, not a power drop: what shape? (PC 2, 7 October 2026, 15:10 UK, the first boot with an RTX 5060 Ti in a
# Thunderbolt enclosure.) Reads, since 14:00Z: the display driver's TDR events (Display 4101, nvlddmkm), WHEA 17/18/19/20,
# Thunderbolt and PCI Express link events (the Thunderbolt providers, Kernel-PnP, pci: "link down"), the clean/unclean
# boot marks (41, 6008, 1074, 6006), the installed app's last lines before the freeze (the second-newest app log), and the
# GPUs with their bus ids. Read-only; nothing is sent to the installed app. Every finding is a RESULT line.
$ErrorActionPreference = 'Continue'
function Say([string]$m) { Write-Host ((Get-Date -Format 'HH:mm:ss') + ' ' + $m) }
$since = '2026-10-07T14:00:00.000Z'
$time = "TimeCreated[@SystemTime>='" + $since + "']"
function Q([string]$log, [string]$xpath, [int]$count) {
try { & wevtutil.exe qe $log ('/q:' + $xpath) /f:text ('/c:' + $count) 2>&1 | ForEach-Object { "$_" } } catch { @('wevtutil failed: ' + $_.Exception.Message) }
}
function Count([string[]]$lines) { return @($lines | Where-Object { $_ -match '^\s*Event ID: ' }).Count }
function Show([string]$label, [string[]]$lines, [int]$max) {
$n = Count $lines
Say ('RESULT ' + $label + ': ' + $n + ' event(s)')
$shown = 0
foreach ($l in $lines) { if ($l -match '^\s*(Date|Event ID|Source|Level|Description):' -or ($l -match '^\s{4}\S' -and $l.Length -lt 220)) { Say (' ' + $l.Trim()); $shown++ }; if ($shown -ge $max) { break } }
}
$os = Get-CimInstance Win32_OperatingSystem
Say ('RESULT boot ' + $os.LastBootUpTime.ToUniversalTime().ToString('o') + ' UTC, uptime ' + [int]((Get-Date) - $os.LastBootUpTime).TotalSeconds + ' s')
Show 'boot marks 41/6008/1074/6006 since 14:00Z' (Q 'System' ("*[System[" + $time + " and (EventID=41 or EventID=6008 or EventID=1074 or EventID=6006)]]") 8) 40
Show 'display TDR (Display 4101, nvlddmkm, Kernel-Power 505/506)' (Q 'System' ("*[System[" + $time + " and (Provider[@Name='Display'] or Provider[@Name='nvlddmkm'] or Provider[@Name='amdkmdag'] or EventID=4101)]]") 20) 60
Show 'WHEA 17/18/19/20/47' (Q 'System' ("*[System[" + $time + " and Provider[@Name='Microsoft-Windows-WHEA-Logger']]]") 20) 60
Show 'Thunderbolt and PCIe link (Thunderbolt providers, Kernel-PnP, pci, PCIe)' (Q 'System' ("*[System[" + $time + " and (Provider[@Name='Microsoft-Windows-Thunderbolt'] or Provider[@Name='ThunderboltService'] or Provider[@Name='Microsoft-Windows-Kernel-PnP'] or Provider[@Name='pci'] or Provider[@Name='PCI'] or Provider[@Name='Microsoft-Windows-Kernel-Pnp'] or Provider[@Name='Microsoft-Windows-Kernel-Power'])]]") 60) 120
Show 'every critical and error in System since 14:00Z' (Q 'System' ("*[System[" + $time + " and (Level=1 or Level=2)]]") 40) 120
Show 'Application errors since 14:00Z (Application Error, WER, Igneum)' (Q 'Application' ("*[System[" + $time + " and (Level=1 or Level=2)]]") 20) 60
Say 'RESULT GPUs:'
try { Get-CimInstance Win32_VideoController | ForEach-Object { Say (' video ' + $_.Name + ' driver ' + $_.DriverVersion + ' status ' + $_.Status + ' pnp ' + $_.PNPDeviceID) } } catch { }
try { & nvidia-smi --query-gpu=index,name,pci.bus_id,driver_version,pstate,temperature.gpu --format=csv,noheader 2>&1 | ForEach-Object { Say (' nvidia ' + "$_") } } catch { }
try { Get-PnpDevice -PresentOnly -ErrorAction SilentlyContinue | Where-Object { $_.FriendlyName -match 'Thunderbolt|Razer|Core X|PCI Express Root' } | ForEach-Object { Say (' pnp ' + $_.Status + ' ' + $_.Class + ' ' + $_.FriendlyName + ' ' + $_.InstanceId) } } catch { }
$logs = Join-Path $env:LOCALAPPDATA 'igneum\logs'
$files = @(Get-ChildItem $logs -Filter 'app-*.log' -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 2)
if ($files.Count -ge 2) { $f = $files[1]; Say ('RESULT app log before the freeze: ' + $f.Name + ' (last write ' + $f.LastWriteTime.ToUniversalTime().ToString('o') + ' UTC), last 40 lines:'); Get-Content $f.FullName -Tail 40 -ErrorAction SilentlyContinue | Where-Object { $_ -notmatch 'TEMPLATE|\[block\]|ACCEPTED' } | ForEach-Object { Say (' ' + $_) } }
Say 'freeze check done'
exit 0