Das Problem mit Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Unique
ist, dass alle Sitzungen angezeigt werden, auch diejenigen, die seit dem letzten Neustart des Computers geschlossen wurden. Der einfachste Weg, Sitzungen abzufragen, ist leider die alte ausführbare Datei query.exe.
Sie können die Ausgabe von query.exe in ein bisschen Regex in Objekte konvertieren:
$Computer = $env:COMPUTERNAME $Users = query user /server:$Computer 2>&1 $Users = $Users | ForEach-Object { (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9])\s+(\d\s+\w+)", '$1 none $2' -replace "\s", "," -replace "none", $null)) } | ConvertFrom-Csv foreach ($User in $Users) { [PSCustomObject]@{ ComputerName = $Computer Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") } }
Was gibt Ihnen eine Ausgabe wie folgt:
ComputerName Username SessionState SessionType ------------ -------- ------------ ----------- BSMITH-LT bobsm Active console
Wir gehen noch viel näher auf eine Funktion ein:
function Convert-QueryToObjects { [CmdletBinding()] [Alias('QueryToObject')] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [Alias('ComputerName', 'Computer')] [string] $Name = $env:COMPUTERNAME ) Process { Write-Verbose "Running query.exe against $Name." $Users = query user /server:$Name 2>&1 if ($Users -like "*No User exists*") { # Handle no user's found returned from query. # Returned: 'No User exists for *' Write-Error "There were no users found on $Name : $Users" Write-Verbose "There were no users found on $Name." } elseif ($Users -like "*Error*") { # Handle errored returned by query. # Returned: 'Error ...<message>...' Write-Error "There was an error running query against $Name : $Users" Write-Verbose "There was an error running query against $Name." } elseif ($Users -eq $null -and $ErrorActionPreference -eq 'SilentlyContinue') { # Handdle null output called by -ErrorAction. Write-Verbose "Error action has supressed output from query.exe. Results were null." } else { Write-Verbose "Users found on $Name. Converting output from text." # Conversion logic. Handles the fact that the sessionname column may be populated or not. $Users = $Users | ForEach-Object { (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9])\s+(\d\s+\w+)", '$1 none $2' -replace "\s", "," -replace "none", $null)) } | ConvertFrom-Csv Write-Verbose "Generating output for $($Users.Count) users connected to $Name." # Output objects. foreach ($User in $Users) { Write-Verbose $User if ($VerbosePreference -eq 'Continue') { # Add '| Out-Host' if -Verbose is tripped. [PSCustomObject]@{ ComputerName = $Name Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") } | Out-Host } else { # Standard output. [PSCustomObject]@{ ComputerName = $Name Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") } } } } } }
und jetzt kannst du Dinge tun wie: Get-ADComputer -Filter | Convert-QueryToObjects | ? {$_.SessionState -eq 'Active'}