$ErrorActionPreference = 'Continue' $testLog = 'C:\Apache24\htdocs\.codex_tmp\airmax_full_probe_validation.log' $protonClient = 'C:\Program Files\Proton\VPN\v5.1.5\ProtonVPN.Client.exe' $protonDirectory = Split-Path -Parent $protonClient $phpExe = 'C:\php\php.exe' function Write-TestLog([string]$message) { Add-Content -LiteralPath $testLog -Value (('{0} {1}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff'), $message)) -Encoding UTF8 } Set-Content -LiteralPath $testLog -Value '' -Encoding UTF8 Write-TestLog 'BEGIN full AirMax probe validation' try { Get-Process -Name 'ProtonVPN.Client' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 750 Stop-Service -Name 'ProtonVPN Service' -Force -ErrorAction Continue Start-Sleep -Seconds 2 $phpCode = @' require 'C:/Apache24/htdocs/mikrotik/includes/db.php'; require_once 'C:/Apache24/htdocs/mikrotik/admin/airmax_monitor_lib.php'; $started = microtime(true); $out = airmax_probe_and_persist($conn, 27); echo json_encode([ 'ok' => $out['ok'] ?? false, 'status' => $out['status'] ?? '', 'message' => $out['message'] ?? '', 'route' => $out['route']['display'] ?? '', 'transport_blocked' => $out['transport_blocked'] ?? false, 'attempts' => count($out['probe']['attempts'] ?? []), 'state' => $out['probe']['state'] ?? '', 'metrics_count' => count($out['probe']['metrics'] ?? []), 'elapsed_seconds' => round(microtime(true) - $started, 3) ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); '@ $result = & $phpExe -r $phpCode 2>$null Write-TestLog ("PHP_FULL_PROBE exit=$LASTEXITCODE result=" + ($result -join ' | ')) } catch { Write-TestLog ("ERROR " + $_.Exception.GetBaseException().Message) } finally { Start-Service -Name 'ProtonVPN Service' -ErrorAction Continue Start-Sleep -Seconds 2 if (Test-Path -LiteralPath $protonClient) { Start-Process -FilePath $protonClient -WorkingDirectory $protonDirectory -WindowStyle Hidden } Start-Sleep -Seconds 12 Write-TestLog 'END full AirMax probe validation; Proton restored' }