Parse PsLoggedOn.exe Output with PowerShell

From Svendsen Tech PowerShell Wiki
Jump to: navigation, search

To find out which user is logged on to a workstation, see this article on Technet, and then use my code below to parse PsLoggedOn.exe output - if that's the approach you choose.

I'm just throwing up the code to parse the output from SysInternals' PsLoggedOn.exe and turn it into custom PowerShell objects. No grand explanation for now. Be well and prosper. The script currently requires PsLoggedOn.exe to be in the working directory (typically where you run the script from).

SysInternals was bought by Microsoft and the PSTools/SysInternals suite can be found for download here, and there's some more info about it here.

Should be compatible with PowerShell version 2 and up. Here I tested it on a Vista client against a couple of servers I have RDP'd to.

Get-LoggedOnUserExample.png




Download

Earlier versions (if any): File:Get-LocallyLoggedOnUser.ps1.txt.



Source Code

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][Alias('Cn')][string[]] $ComputerName
)

process {
    foreach ($Computer in $ComputerName) {
        Write-Verbose "Processing $Computer"
        $Output = @(.\PsLoggedon.exe -l "\\$Computer" 2> $env:TEMP\psloggedon.tmp)
        if ($Output -imatch 'Error') {
            New-Object PSObject -Property @{
                ComputerName = $Computer
                Date         = $null
                Domain       = $null
                User         = $null
                Error        = ($Output | Where-Object { $_ -match '\S' }) -join ' ; '
            } | Select-Object -Property ComputerName, Date, Domain, User, Error
        }
        $Output | ForEach-Object {
            if ($_ -match '\s+(?<DateTime>(?:.?unknown time.?|\d{1,2}/\d{1,2}/\d{4}\s+\d{1,2}:\d{1,2}:\d{1,2}\s+[ap]m))\s+(?<DomainUser>\S+)') {
                $DomainUser = $Matches.DomainUser
                if ($Matches.DateTime -imatch 'unknown time') {
                    $Date = $null
                }
                else {
                    $Date = $Matches.DateTime
                }
                if ($Date) {
                    $Date = [datetime] $Date
                }
                New-Object PSObject -Property @{
                    ComputerName = $Computer
                    Date         = $Date
                    Domain       = $DomainUser.Split('\')[0]
                    User         = $DomainUser.Split('\')[1]
                    Error        = $null
                }
            }
        } | Select-Object -Property ComputerName, Date, Domain, User, Error
    }
}