批处理文件仅在 RDP 会话处于活动状态时执行

Posted

技术标签:

【中文标题】批处理文件仅在 RDP 会话处于活动状态时执行【英文标题】:Batchfile execute only when an RDP session is active 【发布时间】:2020-06-24 08:23:42 【问题描述】:

背景:

我的机器上自动运行的东西在 RDP 会话处于活动状态时无法正常运行(这是因为屏幕分辨率不同),并且在本地机器被锁定时也无法正常运行。

但是,我(和其他几个人)经常通过 RDP 在该计算机上工作,但我们很容易忘记关闭 RDP 会话,因此我创建了一个计划任务,该任务在 PC 进入空闲模式时运行,从而关闭RDP 会话并再次解锁本地计算机。

下一个问题是:当没有 RDP 连接处于活动状态时,批处理文件也会运行。 借助谷歌的力量,我找到了一种在用户仅在本地登录时至少立即退出批处理文件的方法。

这就是我的批次目前的样子

for /f "tokens=2,4" %%a in ('QUERY USER ^| FINDSTR ">"') DO (

    set "consoleTemp=%%a"
    set "connectionState=%%b"
    set "consoleType=!consoleTemp:~0,7!"

)

SET consoleTypeCorrect=

IF "!consoleType!"=="console" goto closebatch
@echo =================================================
@echo ===  Remote session is closing in ONE MINUTE  ===
@echo =================================================
timeout /t 60 /nobreak
for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do (
  %windir%\System32\tscon.exe %%s /dest:console
)
Endlocal
Exit

:closebatch
Endlocal
EXIT

上面定时任务的设置是这样的: https://imgur.com/a/GMprqvz

现在,这产生了另一个问题:pc 的监视器保持打开状态,因为每次 pc 空闲时,都会运行任务,执行批处理,这显然会阻止监视器进入“睡眠”状态。 我还尝试禁用设置“唤醒计算机以运行此任务,但它不会改变此行为。

所以我的主要问题是:如何防止监视器在运行此任务时保持活动状态?或者有没有更简单的方法来实现我想要实现的整个目标?

【问题讨论】:

【参考方案1】:

这可能有效...但我还没有测试过。至少它可以帮助或给你一些想法。

关闭屏幕的部分取自这个答案https://***.com/a/60499680/3004628

@echo off
setlocal enabledelayedexpansion

:: Get local computer SESSIONS info. If find disconnected RDP session, log it off.
:: %%a:SESSIONNAME  %%b:USERNAME   %%c:SESSIONID   %%d:SESSIONSTATE
for /f "tokens=1-4" %%a in ('QUERY session') DO (
    set "sessionName=%%a"
    set "sessionName=!sessionName:>=!"
    if "!sessionName:~0,3!"=="rdp" do (
        if /I "%%d"=="Active" do (
            set "activeUsers=!activeUsers!%%b, "
        ) else (
            echo Logging of User:%%b
            logoff %%c
            timeout /t 5 /NOBREAK>
        )
    ) else (
        if /I "!sessionName!"=="console" do (
            set "consoleID=%%c"
        )
    )
)

:: If an active console user was detected send a message to their screen.
if defined consoleID (
    if defined activeUsers (
        msg %consoleID% /W The RDP users "!activeUsers:~0,-2!" are still active. All other RDP sessions have been closed.
    ) else (
        msg %consoleID% /W All other RDP sessions have been closed.
    )
)

:: If no active console user detected, run command to turn screen off.
if not defined consoleID (
    @Start "" "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -Command "(Add-Type '[DllImport(\"user32.dll\")]public static extern int SendMessage(int hWnd,int hMsg,int wParam,int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,2)"
)

endlocal
exit /B

【讨论】:

嗨,遗憾的是,这批甚至没有断开 RDP,所以我不能说锁屏是否有效 要测试发生了什么,请删除 @echo off 行,然后在您指向此批处理文件的计划任务中,将 `>>%temp%\RDPsessionCloseLog.txt` 添加到末尾.这应该仍然运行批处理文件,但将所有命令和错误输出到日志文件以检查什么不起作用。

以上是关于批处理文件仅在 RDP 会话处于活动状态时执行的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 和 Android 的给定时间检测用户是不是仅在一台设备上处于活动状态

仅在选项卡处于活动状态时加载数据?

保持远程桌面会话“活动”[关闭]

服务器断开连接后如何在 Spring MVC 中保持客户端会话处于活动状态

在运行bat批处理文件时echo处于关闭状态如何解决

当用户会话处于活动状态时使用 Laravel 5.7 中的 Auth 重定向到页面的方法