Windows 10/rdp

Windows 10/rdp

Enable

rdp 服务:Remote Desktop Services (TermService)

sc query TermService

推荐(默认)选中 allow connections only with Network Level Authentication (NLA only)

除了 administrators 组以外的用户必须手工加入允许 rdp 连接的用户列表。

多用户 / 多会话连接 rdp

非 Server 版本的 Windows 系统同一时间只支持1个用户使用桌面,即包括 console 和 rdp 在内的只能有1个 (GUI) session 运行。如果当前有用户正在使用 rdp, 其他用户连接 rdp 时会断开之前用户的 rdp 桌面。

有两种方式可以突破这个限制:修改 Windows rdp 使用的 termsrv.dll 库解除限制;或者使用 RDPWrap 这个第三方工具。

Patch %WINDIR%/system32/termsrv.dll (recommend)

推荐使用这种方法。缺点是 Windows 更新时如果升级了termsrv.dll会失效,需要重新 patch。

右键属性查看 %WINDIR%/system32/termsrv.dll 文件的 dll 版本号。然后到网上找对应版本号 termsrv.dll 的修改字节位置。可以直接用 UltraEdit 等 hex 编辑工具修改。也可以使用 hexreplace 之类的工具自动搜索替换 hex。

x64 10.0.17763.771 (Windows 10 LTSC 1809, released in 2018-11-13):
For multiple users w/single session per user - patch termsrv.dll directly:

39813C0600000F84CB2B0100 -> B80001000089813806000090

39 81 3C 06 00 00 0F 84 CB 2B 01 00 -> B8 00 01 00 00 89 81 38 06 00 00 90

x64 10.0.17763.1613 (Win10 2019 LTSC, after Dec,2020 update):

Patch concurrents
replace 39813C0600000F84998F0100 --> B80001000089813806000090
multisessions
replace C706010000008BDF ---> C706000000008BDF\

hexreplace -o 39813C0600000F84998F0100 -n B80001000089813806000090 termsrv.dll termsrv.mod.dll

网上有1个 Universal Termsrv.dll Patch 工具可以自动修改 Termsrv.dll, 但已停止维护,只支持 Windows 7 等旧版本。

需要彻底禁用 UAC 才能修改系统文件。如果 rdp 服务当前正在运行,直接修改原始 termsrv.dll 或替换原文件时可能会提示文件正在使用。推荐的修改步骤:

  1. 取得 %WINDIR%/system32/termsrv.dll 文件所有权.
  2. 复制一份原始 termsrv.dll 并修改,放到某个临时位置
  3. 把 %WINDIR%/system32/termsrv.dll 直接重命名为 termsrv.bak.dll。这一步即使dll正在被使用也能完成。
  4. 将修改后的 termsrc.dll 复制或移动到 %WINDIR%/system32/ 目录下。
  5. 在 services.msc 里重启 rdp 服务使修改生效。

RDPWrap

rdpwrap (Downloads)

推荐下载 RDPWrap-v1.6.2.zip 版本,运行 install.bat 安装。RDPConf.exe 进行配置和检测状态。RDPCheck.exe 测试。

最新版本里的配置文件 rdpwrap.ini 较旧,不支持 LTSC 2019 或其他较新的 Windows 10。(表现为 RDPConf.exe 里的 Listener state 显示为红色 not supported) (LTSC 2009 的 RDP 版本是 10.0.17763.771)

安装后需要修改:

%PROGRAMFILES%\RDP Wrapper\rdpwrap.ini

替换为网上最新的 rdpwrap.ini 内容。比如 这里这里 提供的 rdpwrap.ini。建议直接修改原 rdpwrap.ini 文件;如果替换文件,需要先停止 rdp 服务。

修改 rdpwrap.ini 文件后需要重启 rdp 服务以生效:

services.msc => Restart "Remote Desktop Services"

或使用以下命令:(如果当前在 rdp 里操作,保存为 bat 后执行,否则第1个命令执行后服务断开了就连不上了)

sc stop TermService
sc start TermService

RDPWrap config 选项

Single User Per Session: 是否仅允许单用户1个session。推荐选中。

如果去掉勾选,单用户可以启动多个 session,就有点类似于 tmux 的 attach 了

但是一个用户多 session 会导致一些自启动的服务于被启动两次,这就鬼扯了。

如果一个用户多个 session 被允许了,那么桌面用户登录的时候会新启动一个 session, 不能选已有的 session 。

浏览器多窗口

截止目前(2022-01) Chrome / FireFox / Edge 等浏览器均不支持同一用户多个 rdp session 各自打开浏览器。如果某用户已经在某个 rdp session 里打开了一个浏览器窗口,在该用户的其他 rdp session 里尝试打开浏览器时:Chrome 无反应;FireFox 会提示关闭其他 rdp session 里的会话才能打开。

Workaround 是为每个 rdp session 里的 Chrome 指定独立的 profile。

I created HKLM\Software\Policies\Google\Chrome added String Value UserDataDir with data of "C:\ChromeProfiles\${session_name}" (no quotes). Upon opening Chrome, I see C:\ChromeProfiles\RDP-Tcp#2 (for example) related to the RDP session of each user. 

As session IDs are recycled, I am curious what happens to these folders. This should still resolve the issue, as only one RDP-Tcp#2 can exist at any time.
Again, thank you for your guidance and work on this project.

Yes if these folders are not periodically cleared you will get the same profiles to appear again and again for possibly different users. It would be good to have a logout script to delete the contents of the ChromeProfiles folder to reduce this effect if you are concerned about it or configure the ephemeral profiles policy so that they get cleared automatically for each user.

Config

组策略可以配置 rdp 超时设置:(默认无限制)

  • rdp session 空闲(idle) 多长时间后自动 disconnect (空闲指rdp session无鼠标和键盘操作输入)
  • rdp session disconnect 多长时间后自动 sign off 用户

组策略位置有2个,分别对应“计算机全局配置”和“用户个人配置”:(如果2个里面都设,只有计算机全局配置生效)

  • Local Computer Policy / Computer Configuration / Administrative Templates / Windows Components / Remote Desktop Services / Remote Desktop Session Host / Session Time Limits
  • User Configuration / Computer Configuration / Administrative Templates / Windows Components / Remote Desktop Services / Remote Desktop Session Host / Session Time Limits

如果需要设置(非当前登录用户)其它用户的组策略用户配置(比如 users 组里的用户无权打开 gpedit.msc, 无法自行设置自己用户的组策略),操作步骤如下:(仅限管理员操作)

  1. mmc.exe
  2. File => Add/Remove Snap-in => Under "Available snap-ins," select Group Policy Object Editor, Click the Add button
  3. Click the Browse button
  4. Click the Users tab, which will display the users and groups compatible with Local Group Policy;
  5. Depending on what you're trying to accomplish, select the user or group of users to which you want to apply a particular setting.
  6. Click OK. Click Finish. Click OK.

然后可以在左侧边栏浏览和编辑选中的用户的 User Configuration 组策略设置。

可选的,可以通过 File - Save as 将当前 console 保存为一个文件,下次可以直接 File - Open 打开这个文件以直接查看或编辑此用户的组策略。

测试更改这几项组策略设置后需要重启 rdp 服务生效。

如果需要在rdp inactive / idle 超过一定时间后执行某个任务(而不是直接 disconnect),可以用 taskschd.msc 计划任务管理器的 "On disconnect from user session" trigger

常见问题

多用户连接 rdp 进去有时黑屏问题

参考这里这里

Workaround: one line registry then reboot

reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fEnableWddmDriver /t reg_dword /d 0 /f

it seems last updates can use wddm drivers causing dwm.exe cpu high or hang system , when two remote users close session without log out and if one user close session without log out, no hang, but if reconnect to existing session , system hang on VM.

It works for me now, disabling that new setting using this GPO: https://answers.microsoft.com/en-us/windows/forum/all/dwmexe-high-cpu-one-core-on-target-system-after/dbce0938-60c5-4051-81ef-468e51d743ab

或修改组策略:

Group Policy Editor - Local Computer Policy - Computer Configuration - Administrative Templates - Windows Components - Remote Desktop Services - Remote Desktop Session Host - Remote Session Environment - Use WDDM graphics display driver for Remote Desktop Connections: DISABLED

"出现了内部错误"

远程桌面服务器端,Win + R 运行 - gpedit.msc 组策略 - 计算机配置 - 管理模板 - windows组件 - 远程桌面服务 - 远程桌面会话主机 - 安全 - “远程(RDP)链接要求使用制定的安全层” - 设为"已启用",安全层设为 "RDP"。

rdp.reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]
"SecurityLayer"=dword:00000000

Last update: 2022-01-05 06:39:38 UTC