From a9ca50bc159002ecdf8b8ca482eb2740eab0afd4 Mon Sep 17 00:00:00 2001 From: PTah Date: Fri, 19 Jun 2026 23:47:48 +1000 Subject: [PATCH] fix: default HeartbeatStaleAlertMultiplier (2.1.1-SAC) Startup notification failed when settings lacked the variable; default 2 in script and deploy bootstrap. --- Deploy-LoginMonitor.ps1 | 44 ++++++++++++++++++++++++++++++ Login_Monitor.ps1 | 3 +- login_monitor.settings.example.ps1 | 2 ++ version.txt | 2 +- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/Deploy-LoginMonitor.ps1 b/Deploy-LoginMonitor.ps1 index 947ff0c..293541e 100644 --- a/Deploy-LoginMonitor.ps1 +++ b/Deploy-LoginMonitor.ps1 @@ -682,6 +682,49 @@ function Sync-RdpMonitorSettingsHeartbeatInterval { return $true } +function Test-RdpMonitorSettingsNeedsHeartbeatStaleAlertMultiplier { + param([string]$SettingsPath) + if (-not (Test-Path -LiteralPath $SettingsPath)) { return $true } + $c = Get-RdpMonitorSettingsRaw -Path $SettingsPath + if ([string]::IsNullOrWhiteSpace($c)) { return $true } + return ($c -notmatch '(?m)^\s*\$HeartbeatStaleAlertMultiplier\s*=\s*\d+') +} + +function Sync-RdpMonitorSettingsHeartbeatStaleAlertMultiplierIfMissing { + param( + [string]$LocalSettings, + [int]$TargetMultiplier = 2 + ) + + if (-not (Test-RdpMonitorSettingsNeedsHeartbeatStaleAlertMultiplier -SettingsPath $LocalSettings)) { + return $false + } + + if (-not (Test-Path -LiteralPath $LocalSettings)) { return $false } + + $c = Get-RdpMonitorSettingsRaw -Path $LocalSettings + $block = @( + '# --- Heartbeat stale alert: множитель × HeartbeatInterval ---' + "`$HeartbeatStaleAlertMultiplier = $TargetMultiplier" + ) -join "`r`n" + + $bak = "$LocalSettings.bak.$(Get-Date -Format 'yyyyMMdd_HHmmss')" + Copy-Item -LiteralPath $LocalSettings -Destination $bak -Force + + $insertAfterHeartbeat = '(?m)^(\s*\$HeartbeatInterval\s*=\s*\d+\s*)$' + if (-not [string]::IsNullOrWhiteSpace($c) -and $c -match $insertAfterHeartbeat) { + $newContent = [regex]::Replace($c, $insertAfterHeartbeat, ('$1' + "`r`n" + $block), 1) + } elseif (-not [string]::IsNullOrWhiteSpace($c)) { + $newContent = ($c.TrimEnd() + "`r`n`r`n" + $block + "`r`n") + } else { + $newContent = ($block + "`r`n") + } + + [System.IO.File]::WriteAllText($LocalSettings, $newContent.TrimEnd() + "`r`n", $Utf8Bom) + Write-DeployLog "login_monitor.settings.ps1: добавлен `$HeartbeatStaleAlertMultiplier = $TargetMultiplier (резервная копия: $bak)" + return $true +} + function Test-RdpMonitorSettingsNeedsStartupRebootDetectMinutes { param([string]$SettingsPath) if (-not (Test-Path -LiteralPath $SettingsPath)) { return $true } @@ -736,6 +779,7 @@ function Invoke-RdpMonitorSettingsPostPatches { if (Sync-RdpMonitorSettingsWinRmInboundBlock -LocalSettings $LocalSettings) { $changed = $true } if (Sync-RdpMonitorSettingsMaxBackupDaysIfMissing -LocalSettings $LocalSettings) { $changed = $true } if (Sync-RdpMonitorSettingsGetInventoryIfMissing -LocalSettings $LocalSettings) { $changed = $true } + if (Sync-RdpMonitorSettingsHeartbeatStaleAlertMultiplierIfMissing -LocalSettings $LocalSettings) { $changed = $true } if (Sync-RdpMonitorSettingsStartupRebootDetectMinutesIfMissing -LocalSettings $LocalSettings) { $changed = $true } return $changed } diff --git a/Login_Monitor.ps1 b/Login_Monitor.ps1 index 42a2f93..8704f19 100644 --- a/Login_Monitor.ps1 +++ b/Login_Monitor.ps1 @@ -90,7 +90,7 @@ $script:SkipLogDetailLimit = 15 # строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах). # Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только # исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1). -$ScriptVersion = "2.1.0-SAC" +$ScriptVersion = "2.1.1-SAC" # Логи (все под InstallRoot) $LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log" @@ -103,6 +103,7 @@ $MaxBackupDays = 31 # Heartbeat (файл; при отсутствии обновления > HeartbeatStaleAlertMultiplier × интервал — оповещение) $HeartbeatInterval = 14400 +$HeartbeatStaleAlertMultiplier = 2 # Окно (мин) для определения «старт после перезагрузки ОС» (LastBootUpTime + System 41/1074/6005/6008/6009). $StartupRebootDetectMinutes = 5 # Инвентаризация железа/ПО для SAC (agent.inventory); интервал опроса, сек (12 ч). diff --git a/login_monitor.settings.example.ps1 b/login_monitor.settings.example.ps1 index 1b55536..f287b1e 100644 --- a/login_monitor.settings.example.ps1 +++ b/login_monitor.settings.example.ps1 @@ -47,6 +47,8 @@ $DailyReportEnabled = 1 # --- Heartbeat SAC (agent.heartbeat): интервал в секундах; 14400 = 4 ч --- $HeartbeatInterval = 14400 +# Оповещение, если last_heartbeat.txt не обновлялся > множитель × интервал (2 × 4 ч = 8 ч) +$HeartbeatStaleAlertMultiplier = 2 # Poll SAC на команды qwinsta/logoff (сек); см. security-alert-center/docs/agent-control-plane.md # $SacCommandPollIntervalSec = 60 diff --git a/version.txt b/version.txt index 8b0505e..704cf91 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.1.0-SAC +2.1.1-SAC