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:
+80
-1
@@ -90,7 +90,7 @@ $script:SkipLogDetailLimit = 15
|
|||||||
# строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах).
|
# строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах).
|
||||||
# Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только
|
# Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только
|
||||||
# исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1).
|
# исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1).
|
||||||
$ScriptVersion = "2.1.13-SAC"
|
$ScriptVersion = "2.1.14-SAC"
|
||||||
|
|
||||||
# Логи (все под InstallRoot)
|
# Логи (все под InstallRoot)
|
||||||
$LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log"
|
$LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log"
|
||||||
@@ -1583,6 +1583,78 @@ function Resolve-Rcm1149UsernameFromParts {
|
|||||||
return $p1
|
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 {
|
function Get-Rcm1149EventInfo {
|
||||||
param($Event)
|
param($Event)
|
||||||
$eventData = @{
|
$eventData = @{
|
||||||
@@ -4953,6 +5025,13 @@ function Start-LoginMonitor {
|
|||||||
foreach ($event in $rcmEvents) {
|
foreach ($event in $rcmEvents) {
|
||||||
if ($event.TimeCreated -le $lastRcmCheckTime) { continue }
|
if ($event.TimeCreated -le $lastRcmCheckTime) { continue }
|
||||||
$rcmInfo = Get-Rcm1149EventInfo -Event $event
|
$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 "*$") {
|
if ($rcmInfo.Username -like "*$") {
|
||||||
$rcmSkipped++
|
$rcmSkipped++
|
||||||
Write-Log "Skip 1149: User=$($rcmInfo.Username) IP=$($rcmInfo.ClientIP) — machine account"
|
Write-Log "Skip 1149: User=$($rcmInfo.Username) IP=$($rcmInfo.ClientIP) — machine account"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# RDP Login Monitor
|
# 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, отчёты.
|
PowerShell-мониторинг Windows: RDP/RDS, RD Gateway, WinRM, admin share, блокировки УЗ, heartbeat, отчёты.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# RDP Login Monitor
|
# 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.
|
PowerShell toolkit for monitoring Windows logons with Telegram and/or Email (SMTP) notifications.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
2.1.13-SAC
|
2.1.14-SAC
|
||||||
|
|||||||
Reference in New Issue
Block a user