远程桌面会话断开后,是否可以(通过组策略等)自动将控制台会话恢复到 Windows 8.1 PC?
我知道您可以在 RDP 会话期间运行命令“tscon 1 /dest:console”来断开连接并重新连接控制台会话,但是是否可以自动完成此操作?
答案1
创建一个包含以下内容的批处理文件,命名为 restore_console.bat:
@echo off
set LOG_FILENAME=%TEMP%\restore_console_log.txt
echo Script executed at %TIME% > %LOG_FILENAME%
echo qwinsta: >> %LOG_FILENAME%
qwinsta >> %LOG_FILENAME%
echo Checking for pending connection... >> %LOG_FILENAME%
for /f %%i in ('qwinsta ^| findstr /r /C:"^ [ ]*[0-9][0-9]* Disc"') do (
echo Pending connection detected, finishing. >> %LOG_FILENAME%
goto end
)
echo Checking for disconnection... >> %LOG_FILENAME%
for /f "tokens=2" %%i in ('qwinsta ^| findstr /r /I /C:"^ [ ]*[^ ][^ ]* [ ]*[0-9][0-9]* Disc"') do (
echo Redirecting session id %%i >> %LOG_FILENAME%
tscon %%i /dest:console /v >> %LOG_FILENAME%
goto end
)
:end
在任务计划程序中,创建一个新任务,并具有以下设置:
- 常规->无论用户是否登录都运行,以最高权限运行。
- 触发器 -> 新建 -> 断开与用户会话的连接、任何用户、来自远程计算机的连接
- 操作 -> 新建 -> 启动程序 -> 程序/脚本:<您的批处理文件>
- 其余一切默认。
实施注意事项:
这通过 findstr 正则表达式解析 qwinsta 输出来实现,即从此处的第 3 行提取 ID:
SESSIONNAME USERNAME ID STATE TYPE DEVICE >services 0 Disc ###### 2 Disc console 7 Conn #############... 65536 Listen rdp-tcp 65537 Listen
中间的块是必要的,因为出于某种原因,计划任务在连接和断开连接时都会执行。发生这种情况时,输出将采用以下形式:
SESSIONNAME USERNAME ID STATE TYPE DEVICE >services 0 Disc ###### 2 Disc 3 Disc console 8 Conn #############... 65536 Listen rdp-tcp 65537 Listen
因此我们从第 4 行开始寻找模式线。
- 它将日志信息转储到 %TEMP%\restore_console_log.txt,这不是必需的,但如果脚本不起作用,它很有用。如果没有日志记录,它将只有几行。
这对我来说在单台 Windows 8.1 机器上运行良好 - 我不知道它是否可以在全球范围内推广。
答案2
@Kim 的回答很棒。不幸的是,微软似乎无法在 Windows 10 中启动远程连接/断开连接的计划任务。无论我做什么,我都无法在通过远程桌面连接或断开连接时运行任何任务,更不用说这个任务了。
幸运的是,触发一般事件仍然有效。关于远程桌面断开连接事件记录在哪里的问题给了我一个起点,通过反复试验,我找到了正确的答案。
将触发器从日志“Microsoft-Windows-TerminalServices-LocalSessionManager/Operational”、源“TerminalServices-LocalSessionManager”、事件 ID“24”更改为“发生事件时”。(我最初推荐 40 - 两者似乎都有效,但 40 有点嘈杂,可能在断开连接时多次发生。如果 24 不起作用,请尝试 40 并告诉我们。)参见下面的屏幕截图。
答案3
我知道这有点过时了,但应该可以编写一个快速的 Windows 服务来监控连接并在发现 RDP 现在处于断开连接状态时恢复控制台会话。稍微省力一点的是使用批处理文件利用 srvany 将其作为服务运行,只需让它监控从 qwinsta 返回的值即可。
我建议将批处理/srvany 作为状态机执行。首先,批处理文件监视 RDP 连接并持续监视直到发现连接。然后它进入下一个状态,等待该 RDP 会话完成。当它检测到会话已断开连接(未注销)时,它会进入最终状态,即将该会话恢复到控制台。最后,它返回到监视 RDP 会话的原始状态。
我并不是说这很容易,但应该是可以的。我主要想提出这个建议是因为您的“tscon [sessionID] /dest:console”让我省了很多心。