<# .SYNOPSIS Inregistreaza local, in CSV, curba de descarcare a UPS-ului in timpul unui test de autonomie cu scoaterea din priza. .DESCRIPTION Se ruleaza ca task programat, sub SYSTEM, ca sa supravietuiasca inchiderii sesiunii SSH - exact scenariul unui test de pana, unde reteaua poate cadea odata cu curentul daca switch-ul nu e pe UPS. Scrie o linie la fiecare interval, indiferent de starea alimentarii, si se opreste singur dupa MaxOre sau cand apare fisierul STOP-TRACE langa CSV. Fisierul CSV e singura sursa sigura de date daca reteaua pica: monitorul propriu-zis noteaza doar evenimentele, nu fiecare citire. Se porneste cu start-trace.ps1, care inregistreaza si taskul. .EXAMPLE powershell -ExecutionPolicy Bypass -File .\trace-baterie.ps1 -IntervalSecunde 20 #> [CmdletBinding()] param( [string]$OutFile = 'C:\ROMFAST\ups-monitor\log\trace-baterie.csv', [ValidateRange(5, 300)][int]$IntervalSecunde = 20, [ValidateRange(1, 24)][int]$MaxOre = 8 ) Set-StrictMode -Version 2.0 $ErrorActionPreference = 'Stop' if (-not ('TracePowerStatus' -as [type])) { Add-Type -TypeDefinition @' using System; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public struct TRACE_POWER_STATUS { public byte ACLineStatus; public byte BatteryFlag; public byte BatteryLifePercent; public byte SystemStatusFlag; public int BatteryLifeTime; public int BatteryFullLifeTime; } public static class TracePowerStatus { [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetSystemPowerStatus(out TRACE_POWER_STATUS status); } '@ } $dir = Split-Path -Parent $OutFile if (-not (Test-Path -LiteralPath $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } $stopFile = Join-Path $dir 'STOP-TRACE' Remove-Item -LiteralPath $stopFile -Force -ErrorAction SilentlyContinue if (-not (Test-Path -LiteralPath $OutFile)) { Set-Content -LiteralPath $OutFile -Encoding UTF8 ` -Value 'ora;sursa;procent;autonomie_sec;acLineStatus;batteryFlag' } Add-Content -LiteralPath $OutFile -Encoding UTF8 ` -Value ('# start {0}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')) $pana = (Get-Date).AddHours($MaxOre) while ((Get-Date) -lt $pana -and -not (Test-Path -LiteralPath $stopFile)) { try { $st = New-Object TRACE_POWER_STATUS [void][TracePowerStatus]::GetSystemPowerStatus([ref]$st) $sursa = switch ($st.ACLineStatus) { 0 { 'baterie' } 1 { 'retea' } default { 'necunoscut' } } $procent = if ($st.BatteryLifePercent -le 100) { [int]$st.BatteryLifePercent } else { '' } $autonomie = if ($st.BatteryLifeTime -ge 0) { [int]$st.BatteryLifeTime } else { '' } Add-Content -LiteralPath $OutFile -Encoding UTF8 -Value ( '{0};{1};{2};{3};{4};{5}' -f (Get-Date -Format 'HH:mm:ss'), $sursa, $procent, $autonomie, [int]$st.ACLineStatus, [int]$st.BatteryFlag) } catch { Add-Content -LiteralPath $OutFile -Encoding UTF8 -Value ( '{0};EROARE;;;;{1}' -f (Get-Date -Format 'HH:mm:ss'), $_.Exception.Message) } Start-Sleep -Seconds $IntervalSecunde } Add-Content -LiteralPath $OutFile -Encoding UTF8 ` -Value ('# stop {0}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'))