mcpField
W
windows-remote-desktop-connection-doctor

windows-remote-desktop-connection-doctor

github.com/daymade云与 DevOps1.5k813 次安装今天更新
代码仓库

关于 windows-remote-desktop-connection-doctor

用于在 macOS 上排查 Windows App 远程桌面连接问题,涵盖 AVD 系列云桌面和直连 PC。它结合网络检查、客户端日志分析及独立 RDP 探测,帮助区分可能原因并指导修复。

主要功能

  1. 01诊断 AVD 和直连 PC
  2. 02检查网络、VPN 与代理
  3. 03分析 Windows App 日志
  4. 04独立探测 RDP 服务端
  5. 05基于证据判断原因并指导修复

适用场景

  1. 01调查 AVD 连接退回 TCP 或 WebSocket 的情况
  2. 02检查 VPN 或 UDP 限制对 Shortpath 的影响
  3. 03诊断直连 PC 卡在连接配置阶段的问题
  4. 04区分客户端身份验证故障与服务端可达性问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/daymade/claude-code-skills --skill windows-remote-desktop-connection-doctor

安装后在 Claude Code 中输入/windows-remote-desktop-connection-doctor确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
avd_transport_protocols.md
direct_pc_and_auth_diagnostics.md
windows_app_log_analysis.md
scripts/
probe_rdp_server.py

详细介绍

Windows 远程桌面连接诊断工具

在 macOS 上诊断并修复 Windows App(Microsoft Remote Desktop / AVD / WVD / W365 / 直接连接 PC)的连接问题,重点关注传输协议优化和根因证伪。

方法论基础: 通用的、以证据为依据的诊断规范见 debugging-network-issues 技能。此技能是 Windows App / AVD 传输的领域层——它更侧重于连接质量优化,而非根因证伪,因此与通用方法的重合较少。

背景

Azure Virtual Desktop 的传输优先级:UDP Shortpath > TCP > WebSocket。UDP Shortpath 可提供最佳体验(延迟最低,支持 UDP Multicast)。如果 UDP Shortpath 失败,客户端会回退到通过网关使用 TCP 443 的 WebSocket,从而显著增加延迟。

直接连接 PC 使用基于 TCP 3389 的标准 RDP(通常由 TLS 封装)。这类连接没有“连接信息”面板、没有网关可达性测试,也无需进行传输优化。对于直接连接 PC,主要故障模式包括:

  1. 远程 PC 已关机或无法访问(网络/防火墙问题)。
  2. Windows App 客户端中的 Microsoft 工作或学校帐户已过期或信息陈旧,导致身份验证协调流程出错,连接卡在“正在配置远程 PC…”。
  3. 远程 PC 已重启(通常由 Windows Update 触发),而客户端无法正常恢复连接。

此技能涵盖这两种场景。

诊断工作流

步骤 1:确定连接类型和症状

收集证据前,先确定要诊断的场景:

场景主要特征主要证据来源
AVD/WVD/W365用户通过工作区/网关连接到云桌面“连接信息”面板、网关运行状况检查、UDP Shortpath 日志
直接连接 PC用户通过主机名或 IP 连接到指定 PC(例如,家用工作站)RDP 协议探测、Windows App 日志中的身份验证链、Windows 端重启事件

对于 AVD/WVD/W365,请让用户提供 Windows App 中的“连接信息”(点击工具栏中的信号图标)。需要提取的关键字段:

字段含义
传输协议当前传输方式:UDP、UDP Multicast、WebSocket 或 TCP
往返时间(RTT)端到端延迟,单位为 ms
可用带宽当前带宽,单位为 Mbps
网关AVD 网关主机名和端口
服务区域Azure 区域代码(例如,SEAS = 东南亚)

如果传输协议为 UDP 或 UDP Multicast,则连接已达到最佳状态——无需进一步诊断。

如果传输协议为 WebSocket 或 TCP,请继续执行步骤 2。

对于直接连接 PC,“连接信息”面板不存在。请改为先运行步骤 2E 中的 RDP 协议探测,确认服务器可访问,然后分析 Windows App 日志,查找身份验证异常或重新连接失败。如果进度对话框卡在“正在配置远程 PC…”,应优先怀疑客户端身份问题(见类别 E)。

步骤 2:收集网络证据

并行收集证据——不要妄下结论。同时运行以下检查:

2A:网络接口和路由
ifconfig | grep -E "^[a-z]|inet |utun"
netstat -rn | head -40
scutil --proxy

请查找:

  • utun 接口:识别 VPN/代理 TUN 隧道(ShadowRocket、Clash、Tailscale)
  • 默认路由优先级:确定哪个接口处理默认流量
  • 分流路由:0/1 + 128.0/1 → utun 模式表示 VPN 正在捕获所有流量
  • 系统代理:是否在 localhost 端口启用了 HTTP/HTTPS 代理
2B:RDP 客户端进程和连接
# Find the Windows App process (NOT "msrdc" — the new client uses "Windows" as process name)
ps aux | grep -i -E 'msrdc|Windows' | grep -v grep
# Check its network connections
lsof -i -n -P 2>/dev/null | grep -i "Windows" | head -20
# Check for UDP connections
lsof -i UDP -n -P 2>/dev/null | head -30

需要查找的关键信息:

  • 源 IP 198.18.0.x:流量正通过 ShadowRocket/代理 TUN 隧道进行路由
  • 没有来自 Windows 进程的 UDP 连接:Shortpath 尚未建立
  • 只有 TCP 443:已回退到网关 WebSocket 传输
2C:VPN/代理状态
# Environment proxy variables
env | grep -i proxy
# System proxy via scutil
scutil --proxy
# ShadowRocket config API (if accessible on local network)
NO_PROXY="<local-ip>" curl -s --connect-timeout 5 "http://<local-ip>:8080/api/read"
2D:Tailscale 状态(如果正在运行)
tailscale status
tailscale netcheck

netcheck 输出会显示 NAT 类型(MappingVariesByDestIP)、UDP 支持情况和公网 IP;即使问题与 Tailscale 无关,这些信息也很有价值。

2E:独立检查 RDP 服务端运行状况(直连 PC)

这一步对 直连 PC 至关重要,也可用于 AVD/WVD/W365 的证伪测试:它能证明服务端 RDP 协议栈运行正常,无需依赖 Windows App 客户端或任何凭据。

使用随附的探测脚本:

python3 scripts/probe_rdp_server.py <host> [port]

示例:

python3 scripts/probe_rdp_server.py my-pc.local 3389

探测成功时会报告 RDP server <host>:<port> is reachable and healthy (RDP + TLS).,这意味着问题出在 客户端(身份验证、应用状态、代理或身份)。探测失败则意味着问题出在 服务端或网络(PC 已关机、防火墙、端口不可达、TLS 拦截)。

有关探测结果的详细解读,请参阅 references/direct_pc_and_auth_diagnostics.md。

第 3 步:分析 Windows App 日志

这是最关键的一步。Windows App 日志包含网络层测试无法揭示的传输协商详情。

macOS 上的日志位置:

~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows App/

文件名格式为:com.microsoft.rdc.macos_v<version>_<date>_<time>.log

**重要提示:**Windows App 日志时间戳采用 UTC。用户的时钟和 Windows 事件日志通常使用本地时间。构建时间线之前,请将所有时间戳转换为同一时区。

**按会话跟踪:**每次连接尝试都会获得一个以大括号括起的唯一活动 GUID。按 GUID 汇总事件,以了解单次尝试的生命周期。有关 GUID 汇总方法,请参阅 references/windows_app_log_analysis.md;有关直连 PC 故障特征,请参阅 references/direct_pc_and_auth_diagnostics.md。

有关详细的日志解析指南,请参阅 references/windows_app_log_analysis.md。

快速搜索日志
LOG_DIR=~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows\ App
# Find the most recent log
LATEST_LOG=$(ls -t "$LOG_DIR"/*.log 2>/dev/null | head -1)

# Search for transport-critical entries (filter out noise)
grep -i -E "STUN|TURN|VPN|Routed|Shortpath|FetchClient|clientoption|GATEWAY.*ERR|Certificate.*valid|InternetConnectivity|Passed URL" "$LATEST_LOG" | grep -v "BasicStateManagement\|DynVC\|dynvcstat\|asynctransport"
关键日志模式
日志模式含义
Passed: InternetConnectivity运行状况检查已成功完成
TCP/IP Traffic Routed Through VPN: No/Yes客户端检测到 TCP 流量通过 VPN 路由
STUN/TURN Traffic Routed Through VPN: Yes客户端检测到 STUN/TURN 流量通过 VPN 路由
Passed URL: https://...wvd.microsoft.com/ Response Time: Nms已确认网关可达
FetchClientOptions exception: Request timed out**关键:**客户端无法从网关获取传输选项
Certificate validation failed检测到 TLS 拦截或 DNS 污染
OnRDWebRTCRedirectorRpc rtcSession not handled客户端未处理 WebRTC 会话设置
OneAuthError_InteractionRequired无法静默刷新缓存的 Microsoft 帐户令牌
No valid refresh tokens available in the cache身份验证请求没有可用的缓存凭据
credential completion has been canceled交互式登录提示已取消
GATEWAY(ERR): ... UserCancelled(8)登录已取消,导致身份验证协调失败
RDP_WAN: Client connMonitor goto CMSTATE_DROPPED连接监视器检测到会话已断开
Channel::StartWrite failed / GetBuffer failed传输已中断;客户端正在向已关闭的套接字写入数据
ParseUserData: No data of type 0xc09非致命——服务端已响应 MCS Connect;这证明 TCP 通路正常
IHAddMouseEventToPDU / IHAddMouseWheelEventToPDU会话正常运行并正在接收输入
比较正常与异常日志

如果条件允许,请将连接正常时(UDP)的日志与当前日志进行比较:

# Compare startup health check blocks
for f in "$LOG_DIR"/*.log; do
  echo "=== $(basename "$f") ==="
  grep -E "InternetConnectivity|Routed Through VPN|Passed URL|FetchClient" "$f" | head -10
  echo ""
done

正常日志会包含完整的运行状况检查区块(InternetConnectivity、VPN 路由检测、网关 URL 测试)。异常日志可能完全缺少这些条目,或者显示证书错误或超时错误。

第 4 步:确定根本原因

根据收集到的证据,确定根本原因类别:

类别 A:VPN/代理干扰

证据:Windows App 源 IP 为 198.18.0.x,STUN/TURN 经 VPN 路由,没有 UDP 连接。

修复方法:在代理工具中为 AVD 流量添加 DIRECT 规则:

DOMAIN-SUFFIX,wvd.microsoft.com,DIRECT
DOMAIN-SUFFIX,microsoft.com,DIRECT
IP-CIDR,13.104.0.0/14,DIRECT

验证方法:暂时禁用 VPN/代理,重新连接 VDI,检查传输方式是否切换为 UDP。

类别 B:ISP/网络限制 UDP

证据:即使关闭所有 VPN,仍使用 WebSocket。没有 UDP 连接。FetchClientOptions 超时。

验证方法:

# Test STUN connectivity to a known server
python3 -c "
import socket, struct, os
header = struct.pack('!HHI', 0x0001, 0, 0x2112A442) + os.urandom(12)
for srv in [('stun.l.google.com', 19302), ('stun1.l.google.com', 19302)]:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.settimeout(3)
        s.sendto(header, srv)
        data, addr = s.recvfrom(1024)
        print(f'STUN from {srv[0]}: OK')
        s.close(); break
    except: print(f'STUN from {srv[0]}: FAILED'); s.close()
"

修复选项:

  • 尝试使用手机热点(将家庭网络与 ISP 隔离)
  • 检查路由器 NAT 类型(优先使用 Full Cone NAT)
  • 在路由器上启用 UPnP
  • 如果可用,尝试使用 IPv6
  • 联系 ISP,询问 UDP 限制
类别 C:客户端运行状况检查失败

证据:日志显示启动时出现证书验证错误,日志中缺少运行状况检查部分(InternetConnectivity、STUN/TURN 检测),FetchClientOptions 超时。

这意味着客户端无法完成诊断/功能发现,导致 Shortpath 协商无法进行。

可能原因:

  • ISP HTTPS 拦截/MITM(尤其是在中国)
  • DNS 污染,导致 Microsoft 诊断端点返回错误 IP
  • 防火墙阻止 Microsoft 遥测端点

修复选项:

  • 将 DNS 更改为 8.8.8.8 或 1.1.1.1(绕过 ISP DNS)
  • 通过干净的代理路由 Microsoft 流量
  • 检查 ISP 是否注入证书
类别 D:服务器端未启用 Shortpath

证据:日志中完全没有 STUN/TURN 或 Shortpath 相关条目(连检测记录也没有),但运行状况检查通过且没有错误。

这意味着 AVD 主机池未启用 RDP Shortpath。需要管理员在 Azure 门户中进行操作。

类别 E:客户端身份/过期 Microsoft 帐户污染(直连 PC 和 AVD)

证据:RDP 协议探测成功(服务器运行正常),但 Windows App 日志显示 OneAuth/MSAL 链中出现以下记录:

  • OneAuthError_InteractionRequired
  • No valid refresh tokens available in the cache
  • AcquireTokenInteractively
  • credential completion has been canceled
  • User canceled sign in
  • GATEWAY(ERR): CWVDTransport::OnOrchestrationHttpError error: UserCancelled(8)
  • Fail OnDisconnected call

进度对话框可能一直停留在“正在配置远程 PC……”,因为应用正在等待一个被隐藏或取消的交互式登录提示。即使过期帐户与该 PC 无关,这也可能影响直连 PC,因为 Windows App 客户端在所有连接类型中共用同一身份验证编排流程。

修复方法:打开 Windows App → Settings → Accounts,退出或移除过期的 Microsoft 工作或学校帐户,然后完全退出应用(Cmd+Q)并重新启动。再次尝试连接。

完整的特征集和故障排除步骤请参阅 references/direct_pc_and_auth_diagnostics.md。

类别 F:服务器端重启/Windows Update

证据:之前正常工作的会话突然断开,随后无法重新连接。Windows App 日志显示 CMSTATE_DROPPED,可能还会出现 Channel::StartWrite failed。Windows PC 的 LastBootUpTime 与断开时间接近,且事件 ID 1074 显示 MoNotificationUx.exe(Windows Update 协调程序)或其他计划重启原因。

修复方法:等待 PC 完成启动,然后重新连接。要避免再次发生,请在 Windows Update 设置中设置活动时间/禁用活动时间内自动重启,或安排在用户不使用计算机时重启。

如果你有管理员权限,可使用 Get-CimInstance Win32_OperatingSystem 获取 LastBootUpTime,并使用 Get-WinEvent 查询事件 ID 1074。有关 WSL/SSH 编码命令技巧,请参阅 references/direct_pc_and_auth_diagnostics.md。

第 5 步:验证修复

应用修复后,重新连接并验证相应症状:

对于 AVD/WVD/W365:

  1. 查看“连接信息”——传输协议应显示为 UDP 或 UDP Multicast。
  2. RTT 应显著降低(例如,从 165ms 降至 40-60ms)。
  3. 使用 lsof 验证:
lsof -i UDP -n -P 2>/dev/null | grep -i "Windows"
# Should show UDP connections if Shortpath is active

对于 Direct PC:

  1. 进度对话框应消失,且会话窗口应显示。
  2. 新会话的 Windows App 日志应显示鼠标/键盘输入事件(IHAddMouseEventToPDU、IHAddKeyboardEventToPDU),且没有 UserCancelled(8) 错误。
  3. 如果问题由已过期的 Microsoft 账户导致,请确认 Windows App →“设置”→“账户”中只保留有效账户。

对于服务器重启:

  1. 使用 ping 和 scripts/probe_rdp_server.py 验证 PC 是否重新可访问。
  2. 确认 LastBootUpTime 是最近的,且与服务中断时段相符。

参考资料

评论

支持 Markdown