fix: qwinsta username fallback when RCM 1149 user empty (2.1.14-SAC)

On some Win10 Pro hosts EventLog 1149 has blank Param1/Param2; resolve the sole RDP session user from qwinsta before emitting Sac/notify events.
This commit is contained in:
PTah
2026-07-14 10:45:56 +10:00
parent a746a82f2a
commit f7b3597206
4 changed files with 83 additions and 4 deletions
+80 -1
View File
@@ -90,7 +90,7 @@ $script:SkipLogDetailLimit = 15
# строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах).
# Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только
# исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1).
$ScriptVersion = "2.1.13-SAC"
$ScriptVersion = "2.1.14-SAC"
# Логи (все под InstallRoot)
$LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log"
@@ -1583,6 +1583,78 @@ function Resolve-Rcm1149UsernameFromParts {
return $p1
}
function Get-Rcm1149UsernameFromQwinsta {
<#
На части ПК (наблюдалось на Win10 Pro) RCM 1149 пишет пустые Param1/Param2,
хотя сеанс уже есть в qwinsta. Берём единственную RDP-сессию (rdp-tcp#N / Disc).
Состояния локализованы (Активно/Listen/…) — не завязываемся на английский STATE.
#>
$qwExe = Join-Path $env:SystemRoot 'System32\qwinsta.exe'
if (-not (Test-Path -LiteralPath $qwExe)) { return $null }
$prevEa = $ErrorActionPreference
$rawLines = @()
try {
$ErrorActionPreference = 'SilentlyContinue'
$rawLines = @(& $qwExe 2>&1 | ForEach-Object { [string]$_ })
} catch {
return $null
} finally {
$ErrorActionPreference = $prevEa
}
$candidates = [System.Collections.Generic.List[string]]::new()
foreach ($raw in $rawLines) {
$text = if ($null -ne $raw) { $raw.Trim() } else { '' }
if ([string]::IsNullOrWhiteSpace($text)) { continue }
if ($text -match '(?i)^SESSION') { continue }
if ($text -match '^-+$') { continue }
$parts = @($text -split '\s+' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
if ($parts.Count -lt 2) { continue }
$idIdx = -1
$sid = -1
for ($i = 0; $i -lt $parts.Count; $i++) {
$token = $parts[$i].TrimStart('>')
if ($token -match '^\d+$') {
$idIdx = $i
$sid = [int]$token
break
}
}
if ($idIdx -lt 1) { continue }
# Listener «rdp-tcp» / ID 65536 — не пользовательская сессия.
if ($sid -eq 65536) { continue }
$before = @($parts[0..($idIdx - 1)])
if ($before.Count -eq 1) {
$sessionName = ''
$userName = $before[0].TrimStart('>')
} else {
$sessionName = $before[0].TrimStart('>')
$userName = $before[1]
}
if ([string]::IsNullOrWhiteSpace($userName)) { continue }
if ($userName -match '(?i)^(services|console|rdp-tcp)$') { continue }
if ($sessionName -match '(?i)^console$') { continue }
if ($sessionName -match '(?i)^rdp-tcp$' -and $sessionName -notmatch '#') { continue }
$isRdpNamed = $sessionName -match '(?i)^rdp-tcp#\d+'
$isDiscBare = [string]::IsNullOrWhiteSpace($sessionName)
if (-not ($isRdpNamed -or $isDiscBare)) { continue }
if (-not $candidates.Contains($userName)) {
[void]$candidates.Add($userName)
}
}
if ($candidates.Count -eq 1) {
return $candidates[0]
}
return $null
}
function Get-Rcm1149EventInfo {
param($Event)
$eventData = @{
@@ -4953,6 +5025,13 @@ function Start-LoginMonitor {
foreach ($event in $rcmEvents) {
if ($event.TimeCreated -le $lastRcmCheckTime) { continue }
$rcmInfo = Get-Rcm1149EventInfo -Event $event
if ($rcmInfo.Username -eq '-' -or [string]::IsNullOrWhiteSpace($rcmInfo.Username)) {
$fromQw = Get-Rcm1149UsernameFromQwinsta
if (-not [string]::IsNullOrWhiteSpace($fromQw)) {
Write-Log "RCM 1149: EventLog user empty — qwinsta fallback User=$fromQw"
$rcmInfo.Username = $fromQw
}
}
if ($rcmInfo.Username -like "*$") {
$rcmSkipped++
Write-Log "Skip 1149: User=$($rcmInfo.Username) IP=$($rcmInfo.ClientIP) — machine account"
+1 -1
View File
@@ -1,6 +1,6 @@
# RDP Login Monitor
**Версия:** `2.1.11-SAC` (`$ScriptVersion` + `version.txt`)
**Версия:** `2.1.14-SAC` (`$ScriptVersion` + `version.txt`)
PowerShell-мониторинг Windows: RDP/RDS, RD Gateway, WinRM, admin share, блокировки УЗ, heartbeat, отчёты.
+1 -1
View File
@@ -1,6 +1,6 @@
# RDP Login Monitor
**Version:** `2.1.11-SAC` (`$ScriptVersion` + `version.txt`)
**Version:** `2.1.14-SAC` (`$ScriptVersion` + `version.txt`)
PowerShell toolkit for monitoring Windows logons with Telegram and/or Email (SMTP) notifications.
+1 -1
View File
@@ -1 +1 @@
2.1.13-SAC
2.1.14-SAC