Get-UserSession.psm1

function Get-UserSession {
    <#
.SYNOPSIS
    List User Session from local or remote computer. List with Active Directory SearchBase.
.DESCRIPTION
    List User session from local or remote computer. List with Active Directory SearchBase.
.PARAMETER ComputerName
    Name of server to list User Session from remote computer.
.PARAMETER ADSearchBase
    Active Directory SearchBase of server to list User Session from remote computer.
.PARAMETER Force
    Disable the built-in Format-Table and Sort-Object.
#>

    [CmdletBinding(DefaultParameterSetName = "ParS1")]
    param (
        [parameter(Position = 0, ParameterSetName = "ParS1", Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string[]] $ComputerName = "localhost",
        [parameter(ParameterSetName = "ParS2", Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string] $ADSearchBase,
        [parameter(ParameterSetName = "ParS1", Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [parameter(ParameterSetName = "ParS2", Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [switch] $TestWinRM,
        [switch] $Force
    )
    # PsVersion
    if ((($PsVersionTable.PSEdition) -match "desktop") -or (($PsVersionTable.OS) -match "windows")) {
        # ADSearchBase
        if ($ADSearchBase) {
            try {
                $ADSearch = New-Object System.DirectoryServices.DirectorySearcher
                $ADSearch.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ADSearchBase")
                $ADSearch.Filter = ("(objectCategory=computer)")
                $ADSearchFind = $ADSearch.FindAll()
            }
            catch {
                Write-Warning "ADSearchBase not found"
            }
            $ComputerName = foreach ($ADComputer in $ADSearchFind) {
                $ADComputer.Properties.name
            }
        }
        # Loop ComputerName
        $Tmp = New-TemporaryFile
        foreach ($Computer in $ComputerName) {
            $Computer = $Computer.ToUpper()
            if ($ComputerName -like "localhost") {
                $TestL = $true
            }
            elseif ($TestWinRM) {
                $TestNCW = Test-NetConnection -CommonTCPPort WINRM -ComputerName $Computer -ErrorAction SilentlyContinue -ErrorVariable EV01
            }
            else {
                $TestNCP = Test-NetConnection -ComputerName $Computer -ErrorAction SilentlyContinue -ErrorVariable EV01
            }
            if ($TestL -or $TestNCW.TcpTestSucceeded -or $TestNCP.PingSucceeded) {
                $QuserTmp = New-TemporaryFile
                Start-Process -FilePath powershell -Wait -ArgumentList "-Command quser /SERVER:$Computer | Out-File '$QuserTmp'" -WindowStyle Hidden
                $Quser = Get-Content $QuserTmp
                if (($Quser).Count -ge 1) {
                    $List = ($Quser | Select-Object -Skip 1).TrimStart().Replace(">", "")
                    # Loop Quser List
                    foreach ($Line in $List) {
                        $Split = $Line.Substring(22) -split "\s{2,}"
                        $Output = New-Object -TypeName PSobject
                        $Output | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer
                        $Output | Add-Member -MemberType NoteProperty -Name UserName -Value $Line.Substring(0,21).Trim()
                        $Output | Add-Member -MemberType NoteProperty -Name SessionName -Value $Split[0]
                        $Output | Add-Member -MemberType NoteProperty -Name ID -Value $Split[1]
                        $Output | Add-Member -MemberType NoteProperty -Name Status -Value $Split[2]
                        $Output | Add-Member -MemberType NoteProperty -Name IdleTime -Value $Split[3]
                        $Output | Add-Member -MemberType NoteProperty -Name SessionTime -Value $Split[4]
                        $Output | Export-Csv -Path $Tmp -Append
                    }
                }
                else {
                    $Output = New-Object -TypeName PSobject
                    $Output | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer
                    $Output | Add-Member -MemberType NoteProperty -Name UserName -Value $null
                    $Output | Add-Member -MemberType NoteProperty -Name SessionName -Value $null
                    $Output | Add-Member -MemberType NoteProperty -Name ID -Value $null
                    $Output | Add-Member -MemberType NoteProperty -Name Status -Value $null
                    $Output | Add-Member -MemberType NoteProperty -Name IdleTime -Value $null
                    $Output | Add-Member -MemberType NoteProperty -Name SessionTime -Value $null
                    $Output | Export-Csv -Path $Tmp -Append
                }
            }
        }
        # Output
        if ($Force) {
            Import-Csv -Path $Tmp
        }
        else {
            Import-Csv -Path $Tmp | Sort-Object -Property ComputerName, UserName | Format-Table -AutoSize
        }
    }
    else {
        Write-Warning "PSVersion OS not Windows"
    }
}