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.