mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-10-26 17:41:58 -06:00
Almost Fixed Last User Field
This commit is contained in:
@@ -156,56 +156,40 @@
|
||||
ansible.builtin.set_fact:
|
||||
device_details: "{{ device_details | combine({'summary': (device_details.summary | combine({'external_ip': (external_ip_raw.stdout | default('') | trim) })) }) }}"
|
||||
|
||||
- name: Collect currently logged-in users (interactive + RDP)
|
||||
- name: Collect last logged-on user from registry (SAM/UPN)
|
||||
ansible.builtin.shell: |
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
function Get-InteractiveUsers {
|
||||
$users = @()
|
||||
try {
|
||||
$ls = Get-CimInstance Win32_LogonSession | Where-Object { $_.LogonType -in 2,10 }
|
||||
foreach ($sess in $ls) {
|
||||
$accs = Get-CimAssociatedInstance -InputObject $sess -Association Win32_LoggedOnUser -ResultClassName Win32_Account
|
||||
foreach ($a in $accs) {
|
||||
if (-not $a -or -not $a.Name) { continue }
|
||||
$nm = [string]$a.Name
|
||||
$dm = [string]$a.Domain
|
||||
if ($nm -match '\$$') { continue }
|
||||
if ($dm -eq 'NT AUTHORITY' -or $dm -eq 'NT SERVICE') { continue }
|
||||
if ($nm -like 'DWM-*' -or $nm -like 'UMFD-*') { continue }
|
||||
if ($dm) { $users += ("{0}\\{1}" -f $dm,$nm) } else { $users += $nm }
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
$users | Sort-Object -Unique
|
||||
function Normalize-Sam([string]$s) {
|
||||
if ([string]::IsNullOrWhiteSpace($s)) { return '' }
|
||||
if ($s -match '\$$') { return '' } # exclude machine accounts
|
||||
if ($s -like 'DWM-*' -or $s -like 'UMFD-*') { return '' }
|
||||
if ($s -eq 'SYSTEM' -or $s -eq 'LOCAL SERVICE' -or $s -eq 'NETWORK SERVICE' -or $s -eq 'ANONYMOUS LOGON') { return '' }
|
||||
return $s
|
||||
}
|
||||
|
||||
function Get-QuserUsers {
|
||||
$list=@()
|
||||
try {
|
||||
$q = (quser 2>$null) -split "`r?`n"
|
||||
foreach ($line in $q) {
|
||||
if (-not $line) { continue }
|
||||
if ($line -match '^USERNAME') { continue }
|
||||
$s = ($line -replace '^>','').Trim()
|
||||
if (-not $s) { continue }
|
||||
$parts = $s -split '\s+'
|
||||
if ($parts.Length -lt 1) { continue }
|
||||
$regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI'
|
||||
$sam = ''
|
||||
$upn = ''
|
||||
try { $sam = (Get-ItemProperty -Path $regPath -Name 'LastLoggedOnSAMUser' -ErrorAction Stop).LastLoggedOnSAMUser } catch {}
|
||||
try { $upn = (Get-ItemProperty -Path $regPath -Name 'LastLoggedOnUser' -ErrorAction Stop).LastLoggedOnUser } catch {}
|
||||
|
||||
$user = Normalize-Sam $sam
|
||||
if (-not $user) {
|
||||
$user = Normalize-Sam $upn
|
||||
if ($user -and $user -like '*@*') {
|
||||
# Convert UPN to DOMAIN\user using machine domain (best effort)
|
||||
$domDns = (Get-WmiObject Win32_ComputerSystem).Domain
|
||||
$domShort = ''
|
||||
if ($domDns) { $domShort = ($domDns -split '\.')[0].ToUpper() }
|
||||
$parts = $user -split '@'
|
||||
if ($parts.Length -ge 1) {
|
||||
$u = $parts[0]
|
||||
if (-not $u) { continue }
|
||||
if ($u -match '\$$') { continue }
|
||||
if ($u -like 'DWM-*' -or $u -like 'UMFD-*') { continue }
|
||||
$list += $u
|
||||
if ($domShort) { $user = "$domShort\$u" }
|
||||
}
|
||||
} catch {}
|
||||
$list | Sort-Object -Unique
|
||||
}
|
||||
}
|
||||
|
||||
$u1 = Get-InteractiveUsers
|
||||
$u2 = Get-QuserUsers
|
||||
$combined = @()
|
||||
foreach ($u in $u1) { if ($combined -notcontains $u) { $combined += $u } }
|
||||
foreach ($u in $u2) { if ($combined -notcontains $u) { $combined += $u } }
|
||||
if ($combined.Count -eq 0) { 'No Users Logged In' } else { $combined -join ', ' }
|
||||
if ($user) { $user } else { 'No Users Logged In' }
|
||||
register: last_user_raw
|
||||
changed_when: false
|
||||
|
||||
|
||||
@@ -495,6 +495,83 @@ else { 'Workstation' }
|
||||
return ''
|
||||
|
||||
|
||||
def _collect_last_user_registry() -> str:
|
||||
if not IS_WINDOWS:
|
||||
return ''
|
||||
# Registry-first approach: LogonUI LastLoggedOnSAMUser / LastLoggedOnUser
|
||||
try:
|
||||
ps = r"""
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
function Normalize-Sam([string]$s) {
|
||||
if ([string]::IsNullOrWhiteSpace($s)) { return '' }
|
||||
if ($s -match '\$$') { return '' }
|
||||
if ($s -like 'DWM-*' -or $s -like 'UMFD-*') { return '' }
|
||||
if ($s -eq 'SYSTEM' -or $s -eq 'LOCAL SERVICE' -or $s -eq 'NETWORK SERVICE' -or $s -eq 'ANONYMOUS LOGON') { return '' }
|
||||
return $s
|
||||
}
|
||||
$regPath = 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI'
|
||||
$sam = ''; $upn = ''
|
||||
try { $sam = (Get-ItemProperty -Path $regPath -Name 'LastLoggedOnSAMUser' -ErrorAction Stop).LastLoggedOnSAMUser } catch {}
|
||||
try { $upn = (Get-ItemProperty -Path $regPath -Name 'LastLoggedOnUser' -ErrorAction Stop).LastLoggedOnUser } catch {}
|
||||
$user = Normalize-Sam $sam
|
||||
if (-not $user) {
|
||||
$user = Normalize-Sam $upn
|
||||
if ($user -and $user -like '*@*') {
|
||||
$domDns = (Get-WmiObject Win32_ComputerSystem).Domain
|
||||
$domShort = ''
|
||||
if ($domDns) { $domShort = ($domDns -split '\\.')[0].ToUpper() }
|
||||
$parts = $user -split '@'
|
||||
if ($parts.Length -ge 1) {
|
||||
$u = $parts[0]
|
||||
if ($domShort) { $user = "$domShort\\$u" }
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($user) { $user } else { '' }
|
||||
"""
|
||||
out = subprocess.run(["powershell", "-NoProfile", "-Command", ps], capture_output=True, text=True, timeout=10)
|
||||
s = (out.stdout or '').strip()
|
||||
if s:
|
||||
return s.splitlines()[0].strip()
|
||||
except Exception:
|
||||
pass
|
||||
# Fallback to Python winreg lookup
|
||||
try:
|
||||
import winreg # type: ignore
|
||||
key_path = r"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI"
|
||||
def _qval(name):
|
||||
try:
|
||||
k = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path, 0, winreg.KEY_READ | getattr(winreg, 'KEY_WOW64_64KEY', 0))
|
||||
try:
|
||||
val, _ = winreg.QueryValueEx(k, name)
|
||||
finally:
|
||||
winreg.CloseKey(k)
|
||||
return str(val or '').strip()
|
||||
except Exception:
|
||||
return ''
|
||||
sam = _qval('LastLoggedOnSAMUser')
|
||||
upn = _qval('LastLoggedOnUser')
|
||||
def _ok(s: str) -> bool:
|
||||
if not s:
|
||||
return False
|
||||
su = s.upper()
|
||||
return not (s.endswith('$') or su in ('SYSTEM','LOCAL SERVICE','NETWORK SERVICE','ANONYMOUS LOGON') or s.startswith('DWM-') or s.startswith('UMFD-'))
|
||||
if _ok(sam):
|
||||
return sam
|
||||
if _ok(upn):
|
||||
if '@' in upn:
|
||||
try:
|
||||
user, dom = upn.split('@', 1)
|
||||
dom_short = (dom.split('.')[0] or dom).upper()
|
||||
return f"{dom_short}\\{user}"
|
||||
except Exception:
|
||||
pass
|
||||
return upn
|
||||
except Exception:
|
||||
pass
|
||||
return ''
|
||||
|
||||
|
||||
def _collect_last_user_string() -> str:
|
||||
if not IS_WINDOWS:
|
||||
return ''
|
||||
@@ -624,7 +701,7 @@ def _build_details_fallback() -> dict:
|
||||
pass
|
||||
# Last user(s)
|
||||
try:
|
||||
last_user = _collect_last_user_string()
|
||||
last_user = _collect_last_user_registry()
|
||||
if last_user:
|
||||
summary['last_user'] = last_user
|
||||
except Exception:
|
||||
@@ -812,7 +889,7 @@ class Role:
|
||||
pass
|
||||
return False
|
||||
if (not lu) or (lu.lower() == 'unknown') or _contains_machine_accounts(lu):
|
||||
lu2 = _collect_last_user_string().strip()
|
||||
lu2 = _collect_last_user_registry().strip()
|
||||
summary['last_user'] = lu2 if lu2 else 'No Users Logged In'
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user