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 одинаково; при только
|
||||
# исправлениях на шаре — достаточно поднять 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,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
@@ -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
@@ -1 +1 @@
|
||||
2.1.13-SAC
|
||||
2.1.14-SAC
|
||||
|
||||
Reference in New Issue
Block a user