多用户如何同时登录操作 Windows ?为原生 RDP 远程桌面添加多会话支持

742

前言

RDP (Remote Desktop Services)是 Windows 下原生的远程桌面连接工具,使用开始菜单 -> 运行 -> mstsc 操作打开,一般在局域网内使用。若要在公网环境条件下使用,通常要使用内网穿透工具,如 frp 等,将本机 3389 端口映射到公网 IP 下去访问。在同等网络条件下,其流畅度,画质,兼容性等足以秒杀其他远程桌面工具。其次,RDP 登录会话是单向的,在远程操作的时候,被控端屏幕无法看到主控端远程的桌面,一定程度上能保护隐私。
一般情况下,RDP 只支持单个会话,当主控端发起远程连接时,被控端会被“挤出”锁屏界面,即使两端使用不同账户进行登录,也仅能维持单一会话。多用户可以同时登录操作 Windows 吗?答案是可以的,要使用原生的支持需要使用 Server 版的 Windows,并修改组策略去开启。本章讨论其他两种方法。

前置步骤

修改 RDP 连接数上限

  1. 开始 -> 运行 -> gpedit.msc ,打开组策略编辑器
  2. 进入目录 计算机配置 -> 管理模板 -> Windows 组件 -> 远程桌面服务 -> 远程桌面会话主机 -> 连接
  3. 选择 限制连接的数量,选择已启动,修改数量为 2

方法一:使用工具 RDPWrap

  1. Release 页面下载工具,并运行 install.bat 安装
  2. 下载最新的 rdpwrap.ini ,覆盖至 C:\Program Files\RDP Wrapper\rdpwrap.ini
  3. 运行 RDPConfig.exe,勾选 Single session per user
  4. 如果 Diagnostics 里面所有属性都是绿色,并且显示 [Fully supported] 则 RDPWrap 设置生效

Diagnostics 中显示红色 [not supported] 的解决办法

  1. 开始 -> 运行 -> gpedit.msc,复制第一行的版本号,如 10.0.22621.2283
  2. 打开 C:\Program Files\RDP Wrapper\rdpwrap.ini,在最底行添加两个分组,底下属性部分复制粘贴最新的一条版本号的配置
[10.0.22621.2283]
...
[10.0.22621.2283-SLInit]
...

方法二:对 Termsrv.dll 打补丁

替换规则

使用十六进制编辑器,如 Tiny Hexer,打开位于 C:\Windows\System32 的 termsrv.dll 文件,按照规则替换文件字符,即可开启 RDP 多会话支持

Windows buildFind the stringReplace with
Windows 11 22H239 81 3C 06 00 00 0F 84 75 7A 01 00B8 00 01 00 00 89 81 38 06 00 00 90
Windows 10 22H239 81 3C 06 00 00 0F 84 85 45 01 00同上
Windows 11 21H2 (RTM)39 81 3C 06 00 00 0F 84 4F 68 01 00同上
Windows 10 x64 21H239 81 3C 06 00 00 0F 84 DB 61 01 00同上
Windows 10 x64 21H139 81 3C 06 00 00 0F 84 2B 5F 01 00同上
Windows 10 x64 20H239 81 3C 06 00 00 0F 84 21 68 01 00同上
Windows 10 x64 200439 81 3C 06 00 00 0F 84 D9 51 01 00同上
Windows 10 x64 190939 81 3C 06 00 00 0F 84 5D 61 01 00同上
Windows 10 x64 190339 81 3C 06 00 00 0F 84 5D 61 01 00同上
Windows 10 x64 180939 81 3C 06 00 00 0F 84 3B 2B 01 00同上
Windows 10 x64 18038B 99 3C 06 00 00 8B B9 38 06 00 00同上
Windows 10 x64 170939 81 3C 06 00 00 0F 84 B1 7D 02 00同上

使用脚本进行替换

将以下脚本保存为 patch.ps1 文件,打开管理员权限的 powershell 终端,执行命令 Set-ExecutionPolicy RemoteSigned 获得权限,再使用 “.\patch.ps1”执行如下脚本

# PowerShell script used to patch termsrv.dll file and allow multiple RDP connections on Windows 10 (1809 and never) and Windows 11 
# Details here http://woshub.com/how-to-allow-multiple-rdp-sessions-in-windows-10/


# Stop RDP service, make a backup of the termsrv.dllfile and change the permissions 
Stop-Service UmRdpService -Force
Stop-Service TermService -Force
$termsrv_dll_acl = Get-Acl c:\windows\system32\termsrv.dll
Copy-Item c:\windows\system32\termsrv.dll c:\windows\system32\termsrv.dll.copy
takeown /f c:\windows\system32\termsrv.dll
$new_termsrv_dll_owner = (Get-Acl c:\windows\system32\termsrv.dll).owner
cmd /c "icacls c:\windows\system32\termsrv.dll /Grant $($new_termsrv_dll_owner):F /C"
# search for a pattern in termsrv.dll file 
$dll_as_bytes = Get-Content c:\windows\system32\termsrv.dll -Raw -Encoding byte
$dll_as_text = $dll_as_bytes.forEach('ToString', 'X2') -join ' '
$patternregex = ([regex]'39 81 3C 06 00 00(\s\S\S){6}')
$patch = 'B8 00 01 00 00 89 81 38 06 00 00 90'
$checkPattern=Select-String -Pattern $patternregex -InputObject $dll_as_text
If ($checkPattern -ne $null) {
    $dll_as_text_replaced = $dll_as_text -replace $patternregex, $patch
}
Elseif (Select-String -Pattern $patch -InputObject $dll_as_text) {
    Write-Output 'The termsrv.dll file is already patched, exiting'
    Start-Service UmRdpService
		Start-Service TermService
    Exit
}
else { 
    Write-Output "Pattern not found "
    Start-Service UmRdpService
		Start-Service TermService
		Exit
}
# patching termsrv.dll
[byte[]] $dll_as_bytes_replaced = -split $dll_as_text_replaced -replace '^', '0x'
Set-Content c:\windows\system32\termsrv.dll.patched -Encoding Byte -Value $dll_as_bytes_replaced
# comparing two files 
fc.exe /b c:\windows\system32\termsrv.dll.patched c:\windows\system32\termsrv.dll
# replacing the original termsrv.dll file 
Copy-Item c:\windows\system32\termsrv.dll.patched c:\windows\system32\termsrv.dll -Force
Set-Acl c:\windows\system32\termsrv.dll $termsrv_dll_acl
Start-Service UmRdpService
Start-Service TermService

Windows 更新后多会话失效的解决方法

windows 小版本更新后,termsrv.dll 文件可能会被覆盖更新。可将如下脚本保存为 cmd 或 bat 文件添加至启动项或添加为计划任务自动去为 termsrv.dll 文件打补丁(路径“C:\Portable\RdpPatch\termsrv_rdp_patch.ps1”替换为 ps1 脚本路径)

PowerShell -NoProfile -ExecutionPolicy Unrestricted -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Unrestricted -File "" C:\Portable\RdpPatch\termsrv_rdp_patch.ps1 ""' -Verb RunAs}" ;

参考资料