From a746a82f2acd61ce6fa769ae6bca5c3b5860357f Mon Sep 17 00:00:00 2001 From: PTah Date: Mon, 13 Jul 2026 19:36:56 +1000 Subject: [PATCH] fix: parse RCM 1149 UserData/EventXML for RDG logins (2.1.13-SAC) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1149 stores username in Param1/Param2 under UserData, not EventData — RDG sessions on target PCs were skipped with empty User and never reached SAC as rdp.login.success. --- Login_Monitor.ps1 | 96 +++++++++++++++++++++++++++++++++++++++++------ version.txt | 2 +- 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/Login_Monitor.ps1 b/Login_Monitor.ps1 index c0a4c64..7f41176 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.12-SAC" +$ScriptVersion = "2.1.13-SAC" # Логи (все под InstallRoot) $LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log" @@ -1539,6 +1539,50 @@ function Test-RcmLogAvailable { } } +function Get-Rcm1149UserDataEventInfoMap { + param($Event) + + $map = @{} + try { + $xml = [xml]$Event.ToXml() + $userData = $xml.Event.UserData + if ($null -eq $userData) { return $map } + + $eventXml = $userData.EventXML + if ($null -eq $eventXml) { + foreach ($child in @($userData.ChildNodes)) { + if ($null -ne $child -and $child.LocalName -eq 'EventXML') { + $eventXml = $child + break + } + } + } + if ($null -eq $eventXml) { return $map } + + foreach ($node in @($eventXml.ChildNodes)) { + if ($null -eq $node -or $node.NodeType -ne [System.Xml.XmlNodeType]::Element) { continue } + $map[$node.LocalName] = [string]$node.InnerText + } + } catch { } + return $map +} + +function Resolve-Rcm1149UsernameFromParts { + param( + [string]$Param1, + [string]$Param2 + ) + + $p1 = if ($null -ne $Param1) { $Param1.Trim() } else { '' } + $p2 = if ($null -ne $Param2) { $Param2.Trim() } else { '' } + if ([string]::IsNullOrWhiteSpace($p1)) { return $null } + if ($p1 -match '[\\@]') { return $p1 } + if (-not [string]::IsNullOrWhiteSpace($p2)) { + return "$p2\$p1" + } + return $p1 +} + function Get-Rcm1149EventInfo { param($Event) $eventData = @{ @@ -1548,25 +1592,49 @@ function Get-Rcm1149EventInfo { } try { $map = Get-EventDataMap -Event $Event + $userDataMap = Get-Rcm1149UserDataEventInfoMap -Event $Event $user = Get-FirstNonEmptyMapValue -DataMap $map -Keys @( "TargetUser","User","Domain User","Param1","AccountName","ConnectionUser","SubjectUserName" ) $ip = Get-FirstNonEmptyMapValue -DataMap $map -Keys @( "ClientIP","Client Address","IpAddress","Ip","Param3","Address","CallingStationId" ) - if (-not [string]::IsNullOrWhiteSpace($user)) { $eventData.Username = [string]$user } - if (-not [string]::IsNullOrWhiteSpace($ip)) { $eventData.ClientIP = [string]$ip } - - if ($eventData.Username -eq '-' -and $Event.Properties.Count -gt 0) { - $eventData.Username = [string]$Event.Properties[0].Value + if ([string]::IsNullOrWhiteSpace($user)) { + $user = Resolve-Rcm1149UsernameFromParts -Param1 $userDataMap['Param1'] -Param2 $userDataMap['Param2'] } - if ($eventData.ClientIP -eq '-') { - if ($Event.Properties.Count -gt 2) { - $eventData.ClientIP = [string]$Event.Properties[2].Value - } elseif ($Event.Properties.Count -gt 1) { - $eventData.ClientIP = [string]$Event.Properties[1].Value + if ([string]::IsNullOrWhiteSpace($ip)) { + $ip = Get-FirstNonEmptyMapValue -DataMap $userDataMap -Keys @('Param3', 'Param2', 'Param1') + } + if (-not [string]::IsNullOrWhiteSpace($user)) { $eventData.Username = [string]$user } + if (-not [string]::IsNullOrWhiteSpace($ip)) { + $eventData.ClientIP = Get-RdpMonitorNormalizedClientIp -Value ([string]$ip) + } + + if (($eventData.Username -eq '-' -or [string]::IsNullOrWhiteSpace($eventData.Username)) -and $Event.Properties.Count -gt 0) { + $p0 = [string]$Event.Properties[0].Value + if (-not [string]::IsNullOrWhiteSpace($p0)) { + $eventData.Username = $p0 } } + if ($eventData.ClientIP -eq '-' -or [string]::IsNullOrWhiteSpace($eventData.ClientIP)) { + if ($Event.Properties.Count -gt 2) { + $p2 = [string]$Event.Properties[2].Value + if (-not [string]::IsNullOrWhiteSpace($p2)) { + $eventData.ClientIP = Get-RdpMonitorNormalizedClientIp -Value $p2 + } + } elseif ($Event.Properties.Count -gt 1) { + $p1 = [string]$Event.Properties[1].Value + if (-not [string]::IsNullOrWhiteSpace($p1)) { + $eventData.ClientIP = Get-RdpMonitorNormalizedClientIp -Value $p1 + } + } + } + if ([string]::IsNullOrWhiteSpace($eventData.Username) -or $eventData.Username -eq '-') { + $eventData.Username = '-' + } + if ([string]::IsNullOrWhiteSpace($eventData.ClientIP) -or $eventData.ClientIP -eq '-') { + $eventData.ClientIP = '-' + } } catch { Write-Log "Ошибка разбора события RCM 1149: $($_.Exception.Message)" } @@ -4893,7 +4961,11 @@ function Start-LoginMonitor { if (Should-IgnoreEvent -Username $rcmInfo.Username -ProcessName "-" ` -ComputerName "-" -EventID 1149 -LogonType 10 -SourceIP $rcmInfo.ClientIP) { $rcmSkipped++ - Write-Log "Skip 1149: User=$($rcmInfo.Username) IP=$($rcmInfo.ClientIP) — built-in exclusion or ignore.lst" + $ud = Get-Rcm1149UserDataEventInfoMap -Event $event + $p1 = if ($ud.ContainsKey('Param1')) { $ud['Param1'] } else { '' } + $p2 = if ($ud.ContainsKey('Param2')) { $ud['Param2'] } else { '' } + $p3 = if ($ud.ContainsKey('Param3')) { $ud['Param3'] } else { '' } + Write-Log "Skip 1149: User=$($rcmInfo.Username) IP=$($rcmInfo.ClientIP) — built-in exclusion or ignore.lst (EventXML Param1=$p1 Param2=$p2 Param3=$p3)" continue } diff --git a/version.txt b/version.txt index 3a74b42..c681f05 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.1.12-SAC +2.1.13-SAC