我正在尝试创建一个简单的脚本来终止所有远程桌面会话(无论活动还是断开连接),而无需重新启动服务器。我的服务器操作系统是 Windows Server 2012R2,启用并许可了远程桌面服务。
我在这里找到了一个简单的批处理文件脚本来执行此任务:在此处输入链接描述
当我在终端服务器上本地运行此脚本时,我在批处理文件运行中收到错误消息:未找到会话光盘
并且只有控制台用户被注销。谁能告诉我这个脚本有什么问题吗?
query session >session.txt
for /f "skip=1 tokens=3," %%i in (session.txt) DO logoff %%i
del session.txt
我的会话文本文件如下所示:
SESSIONNAME USERNAME ID STATE TYPE DEVICE
services 0 Disc
>console Administrator 13 Active
wcunningham 18 Disc
kstarkey 25 Disc
rdp-tcp#11 cyannone 52 Active
rdp-tcp 65536 Listen
我发现一个很好的解决方法是添加一条额外的线路来处理断开连接的会话。由于断开连接的会话不会列出会话名称,因此 ID 位于位置 2,而不是像活动会话那样位于位置 3。因此,添加指定 token=2 的附加行就可以了:
query session >session.txt
for /f "skip=1 tokens=2," %%i in (session.txt) DO logoff.exe %%i
for /f "skip=1 tokens=3," %%i in (session.txt) DO logoff.exe %%i
del session.txt
跳过前 3 个线和活跃用户
query session >session.txt
for /f "skip=3 eol=> tokens=2," %%i in (session.txt) DO echo %%i
for /f "skip=3 eol=> tokens=3," %%i in (session.txt) DO echo %%i
del session.txt
您可能已经注意到,
SESSIONNAME
和USERNAME
有时是空的,这完全搞乱了位置参数。
这是处理查询会话的更可靠的方法:
script.bat
@ECHO OFF
@SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
FOR /f "skip=1 tokens=* usebackq delims=" %%G IN (`query session`) DO (
CALL :SESS_PARSE "%%G"
FOR /f "tokens=1-6 eol= delims=;" %%a IN ("!SESS_DESC!") DO (
SET sess_is_curr=%%a
SET sess_user=%%b
SET sess_id=%%c
SET sess_state=%%d
SET sess_type=%%e
SET sess_name=%%f
)
ECHO INPUT: '%%G'
ECHO DESC : '!SESS_DESC!'
ECHO CURR : '!sess_is_curr!'
ECHO NAME : '!sess_name!'
ECHO USER : '!sess_user!'
ECHO SESS : '!sess_id!'
ECHO STATE: '!sess_state!'
ECHO TYPE : '!sess_type!'
ECHO ------------------------------
rem IF !sess_is_curr! == 1 ECHO Current session ID: '!sess_id!'
)
GOTO :EOF
:SESS_PARSE
SETLOCAL
SET "line=%~1"
rem Extract current session flag
SET is_curr=0
IF "!line:~0,1!" == ">" SET is_curr=1
rem Extract and trim 'SESSIONNAME' field
SET name=!line:~1,18!
SET name=!name: =!
IF "!name!" == "" SET name=-
rem Extract and trim 'USERNAME' field
SET user=!line:~19,22!
SET user=!user: =!
IF "!user!" == "" SET user=-
rem Quick-parse the rest of the not so flacky fields
FOR /f "tokens=1-3" %%a IN ("!line:~42,-1!") DO (SET "sid=%%a" & SET "state=%%b" & SET "type=%%c")
IF "!type!" == "" SET type=-
ENDLOCAL & SET "SESS_DESC=%is_curr%;%user%;%sid%;%state%;%type%;%name%;"
GOTO :EOF
输出将如下所示:
C:\Users\User1>script.cmd
INPUT: ' services 0 Disc '
DESC : '0;-;0;Disc;-;services;'
CURR : '0'
NAME : 'services'
USER : '-'
SESS : '0'
STATE: 'Disc'
TYPE : '-'
------------------------------
INPUT: '>rdp-tcp#1 User1 1 Active rdpwd '
DESC : '1;User1;1;Active;rdpwd;rdp-tcp#1;'
CURR : '1'
NAME : 'rdp-tcp#1'
USER : 'User1'
SESS : '1'
STATE: 'Active'
TYPE : 'rdpwd'
------------------------------
INPUT: ' rdp-tcp#0 user2 2 Active rdpwd '
DESC : '0;user2;2;Active;rdpwd;rdp-tcp#0;'
CURR : '0'
NAME : 'rdp-tcp#0'
USER : 'user2'
SESS : '2'
STATE: 'Active'
TYPE : 'rdpwd'
------------------------------
INPUT: ' console 3 Conn '
DESC : '0;-;3;Conn;-;console;'
CURR : '0'
NAME : 'console'
USER : '-'
SESS : '3'
STATE: 'Conn'
TYPE : '-'
------------------------------
INPUT: ' rdp-tcp 65536 Listen '
DESC : '0;-;5536;Listen;-;rdp-tcp;'
CURR : '0'
NAME : 'rdp-tcp'
USER : '-'
SESS : '5536'
STATE: 'Listen'
TYPE : '-'
------------------------------