修复远程桌面
$ws = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations'
$current = (
Get-ItemProperty `
-Path $ws `
-Name 'SelfSignedCertStore' `
-ErrorAction SilentlyContinue
).SelfSignedCertStore
if ($current -ne 'Remote Desktop') {
New-ItemProperty `
-Path $ws `
-Name 'SelfSignedCertStore' `
-PropertyType String `
-Value 'Remote Desktop' `
-Force |
Out-Null
Write-Host "已修复:SelfSignedCertStore = Remote Desktop" -ForegroundColor Green
}
Write-Host "当前值:" -ForegroundColor Cyan
(Get-ItemProperty $ws).SelfSignedCertStore
Write-Host "请重启 Windows。" -ForegroundColor Yellow
使用方法:先在 Windows 设置中正常开启“远程桌面”,然后以管理员身份打开 PowerShell,复制上面的代码执行。执行完成后重启 Windows,再尝试远程桌面连接。
一、问题现象
我在 VMware 中全新安装 Windows 10 Enterprise LTSC 2021 后,多次遇到一个比较奇怪的问题:
Windows 设置中已经开启“远程桌面”,但是其他电脑仍然无法通过 RDP 连接。
而且这个问题并不是偶发的。在相同安装环境中重新安装多台全新的虚拟机,可以稳定复现。
使用的系统镜像为:
SW_DVD9_WIN_ENT_LTSC_2021_64BIT_ChnSimp_MLF_X22-84402.ISO
虚拟机属于全新安装环境,没有使用旧系统克隆,也没有在安装后执行第三方系统优化脚本,只进行了正常的 Windows 更新。
表面上看,远程桌面已经开启:
fDenyTSConnections = 0
RDP-Tcp 的基本配置同样正常:
fEnableWinStation = 1
PortNumber = 3389
SecurityLayer = 2
Remote Desktop Services 服务也处于运行状态:
TermService = Running
但是进一步检查会发现一个关键异常:
netstat -ano -p tcp | findstr ":3389"
没有任何输出。
也就是说,虽然 Windows 设置界面显示远程桌面已经开启,但系统实际上根本没有监听 TCP 3389。
继续执行:
qwinsta
正常的远程桌面主机应该能看到类似:
rdp-tcp 65536 侦听
但故障机器中完全没有 rdp-tcp Listener。
所以这个问题与普通的“防火墙没有开放 3389”并不一样。
二、真正的问题不是网络,而是 RDP Listener 没有建立
远程桌面连接并不是只要打开 Windows 设置中的开关就一定可以工作。
一个正常的 RDP 主机,大致需要完成下面的初始化链路:
Windows 开启远程桌面
↓
允许 RDP 连接
↓
TermService 启动
↓
初始化 RDP-Tcp
↓
初始化 RDP TLS / 自签名证书
↓
创建 RDP 私钥
↓
建立 rdp-tcp Listener
↓
TCP 3389 开始 LISTENING
↓
客户端才能连接
这次遇到的问题正好卡在中间。
Windows 已经认为远程桌面被开启,TermService 也已经运行,但是 RDP-Tcp Listener 初始化没有正常完成。
因此产生了一个很容易误导人的状态:
设置 → 远程桌面 → 已开启 √
TermService → Running √
RDP-Tcp 注册表 → 已启用 √
端口配置 → 3389 √
rdp-tcp Listener ×
TCP 3389 LISTENING ×
远程连接 ×
三、事件日志中的关键错误:0x80070005
在事件查看器的以下日志中:
Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
可以反复看到:
事件 ID:17
远程桌面服务启动失败。
相关的状态代码为 0x80070005。
0x80070005 对应的是:
Access Denied
拒绝访问
说明 TermService 在进行某个初始化操作时没有正常完成。
四、发现 SelfSignedCertStore 配置缺失
继续检查:
HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations
发现:
SelfSignedCertStore
这个配置在故障机器上不存在或者为空。
正常目标值为:
SelfSignedCertStore = Remote Desktop
这个配置和 Windows Remote Desktop 使用的自签名证书存储有关。
也正是本文最上面的脚本所修复的核心配置。
五、为什么这个配置会导致 3389 完全不监听?
Windows RDP 默认需要建立自己的 TLS 环境。
在正常情况下,系统会创建 Remote Desktop 使用的自签名证书以及对应的机器私钥。
故障发生时,我进一步检查:
Cert:\LocalMachine\Remote Desktop
结果发现:
Remote Desktop 证书存储不存在
再检查:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
其中也没有 RDP 对应的机器私钥。
因此故障状态可以理解成:
SelfSignedCertStore 缺失
↓
RDP 自签名证书初始化异常
↓
RDP MachineKey 没有正常生成
↓
TermService 无法完成 RDP Listener 初始化
↓
事件日志出现 0x80070005
↓
rdp-tcp 不存在
↓
3389 不监听
↓
远程桌面无法连接
六、执行本文脚本后发生了什么?
执行本文最上面的代码后:
SelfSignedCertStore = Remote Desktop
被正确补充。
随后 Windows 自己开始生成 Remote Desktop 自签名证书。
再次检查证书时已经可以看到:
Subject : CN=计算机名
HasPrivateKey : True
同时:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
里面自动出现类似:
f686aace6942fb7f7ceb231212eef4a4_...
的 RDP MachineKey。
这里需要特别说明:
证书和私钥都不是上面的脚本人工创建的。
脚本只是恢复:
SelfSignedCertStore = Remote Desktop
这个配置,后续证书、私钥以及 RDP Listener 都是 Windows 自己按照正常机制生成和初始化的。
七、为什么一定建议重启一次 Windows?
在配置补充完成之后,并不一定会立即看到 TCP 3389 开始监听。
原因是之前运行中的 TermService 可能已经经历过一次失败的 Listener 初始化。
最干净的处理方式就是:
重启 Windows
让 Remote Desktop Services 从系统启动阶段重新进行一次完整初始化。
在实际测试中,重启以后:
qwinsta
已经出现:
rdp-tcp 65536 侦听
执行:
netstat -ano -p tcp | findstr ":3389"
出现:
TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING
再执行:
Test-NetConnection 127.0.0.1 -Port 3389
结果:
TcpTestSucceeded : True
此时局域网其他电脑即可正常使用 Windows Remote Desktop 连接。
八、如何判断自己遇到的是不是同一个问题?
如果你的 Windows 出现以下情况:
- Windows 设置中已经开启远程桌面;
- TermService 正在运行;
- 远程电脑却完全连不上;
- 本机 TCP 3389 也没有监听;
qwinsta中没有rdp-tcpListener;
那么可以先运行:
Get-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations' `
-Name SelfSignedCertStore `
-ErrorAction SilentlyContinue
如果没有看到:
SelfSignedCertStore : Remote Desktop
那么与本文遇到的问题高度相似。
九、修复以后如何验证?
重启以后,可以使用下面三个命令进行确认。
1. 检查 RDP Listener
qwinsta
正常应该包含:
rdp-tcp 65536 侦听
2. 检查 TCP 3389
netstat -ano -p tcp | findstr ":3389"
正常应该出现类似:
TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING
3. 本机测试 3389
Test-NetConnection 127.0.0.1 -Port 3389
正常结果:
TcpTestSucceeded : True
十、这个修复会不会对 Windows 产生很大影响?
这个问题排查过程中,最需要注意的是不要为了“让 RDP 先能用”而进行过度修复。
例如,一些更激进的处理方式可能会:
- 修改大量 RDP 注册表项;
- 修改服务启动类型;
- 重置 MachineKeys ACL;
- 修改系统服务账户权限;
- 把 NETWORK SERVICE 加入 Administrators;
- 强制覆盖 RDP 端口和防火墙规则。
这些方法虽然有时也能让 RDP 恢复,但会让系统偏离 Windows 默认权限模型,并且会扩大不必要的安全影响面。
经过逐项排查,本案例真正需要补充的核心配置只有:
HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations
SelfSignedCertStore = "Remote Desktop"
因此本文最终使用的脚本:
- 不修改 RDP 端口;
- 不修改 NLA;
- 不修改 SecurityLayer;
- 不修改防火墙;
- 不修改 MachineKeys ACL;
- 不修改用户权限;
- 不修改服务启动类型;
- 不把 NETWORK SERVICE 加入 Administrators;
- 不人工生成证书;
- 不人工生成 RDP 私钥。
它只是在检测到配置异常时写入:
SelfSignedCertStore = Remote Desktop
后续 RDP 自签名证书、机器私钥和 Listener 均由 Windows 自己完成初始化。
因此,相比通过修改大量 RDP 参数或者直接提高系统服务账户权限,这种处理方式对系统的改动非常小。
十一、为什么全新安装的 Windows 会出现这个问题?
这是整个问题中最值得注意的部分。
本次问题不是出现在一台使用时间很长、经过大量软件安装和系统优化的机器上,而是在相同环境下全新安装 Windows 10 Enterprise LTSC 2021 时,可以多次稳定复现。
因此基本可以排除:
- 单台虚拟机偶发损坏;
- 用户手工改坏 RDP 配置;
- 第三方优化软件导致;
- 单纯的 Windows 防火墙问题;
- VMware NAT 或桥接导致端口访问失败;
- Windows 未激活导致 RDP 被禁止。
特别是网络问题基本可以排除,因为故障状态下:
Test-NetConnection 127.0.0.1 -Port 3389
在本机都返回 False。
这说明连接请求甚至还没有到 VMware 网络、防火墙或局域网这一层,Windows 自己就没有建立 3389 Listener。
目前能够通过实际测试确认的是:
在这套安装环境中,Windows RDP 自签名证书相关配置没有正常完成初始化,其中 SelfSignedCertStore 缺失是可以稳定观察到并通过补充该配置解决的问题。
至于为什么这一项会在全新安装后缺失,目前还不能仅根据现有测试严格确定究竟是:
- LTSC 2021 安装介质本身的某个初始化路径;
- 安装完成后的 Windows Update;
- 某个特定累计更新版本;
- 系统首次启动时 RDP/证书组件初始化时序;
- 或者 LTSC 2021 与当前部署环境组合下的特殊问题。
因此不建议简单把它描述成“VMware Bug”或者“Windows LTSC 2021 必然存在的 Bug”。
更准确的说法应该是:
在本文测试的 Windows 10 Enterprise LTSC 2021 全新 VMware 安装环境中,远程桌面开启后出现了可稳定复现的 RDP Listener 初始化异常。故障机器的 SelfSignedCertStore 配置缺失,补充为 Remote Desktop 后,Windows 可以重新生成 RDP 自签名证书和 MachineKey,并在重启后恢复 rdp-tcp Listener 与 TCP 3389 监听。
十二、为什么 Windows 设置显示“远程桌面已开启”,却仍然无法连接?
这个问题最容易让人困惑。
Windows 设置中的“启用远程桌面”主要表示系统已经允许 RDP,但它并不代表底层所有组件一定初始化成功。
可以把它理解成:
“允许远程桌面” ≠ “3389 一定已经成功监听”
真正可连接还需要:
允许 RDP
+
TermService
+
RDP-Tcp
+
TLS 证书
+
MachineKey
+
Listener
+
3389
+
防火墙
+
用户权限
只要其中一个关键初始化步骤失败,就可能出现:
Windows 显示远程桌面已开启,但客户端完全无法连接。
十三、为什么本文不推荐“把 NETWORK SERVICE 加入管理员组”的做法?
在一些 RDP 修复脚本中,可能会看到类似:
Add-LocalGroupMember -Group Administrators -Member 'NT AUTHORITY\NETWORK SERVICE'
这种做法有时确实会让某些权限相关的 RDP 故障立即恢复,因为 Remote Desktop Services 的部分组件会以 NETWORK SERVICE 身份运行。
但是这种方式属于明显的过度授权。
NETWORK SERVICE 本来是一个权限受限的系统服务账户。如果把它加入本机 Administrators 组,等于让本来只应该具有有限权限的服务身份获得更高的系统权限。
这并不是修复正常 RDP 所需要的标准状态。
本次排查已经验证:
NETWORK SERVICE 不加入 Administrators
+
SelfSignedCertStore = Remote Desktop
+
重启 Windows
=
RDP 正常工作
因此没有必要为了修复 Listener 去提升 NETWORK SERVICE 的整体系统权限。
十四、修复后的机器和本来就正常的 Windows 有什么区别?
从运行结果来看,基本没有实质区别。
本文脚本不会自己创建特殊的 RDP 服务、不会替换 Windows 组件,也不会修改大量非默认参数。
脚本只是补充:
SelfSignedCertStore = Remote Desktop
随后:
- Remote Desktop 自签名证书由 Windows 自己生成;
- RDP MachineKey 由 Windows 自己生成;
- 证书私钥权限由 Windows 自己配置;
- rdp-tcp Listener 由 Windows 自己建立;
- 3389 由 Windows Remote Desktop Services 自己监听。
因此修复完成后的状态,与原本能够正常初始化 RDP 的 Windows 非常接近。
十五、建议的标准使用流程
如果你使用的环境和本文一样,并且可以稳定复现这个问题,可以按照下面的顺序处理:
1. 全新安装 Windows 10 Enterprise LTSC 2021
2. 正常进入:
设置 → 系统 → 远程桌面
3. 开启“启用远程桌面”
4. 如果无法连接,检查:
qwinsta
netstat -ano -p tcp | findstr ":3389"
5. 如果没有 rdp-tcp Listener 且 3389 不监听,
运行本文顶部最小修复脚本
6. 重启 Windows
7. 再次检查:
qwinsta
netstat -ano -p tcp | findstr ":3389"
8. 确认出现:
rdp-tcp 侦听
TCP 0.0.0.0:3389 LISTENING
9. 再从其他电脑使用 mstsc 连接
十六、总结
本次故障最典型的特点是:
Windows 10 Enterprise LTSC 2021
VMware 全新安装
远程桌面已经开启
TermService 正常运行
RDP-Tcp 注册表基本配置正常
但是没有 rdp-tcp Listener
TCP 3389 完全没有监听
事件日志出现 0x80070005
SelfSignedCertStore 缺失
最终通过补充:
SelfSignedCertStore = Remote Desktop
并重启 Windows 后:
RDP 自签名证书生成成功
↓
RDP MachineKey 生成成功
↓
rdp-tcp Listener 初始化成功
↓
TCP 3389 开始 LISTENING
↓
远程桌面恢复正常
如果你也遇到“Windows 明明已经开启远程桌面,但 3389 根本不监听”的情况,可以优先检查本文提到的 SelfSignedCertStore,而不是一开始就关闭防火墙、修改端口、重置服务权限或者把 NETWORK SERVICE 提升为管理员。
注意:本文脚本针对的是本文描述的特定故障。如果你的机器本身已经存在正常的 SelfSignedCertStore 配置、3389 已经监听,或者使用了企业自定义 RDP 证书、域策略、RDS 部署、自定义证书存储等配置,不建议为了“优化”而强制修改。排障前应先确认自己的现象是否与本文一致。
测试结论:在本文测试环境中,这个最小修复已经在多台全新安装的 Windows 10 Enterprise LTSC 2021 VMware 虚拟机中验证有效。