Private/Resolve-LoggedOnUser.ps1
|
function Resolve-LoggedOnUser { <# .SYNOPSIS Detects the currently logged-on interactive user. .DESCRIPTION Uses multiple strategies to find the active interactive user: 1. Win32_ComputerSystem.UserName (most reliable for console sessions) 2. Explorer.exe process owner (fallback for edge cases) Caches the result in $script:IndagoState.LoggedOnUser. .OUTPUTS [PSCustomObject] with UserName and Domain properties, or $null if no user is logged on. #> [CmdletBinding()] [OutputType([PSCustomObject])] param() # Bug #11 fix: always query the live session. Caching is dangerous in # persistent RMM agents — if user A logs off and user B logs on, the # cache would forever return user A's identity. $userInfo = $null #region Strategy 1: Win32_ComputerSystem try { $cs = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop if (-not [string]::IsNullOrWhiteSpace($cs.UserName)) { $parts = $cs.UserName -split '\\' if ($parts.Count -eq 2) { $userInfo = [PSCustomObject]@{ UserName = $parts[1] Domain = $parts[0] FullName = $cs.UserName Source = 'Win32_ComputerSystem' } } else { $userInfo = [PSCustomObject]@{ UserName = $cs.UserName Domain = $env:COMPUTERNAME FullName = "$env:COMPUTERNAME\$($cs.UserName)" Source = 'Win32_ComputerSystem' } } Write-Verbose "Resolve-LoggedOnUser: Found user via Win32_ComputerSystem: $($userInfo.FullName)" } } catch { Write-Verbose "Resolve-LoggedOnUser: Win32_ComputerSystem query failed: $($_.Exception.Message)" } #endregion #region Strategy 2: Explorer.exe process owner (fallback) if ($null -eq $userInfo) { try { $explorerProc = Get-CimInstance -ClassName Win32_Process -Filter "Name = 'explorer.exe'" -ErrorAction Stop | Select-Object -First 1 if ($null -ne $explorerProc) { $ownerResult = Invoke-CimMethod -InputObject $explorerProc -MethodName GetOwner -ErrorAction Stop if ($ownerResult.ReturnValue -eq 0) { $userInfo = [PSCustomObject]@{ UserName = $ownerResult.User Domain = $ownerResult.Domain FullName = "$($ownerResult.Domain)\$($ownerResult.User)" Source = 'Explorer.exe' } Write-Verbose "Resolve-LoggedOnUser: Found user via Explorer.exe owner: $($userInfo.FullName)" } } } catch { Write-Verbose "Resolve-LoggedOnUser: Explorer.exe owner query failed: $($_.Exception.Message)" } } #endregion if ($null -eq $userInfo) { Write-Verbose 'Resolve-LoggedOnUser: No interactive user session detected.' } return $userInfo } |