From d0171daf8e4dd32f735dbea85508fc1074b8f28a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D1=83=D1=86=D0=B5=D0=BD=D0=BA=D0=BE=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9=20=D0=90=D0=BD=D0=B0=D1=82=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sat, 11 Apr 2026 21:48:49 +1000 Subject: [PATCH] Fix auditpol for RU subcategory and safer stderr handling --- Login_Monitor.ps1 | 79 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/Login_Monitor.ps1 b/Login_Monitor.ps1 index 6a9fc7f..fc7977c 100644 --- a/Login_Monitor.ps1 +++ b/Login_Monitor.ps1 @@ -178,18 +178,77 @@ Write-Log "Скрипт запущен с правами администрат function Enable-SecurityAudit { Write-Log "Проверка настроек аудита..." - $auditPolicy = auditpol /get /subcategory:"Logon" 2>$null - if ($auditPolicy -like "*Success*Failure*") { - Write-Log "Аудит входа уже настроен" - } else { - Write-Log "Включение аудита входа..." - try { - auditpol /set /category:"{69979849-797A-11D9-BED3-505054503030}" /success:enable /failure:enable - Write-Log "Аудит входа успешно включен" - } catch { - Write-Log "Ошибка включения аудита: $($_.Exception.Message)" + + # Важно: auditpol пишет часть сообщений в stderr. Если перенаправлять stderr в $null, + # PowerShell может превратить это в завершающую ошибку (и скрипт упадёт из-за $ErrorActionPreference=Stop). + function Invoke-AuditPol { + param([Parameter(Mandatory = $true)][string]$Arguments) + $cmd = "auditpol $Arguments 2>&1" + $text = cmd.exe /c $cmd + $code = $LASTEXITCODE + return [pscustomobject]@{ + ExitCode = $code + Text = ($text | Out-String).Trim() } } + + function Test-LogonAuditEnabled { + # На русской Windows подкатегория называется "Вход в систему", а не "Logon". + # В выводе auditpol обычно встречаются слова "успех" и "отказ" (или Success/Failure). + $candidates = @( + '/get /subcategory:"Вход в систему"', + '/get /subcategory:"Logon"' + ) + + foreach ($args in $candidates) { + $r = Invoke-AuditPol -Arguments $args + if ($r.ExitCode -ne 0) { + Write-Log ("Не удалось прочитать auditpol (код {0}) для: {1}. Вывод:`n{2}" -f $r.ExitCode, $args.Trim(), $r.Text) + continue + } + + $t = $r.Text + if (($t -match '(?i)Success') -and ($t -match '(?i)Failure')) { return $true } + if (($t -match '(?i)успех') -and ($t -match '(?i)отказ')) { return $true } + } + + return $false + } + + if (Test-LogonAuditEnabled) { + Write-Log "Аудит входа уже настроен (Success+Failure)" + return + } + + Write-Log "Аудит входа не настроен полностью. Пытаюсь включить..." + + # Порядок попыток: от самого "каноничного" к более совместимому. + $attempts = @( + # RU Windows (как в вашем выводе auditpol /list /subcategory:*) + '/set /subcategory:"Вход в систему" /success:enable /failure:enable', + '/set /category:"Вход/выход" /success:enable /failure:enable', + # EN Windows + '/set /subcategory:"Logon" /success:enable /failure:enable', + '/set /category:"Logon/Logoff" /success:enable /failure:enable', + # GUID категории (как было у вас изначально) + '/set /category:"{69979849-797A-11D9-BED3-505054503030}" /success:enable /failure:enable' + ) + + foreach ($a in $attempts) { + $r = Invoke-AuditPol -Arguments $a + if ($r.ExitCode -eq 0) { + Write-Log ("auditpol OK: {0}" -f $a.Trim()) + } else { + Write-Log ("auditpol FAIL (код {0}): {1}`n{2}" -f $r.ExitCode, $a.Trim(), $r.Text) + } + + if (Test-LogonAuditEnabled) { + Write-Log "Аудит входа успешно включен (Success+Failure)" + return + } + } + + Write-Log "ВНИМАНИЕ: не удалось автоматически включить аудит входа через auditpol. Скрипт продолжит работу, но часть событий может отсутствовать. Проверьте политику аудита вручную (локальная/доменная GPO)." } function Send-Heartbeat {