How to List Active User Sessions in Batch Script
On a shared computer or a Terminal Server, knowing who is currently active (versus just "connected but idle") is crucial for resource management and security monitoring. While the Task Manager shows a list, IT administrators need a scriptable way to find out if "User A" is actually typing at their keyboard or if they walked away 4 hours ago.
This guide explains how to use the query user command to filter and report on active sessions via Batch.
Why List Active Sessions?
- License Management: Ensuring that you are not exceeding the maximum number of concurrent active users allowed by your software.
- Maintenance Windows: Verifying that all users have logged off before starting a critical update.
- Security: Identifying if a user is logging in at an unusual time (e.g., 3 AM).
The query user command is functionally identical to quser. Both are built-in tools for querying the Remote Desktop Services subsystem.
Method 1: Basic Session Query
The simplest way to see who is on the machine is to run the command without arguments.
@echo off
echo [PROCESS] Auditing current logon sessions...
echo.
set "FOUND="
for /f "skip=1 tokens=1" %%A in ('query user 2^>nul') do (
set "FOUND=1"
echo %%A
)
if not defined FOUND (
echo [INFO] No user sessions found on this machine.
echo [NOTE] This may also occur if not running as Administrator.
)
echo.
pause
Method 2: Filtering for 'Active' State Only
The output of query user contains both "Active" and "Disc" (Disconnected) sessions. To see only the people who are currently working:
@echo off
echo [PROCESS] Searching for live sessions...
echo.
setlocal enabledelayedexpansion
set "foundActive=0"
:: Skip header row and parse columns
for /f "skip=1 tokens=1,4*" %%A in ('query user 2^>nul') do (
set "username=%%A"
set "state=%%B"
:: Remove the '>' if present
if "!username:~0,1!"==">" set "username=!username:~1!"
if /i "!state!"=="Active" (
echo Active user: !username!
set "foundActive=1"
)
)
if !foundActive! equ 0 (
echo [INFO] No ACTIVE sessions found. All users may be disconnected.
)
pause
Creating a Session Monitor
This professional script provides a complete session overview with categorized status information.
@echo off
setlocal EnableDelayedExpansion
echo ============================================================
echo Session Monitor ^& Idle Detector
echo %COMPUTERNAME% - %DATE% %TIME%
echo ============================================================
:: Verify we can query sessions
set "SESSION_CHECK="
for /f "skip=1 tokens=*" %%a in ('query user 2^>nul') do (
set "SESSION_CHECK=found"
goto :sessions_exist
)
:sessions_exist
if not defined SESSION_CHECK (
echo.
echo [INFO] No user sessions detected.
echo [NOTE] Run as Administrator for complete results.
echo ============================================================
pause
exit /b 0
)
:: 1. Display full session overview
echo.
echo [OVERVIEW] All Sessions:
echo -----------------------------------------
query user 2>nul
echo -----------------------------------------
:: 2. Count active and disconnected sessions
echo.
set "ACTIVE=0"
set "DISC=0"
set "TOTAL=0"
for /f "skip=1 tokens=1,2,3,4*" %%a in ('query user 2^>nul') do (
set "STATE=%%d"
set /a "TOTAL+=1"
if /i "!STATE!"=="Active" set /a ACTIVE+=1
if /i "!STATE!"=="Disc" set /a DISC+=1
)
echo [SUMMARY]
echo Active sessions: !ACTIVE!
echo Disconnected sessions: !DISC!
echo Total sessions: !TOTAL!
:: 3. Alert on disconnected sessions
if !DISC! gtr 0 (
echo.
echo [WARNING] Disconnected sessions are consuming server resources.
echo [ACTION] Review and log off stale sessions:
echo.
echo Disconnected sessions:
for /f "skip=1 tokens=*" %%d in ('query user 2^>nul') do (
echo %%d | findstr /i /c:"Disc" >nul
if !errorlevel! equ 0 echo %%d
)
echo.
echo To log off a session: logoff SESSION_ID
)
echo.
echo ============================================================
pause
Common Pitfalls and How to Avoid Them
Column Shift
Parsing query user is tricky because if a user is on the "Console" session, the columns align differently than if they are on an "RDP-Tcp#1" session. Disconnected sessions may have a blank session name, causing all subsequent columns to shift left.
Solution:
For simple filtering (Active vs. Disc), use findstr on the entire line rather than trying to parse individual columns. For precise per-field extraction, PowerShell's Get-RDUserSession or structured parsing is more reliable.
"No User Exists" Error
If no one is logged in, query user returns an error level of 1 and prints "No User exists for *".
Advise your users that a "No User exists" error is actually a Good Thing in many automation contexts (it means the server is empty and safe to reboot).
Best Practices for Session Management
- Use 'qwinsta' for Services: If you need to see system sessions (like services),
query userwon't show them. Useqwinsta(Query Window Station) instead. - Remote Querying: You can query a remote server by appending
/server:ServerName. This is perfect for checking a farm of terminal servers from one script. - Logoff Command: To kick a user off, combine the Session ID found here with the
logofforrwinstacommand:logoff 2.
You need local Administrator rights to view sessions other than your own. Standard users can only see their own session.
Conclusion
Listing active user sessions via Batch script is a fundamental skill for managing shared computing environments. By leveraging the query user command to inspect connection states and idle times, you can ensure efficient resource usage, enforce security policies, and maintain a high level of operational awareness across your Windows infrastructure. This professional approach allows you to detect "zombie" sessions and keep your systems running at peak performance.