From 2bbf1face69fb1e09e573f7aec44e39582aba680 Mon Sep 17 00:00:00 2001 From: PTah Date: Fri, 29 May 2026 17:50:17 +1000 Subject: [PATCH] fix(deploy): patch DailyReportEnabled hint and invalid false assignment (1.2.22-SAC) Co-authored-by: Cursor --- Deploy-LoginMonitor.ps1 | 98 +++++++++++++++++++++++++++++- Docs/deploy-rdp-login-monitor.md | 1 + Login_Monitor.ps1 | 19 +++++- login_monitor.settings.example.ps1 | 3 +- version.txt | 3 +- 5 files changed, 118 insertions(+), 6 deletions(-) diff --git a/Deploy-LoginMonitor.ps1 b/Deploy-LoginMonitor.ps1 index 1b6d50a..9811199 100644 --- a/Deploy-LoginMonitor.ps1 +++ b/Deploy-LoginMonitor.ps1 @@ -264,6 +264,92 @@ function Test-RdpMonitorSettingsNeedsServerDisplayNameHint { return $true } +function Test-RdpMonitorSettingsNeedsDailyReportHint { + param([string]$SettingsPath) + if (-not (Test-Path -LiteralPath $SettingsPath)) { return $false } + $c = Get-RdpMonitorSettingsRaw -Path $SettingsPath + if ([string]::IsNullOrWhiteSpace($c)) { return $false } + if ($c -match '(?m)^\s*(\#\s*)?\$DailyReportEnabled\s*=') { return $false } + return $true +} + +function Test-RdpMonitorSettingsHasInvalidDailyReportAssignment { + param([string]$SettingsPath) + if (-not (Test-Path -LiteralPath $SettingsPath)) { return $false } + $c = Get-RdpMonitorSettingsRaw -Path $SettingsPath + if ([string]::IsNullOrWhiteSpace($c)) { return $false } + if ($c -match '(?m)^\s*\$DailyReportEnabled\s*=\s*\$(?:true|false)\b') { return $false } + if ($c -match '(?m)^\s*\$DailyReportEnabled\s*=\s*(?:0|1)\s*(?:#.*)?$') { return $false } + if ($c -match '(?m)^\s*\$DailyReportEnabled\s*=\s*(?:true|false)\s*(?:#.*)?$') { return $true } + return $false +} + +function Repair-RdpMonitorSettingsDailyReportAssignmentIfInvalid { + param([string]$LocalSettings) + if (-not (Test-Path -LiteralPath $LocalSettings)) { return $false } + if (-not (Test-RdpMonitorSettingsHasInvalidDailyReportAssignment -SettingsPath $LocalSettings)) { + return $false + } + + $c = Get-RdpMonitorSettingsRaw -Path $LocalSettings + $newContent = [regex]::Replace( + $c, + '(?m)^(\s*\$DailyReportEnabled\s*=\s*)(true|false)(\s*(?:#.*)?)$', + { param($m) "$($m.Groups[1].Value)`$$($m.Groups[2].Value)$($m.Groups[3].Value)" } + ) + if ($newContent -eq $c) { return $false } + + $bak = "$LocalSettings.bak.$(Get-Date -Format 'yyyyMMdd_HHmmss')" + Copy-Item -LiteralPath $LocalSettings -Destination $bak -Force + [System.IO.File]::WriteAllText($LocalSettings, $newContent.TrimEnd() + "`r`n", $Utf8Bom) + Write-DeployLog "login_monitor.settings.ps1: исправлено DailyReportEnabled = true/false без dollar — заменено на `$true/`$false (резервная копия: $bak)" + return $true +} + +function Update-RdpMonitorSettingsDailyReportHintIfMissing { + param([string]$LocalSettings) + if (-not (Test-Path -LiteralPath $LocalSettings)) { return $false } + if (-not (Test-RdpMonitorSettingsNeedsDailyReportHint -SettingsPath $LocalSettings)) { + return $false + } + + $c = Get-RdpMonitorSettingsRaw -Path $LocalSettings + if ([string]::IsNullOrWhiteSpace($c)) { return $false } + + $hintBlock = @( + '# --- Суточный отчёт report.daily.rdp (агент или только SAC) ---' + '# $DailyReportEnabled = $false # по умолчанию: только SAC; $true или 1 — отчёт с агента' + '# Не пишите "= false" без $ — PowerShell воспримет false как команду.' + ) -join "`r`n" + + $bak = "$LocalSettings.bak.$(Get-Date -Format 'yyyyMMdd_HHmmss')" + Copy-Item -LiteralPath $LocalSettings -Destination $bak -Force + Write-DeployLog "Добавление закомментированного `$DailyReportEnabled в login_monitor.settings.ps1; резервная копия: $bak" + + $insertBefore = '(?m)^\s*#\s*---\s*Security Alert Center' + if ($c -match $insertBefore) { + $newContent = [regex]::Replace($c, $insertBefore, ($hintBlock + "`r`n`r`n" + '$0'), 1) + } else { + $newContent = ($c.TrimEnd() + "`r`n`r`n" + $hintBlock + "`r`n") + } + [System.IO.File]::WriteAllText($LocalSettings, $newContent.TrimEnd() + "`r`n", $Utf8Bom) + Write-DeployLog 'login_monitor.settings.ps1: добавлена подсказка # $DailyReportEnabled = $false' + return $true +} + +function Sync-RdpMonitorSettingsDailyReportPatches { + param([string]$LocalSettings) + if (-not (Test-Path -LiteralPath $LocalSettings)) { return $false } + $changed = $false + if (Repair-RdpMonitorSettingsDailyReportAssignmentIfInvalid -LocalSettings $LocalSettings) { + $changed = $true + } + if (Update-RdpMonitorSettingsDailyReportHintIfMissing -LocalSettings $LocalSettings) { + $changed = $true + } + return $changed +} + function Update-RdpMonitorSettingsServerDisplayNameHintIfMissing { param([string]$LocalSettings) if (-not (Test-Path -LiteralPath $LocalSettings)) { return $false } @@ -372,6 +458,7 @@ function Sync-RdpMonitorSettingsFromShare { if (-not $needsBootstrap) { Write-DeployLog "login_monitor.settings.ps1: SAC уже настроен, файл не перезаписываем." Update-RdpMonitorSettingsServerDisplayNameHintIfMissing -LocalSettings $LocalSettings | Out-Null + Sync-RdpMonitorSettingsDailyReportPatches -LocalSettings $LocalSettings | Out-Null return } @@ -383,11 +470,13 @@ function Sync-RdpMonitorSettingsFromShare { Write-DeployLog "Создан login_monitor.settings.ps1 из example (Telegram + SAC dual)." Copy-Item -LiteralPath $ExampleOnShare -Destination $LocalSettings -Force Update-RdpMonitorSettingsServerDisplayNameHintIfMissing -LocalSettings $LocalSettings | Out-Null + Sync-RdpMonitorSettingsDailyReportPatches -LocalSettings $LocalSettings | Out-Null return } if (Update-RdpMonitorSettingsSacBlockIfMissing -LocalSettings $LocalSettings -ExampleOnShare $ExampleOnShare) { Update-RdpMonitorSettingsServerDisplayNameHintIfMissing -LocalSettings $LocalSettings | Out-Null + Sync-RdpMonitorSettingsDailyReportPatches -LocalSettings $LocalSettings | Out-Null return } @@ -396,6 +485,7 @@ function Sync-RdpMonitorSettingsFromShare { Write-DeployLog "Апгрейд settings: резервная копия $bak, применяем example с шары." Copy-Item -LiteralPath $ExampleOnShare -Destination $LocalSettings -Force Update-RdpMonitorSettingsServerDisplayNameHintIfMissing -LocalSettings $LocalSettings | Out-Null + Sync-RdpMonitorSettingsDailyReportPatches -LocalSettings $LocalSettings | Out-Null } function Stop-RdpLoginMonitorMainProcesses { @@ -473,8 +563,10 @@ try { $needsSettingsBootstrap = Test-RdpMonitorSettingsNeedsSacBootstrap -SettingsPath $settingsLocal $needsDisplayNameHint = Test-RdpMonitorSettingsNeedsServerDisplayNameHint -SettingsPath $settingsLocal + $needsDailyReportHint = Test-RdpMonitorSettingsNeedsDailyReportHint -SettingsPath $settingsLocal + $needsDailyReportRepair = Test-RdpMonitorSettingsHasInvalidDailyReportAssignment -SettingsPath $settingsLocal $needsBundleSync = Test-RdpMonitorDeployBundleNeedsSync -ShareRoot $shareRoot - $needsSacBootstrap = $needsSettingsBootstrap -or $needsBundleSync -or $needsDisplayNameHint + $needsSacBootstrap = $needsSettingsBootstrap -or $needsBundleSync -or $needsDisplayNameHint -or $needsDailyReportHint -or $needsDailyReportRepair $cmp = Compare-VersionStrings -Left $shareVerRaw -Right $localVerRaw if ($null -ne $cmp) { @@ -489,6 +581,10 @@ try { Write-DeployLog "Версия совпадает ($shareVerRaw), но нужна донастройка SAC в settings — продолжаем деплой." } elseif ($needsDisplayNameHint) { Write-DeployLog "Версия совпадает ($shareVerRaw), но нет подсказки `$ServerDisplayName в settings — продолжаем деплой." + } elseif ($needsDailyReportHint) { + Write-DeployLog "Версия совпадает ($shareVerRaw), но нет `$DailyReportEnabled в settings — продолжаем деплой." + } elseif ($needsDailyReportRepair) { + Write-DeployLog "Версия совпадает ($shareVerRaw), но в settings некорректно задан `$DailyReportEnabled (= true/false без `$) — продолжаем деплой." } } if ($cmp -lt 0 -and -not $AllowDowngrade) { diff --git a/Docs/deploy-rdp-login-monitor.md b/Docs/deploy-rdp-login-monitor.md index 8071cf0..18d0408 100644 --- a/Docs/deploy-rdp-login-monitor.md +++ b/Docs/deploy-rdp-login-monitor.md @@ -50,6 +50,7 @@ - Если файла нет — Deploy **один раз** копирует example → settings (**`UseSAC = 'dual'`**). - Если файл есть, но **нет блока SAC** — Deploy **дописывает** блок из example (Telegram/SMTP не трогает). - Если **нет** строки `$ServerDisplayName` — Deploy **дописывает** закомментированную подсказку `# $ServerDisplayName = '<имя ПК>'`. +- Если **нет** `$DailyReportEnabled` — Deploy **дописывает** закомментированную подсказку `# $DailyReportEnabled = $false` (суточный отчёт только из SAC). Если в файле ошибочно `= false` без `$` — Deploy **исправляет** на `$false`. ```powershell $root = 'C:\ProgramData\RDP-login-monitor' diff --git a/Login_Monitor.ps1 b/Login_Monitor.ps1 index 0a538fb..d12c565 100644 --- a/Login_Monitor.ps1 +++ b/Login_Monitor.ps1 @@ -80,7 +80,7 @@ $script:MonitorLoopInitialized = $false # строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах). # Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только # исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1). -$ScriptVersion = "1.2.21-SAC" +$ScriptVersion = "1.2.22-SAC" # Логи (все под InstallRoot) $LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log" @@ -107,7 +107,8 @@ $script:IgnoreListCacheStampUtc = $null $DailyReportHour = 9 $DailyReportMinute = 0 # $false = не слать report.daily.rdp с агента (суточный отчёт только из SAC) -$DailyReportEnabled = $true +# В settings.ps1 используйте 1/0 или $true/$false — не пишите голое false без $ +$DailyReportEnabled = 1 $LastReportFile = Join-Path $script:InstallRoot "Logs\last_daily_report.txt" # RD Gateway @@ -2537,8 +2538,20 @@ function Send-DailyReport { } } +function Test-DailyReportEnabledFlag { + if (-not (Get-Variable -Name DailyReportEnabled -ErrorAction SilentlyContinue)) { + return $true + } + $v = $DailyReportEnabled + if ($v -is [bool]) { return $v } + if ($v -is [int] -or $v -is [long]) { return ([int]$v -ne 0) } + $s = ([string]$v).Trim().ToLowerInvariant() + if ($s -in @('0', 'false', 'no', 'off')) { return $false } + return $true +} + function Check-AndSendDailyReport { - if (-not $DailyReportEnabled) { + if (-not (Test-DailyReportEnabledFlag)) { return (Get-NextLocalSlotBoundary -Hour $DailyReportHour -Minute $DailyReportMinute) } $lastReport = $null diff --git a/login_monitor.settings.example.ps1 b/login_monitor.settings.example.ps1 index bbd876e..2f80184 100644 --- a/login_monitor.settings.example.ps1 +++ b/login_monitor.settings.example.ps1 @@ -42,7 +42,8 @@ $SacApiKey = 'sac_UkOsAT3UWiQS54KK5OJPBDCSucysQDrKFju28wmYiz8' # $SacTlsSkipVerify = $false # $SacFallbackFailures = 5 # $false = не слать report.daily.rdp с агента (суточный отчёт только из SAC) -# $DailyReportEnabled = $true +# Важно: только $false или 0/1 — строка "false" без $ ломает загрузку настроек! +$DailyReportEnabled = 1 # Проверка: powershell -File Login_Monitor.ps1 -CheckSac # --- Узкое исключение шумовых сетевых логонов (LogonType=3, Advapi) --- diff --git a/version.txt b/version.txt index b3568b8..80ed66d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1,2 @@ -1.2.21-SAC +1.2.22-SAC +