Home > Back-end >  How to get all remote logged on users with Logon Time
How to get all remote logged on users with Logon Time

Time:02-24

I wanted a simple way to get all (remote) logged on (and disconnected) users on all servers from my list.

I use the QUERY SESSION command for this purpose (as I found it to be the quickest and most reliable one). The command is called QWINSTA in my code (which is the same as QUERY SESSION) and works from Windows 2012 and up.

But with my script I will get the details of (server name, session name, session ID, and session state), but I need User IDOL time and User Logon time as well, but I feel with QWINSTA we cannot achieve that, with QUER User we can get those details.

Can someone help me to get all these details in my output (USERNAME, SESSIONNAME, ID, STATE, IDLE TIME, LOGIN TIME)

Below is my Code.

Code

## Clear Host Console
 Clear-Host
    
 ## Define Variable for Server Count
 $z = 0
    
 ##Set Default Script Location
 Set-Location -Path "C:\Users\reddy\Desktop\Active or Disc users"
        
 ## Provide List of Servers to Check for the Disconnected user session
 $Servers = Get-Content ".\Servers\AZ_Servers.txt"
    
 ## Get Servers Count
 $count = $Servers.count 
    
 ## Define Date for the Out file
 $dt = Get-Date -Format yyyyMMdd
 $Date = Get-Date
    
 ## Define Path for the Out File
 $exportFile = ".\Out\RDP_DisConnected_Users.csv"
    
 ## Define Array for Storing the User sessions
 $openSessions = @()
    
 ## Loop through each server to find the User Disconnected session
 Foreach ($ServerName in $Servers)
 {
    
 #initiate counter for showing progress
     $z = $z   1
    
 # Start writing progress 
 Write-Progress -Activity "Processing Server: $z out of $count servers." -Status " Progress" -PercentComplete ($z/$Servers.count*100)
    
 ## Add the servers if you want to exclude any
 $ExcludedServers = "EXCLUDESRV01", "EXCLUDESRV02", "EXCLUDESRV03"
 If ($ExcludedServers -notcontains $ServerName)
 {
 Write-Host "Getting session information for $ServerName"
 $sessions = qwinsta /server $ServerName| ?{ $_ -notmatch '^ SESSIONNAME' } | %{
 $item = "" | Select "ServerName", "Username", "Id", "State"
 $item.ServerName = $ServerName
 #$item.SessionName = $_.Substring(1,18).Trim()
 $item.Username = $_.Substring(19,20).Trim()
 $item.Id = $_.Substring(39,9).Trim()
 $item.State = $_.Substring(48,8).Trim()
 $item
 }
 $openSessions  = $sessions | where { ($_.Username -ne "") -and ($_.Username -ne "Administrator") -and ($_.State -ne "Active")}
 }
 Else { Write-Host "Skipping named computer $ServerName" -ForegroundColor Green}
 }
    
 $openSessions | Export-Csv "$exportFile" -NoTypeInformation

CodePudding user response:

I would just use

quser | Out-GridView

Then you get it in a grid.

As an alternative you can export it to CSV:

$active = quser
$active | Export-Csv -Path .\Users.csv

I hope I understood right, what you wanted...

CodePudding user response:

This is one way to split the quser output into an object with properties:

# skip header line of output
quser | Select -Skip 1 | Foreach-Object {
    # create object with empty properties
    $obj = "" | Select Username,Sessionname,ID,State,IdleTime,LogonTime
    # split the line with each group of 2 or more spaces
    $tokens = $_ -split '\s{2,}'
    # Sessionname is only available if six tokens are present
    if ($tokens.count -eq 6) {
        $obj.sessionName = $tokens[1]
    }
    # triming leading space and > for the your session
    $obj.username = $tokens[0].TrimStart(' ','>')
    # assigning remaining properties
    $obj.id,$obj.state,$obj.idletime,$obj.logontime = $tokens[-4..-1]
    # output the object
    $obj
}

CodePudding user response:

Here's an approach you can take:

## Provide List of Servers to Check for the Disconnected user session
$ExcludedServers = "EXCLUDESRV01", "EXCLUDESRV02", "EXCLUDESRV03" 
$servers = Get-Content ".\Servers\AZ_Servers.txt" | Where-Object -FilterScript { $_ -notin $ExcludedServers }
$serversCount = $servers.Count

## Define Path for the Out File
$exportFile = ".\Out\RDP_DisConnected_Users.csv"

for ($i = 0; $i -lt $serversCount; $i  )
{
    $server = $servers[$i]
    $h = $i   1
    $progressSplat = @{
        Activity = "Attempting to query $h out of $serverCount"
        Status   = "Currently on $server."
        PercentComplete = [int]($h / $serverCount * 100)
    }
    Write-Progress @progressSplat
    if (Test-Connection -ComputerName $server -Count 1 -Quiet) {
        quser /server:$server 2>&1 | 
            ForEach-Object -Process `
            {
                if (-not($_ -match "Error")) {
                    ($_ -replace '\s{2,}', ',').Trim()
                }
            } | ConvertFrom-Csv | Add-Member -NotePropertyName "ComputerName" -NotePropertyValue $server |
                Export-Csv -Path $exportFile -Append -Force -NoTypeInformation
    }
    else {
        Write-Warning -Message "Unable to ping: [$server]"
    }
}     

...it's the same logic you're using, just using Quser.exe instead. I also see that you define a $date variable that is never used.

You can use some RegEx to replace the "white space" for comma's which we will be able to ConvertFrom-Csv ignoring all errors. If you're looking to see if there was any issues when running the code, just add an extra else block to the if statement in the call to quser loop.

  • Related