Whenn managing remote terminal servers, administrators often need to perform user session management tasks such as logging off speicfic users. The traditional approach involves using quser to retrieve session information and logoff to terminate sessions:
quser /server:SERVER_NAME
logoff SESSION_ID /server:SERVER_NAME
Like many legacy command-line tools from Windows cmd and Linux bash, quser outputs data in string format. String manipulation in scripts can become cumbersome, making it beneficial to convert these results into structured object format.
Analyzing the Output Format
Examining the quser output reveals a well-formatted table structure. By replacing spaces between columns with commas, we can transform this into CSV format, which PowerShell can easily convert to objects. The challenge lies in empty fields like SESSIONNAME, requiring careful counting of space characters to replace.
Example quser output:
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
smiths rdp-tcp#5 16 Active 24692+13:29 3/14/2017 9:06 AM
llederbauer rdp-tcp#4 22 Active 1:18 3/14/2017 9:18 AM
jedwards 23 Disc 1:39 3/14/2017 7:54 AM
tpicken rdp-tcp#2 24 Active . 3/14/2017 8:22 AM
Character Analysis Approach
To determine the correct number of spaces to replace, converting the output to ASCII values helps identify spacing patterns:
$rawOutput = quser /server:TARGET_SERVER
[char[]]$rawOutput[2] | ForEach-Object { [int]$_ }
This analysis reveals that there are 16 space characters (ASCII value 32) that need replacement.
Solution Implementation
The solution envolves replacing multiple consecutive spaces (from 2 to 17 characters) with commas, starting from position 2 to avoid altering spaces within column headers like 'IDLE TIME'.
$userSessions = (quser /server:TARGET_SERVER) -replace '\s{2,17}', ',' | ConvertFrom-Csv
$userSessions | Format-Table
This produces structured objects with properties like USERNAME, SESSIONNAME, ID, STATE, IDLE TIME, and LOGON TIME.
Sample processed output:
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
-------- ----------- -- ----- --------- ----------
smiths 16 Disc 3 3/14/2017 9:06 AM
llederbauer rdp-tcp#4 22 Active 1:26 3/14/2017 9:18 AM
jedwards 23 Disc 1:47 3/14/2017 7:54 AM
tpicken rdp-tcp#2 24 Active 7 3/14/2017 8:22 AM
Enhanced Script Example
function Get-RemoteUserSessions {
param(
[string]$ServerName
)
$sessionData = (quser /server:$ServerName) -replace '\s{2,17}', ',' | ConvertFrom-Csv
return $sessionData
}
$sessions = Get-RemoteUserSessions -ServerName "terminal-server-01"
# Filter active sessions
$activeSessions = $sessions | Where-Object { $_.STATE -eq "Active" }
# Display formatted results
$activeSessions | Select-Object USERNAME, ID, SESSIONNAME, "IDLE TIME" | Format-Table -AutoSize
This approach enables more sophisticated data processing, filtering, and automation compared to working with raw string output. The same methodology can be applied to other legacy command-line tools that produce tabular text output.