windows-remote-desktop-connection-doctor について
macOS 上の Windows App によるリモートデスクトップ接続を診断するスキルです。AVD 系クラウドデスクトップと PC への直接接続を対象に、ネットワーク確認、クライアントログ分析、独立した RDP プローブで原因を切り分け、修正を案内します。
主な機能
- 01AVD と PC 直接接続の診断
- 02ネットワーク、VPN、プロキシの確認
- 03Windows App ログの分析
- 04独立した RDP サーバープローブ
- 05根拠に基づく原因特定と修正案内
活用シーン
- 01AVD 接続が TCP または WebSocket に切り替わる状況の調査
- 02VPN や UDP 制限が Shortpath に及ぼす影響の確認
- 03PC への直接接続が設定中に停止する問題の診断
- 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.mddirect_pc_and_auth_diagnostics.mdwindows_app_log_analysis.mdscripts/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 マルチキャストに対応)、失敗した場合、クライアントはゲートウェイ経由で TCP 443 を使用する WebSocket にフォールバックし、レイテンシのオーバーヘッドが大幅に増加します。
直接 PC 接続では、TCP 3389 上の通常の RDP(通常は TLS でラップ)を使用します。接続情報パネル、ゲートウェイ到達性テスト、転送最適化の手順はありません。直接 PC 接続で主に発生する障害は次のとおりです。
- リモート PC の電源がオフ、または到達不能(ネットワーク/ファイアウォール)です。
- Windows App クライアントの Microsoft 職場/学校アカウントが古いか期限切れで、認証オーケストレーションに悪影響を与え、接続が「Configuring remote PC...」のままになります。
- リモート PC が再起動され(多くの場合、Windows Update が原因)、クライアントが正常に再接続できません。
このスキルは両方のシナリオに対応します。
診断ワークフロー
ステップ 1:接続の種類と症状を特定する
エビデンスを収集する前に、診断対象のシナリオを特定します。
| シナリオ | 主な特徴 | 主なエビデンスの取得元 |
|---|---|---|
| AVD/WVD/W365 | ユーザーがワークスペース/ゲートウェイ経由でクラウドデスクトップに接続する | 接続情報パネル、ゲートウェイのヘルスチェック、UDP Shortpath のログ |
| 直接 PC | ユーザーがホスト名または IP で指定した PC(例:自宅のワークステーション)に接続する | RDP プロトコルプローブ、Windows App ログの認証チェーン、Windows 側の再起動イベント |
AVD/WVD/W365 の場合、Windows App の接続情報を提示してもらいます(ツールバーの信号アイコンをクリックします)。次の主要なフィールドを確認します。
| フィールド | 内容 |
|---|---|
| Transport Protocol | 現在の転送方式:UDP、UDP Multicast、WebSocket、または TCP |
| Round-Trip Time (RTT) | エンドツーエンドのレイテンシ(ms) |
| Available Bandwidth | 現在の帯域幅(Mbps) |
| Gateway | AVD ゲートウェイのホスト名とポート |
| Service Region | Azure リージョンコード(例:SEAS = 東南アジア) |
Transport Protocol が UDP または UDP Multicast の場合、接続は最適な状態です。それ以上の診断は不要です。
Transport Protocol が WebSocket または TCP の場合は、ステップ 2 に進みます。
直接 PC の場合、接続情報パネルはありません。代わりに、まずステップ 2E のRDP プロトコルプローブを実行してサーバーに到達可能であることを確認し、その後、Windows App ログで認証の不整合や再接続の失敗を分析します。進行状況ダイアログが「Configuring remote PC...」のままの場合は、クライアント側の ID の問題が強く疑われます(カテゴリー 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 では反証テストとして有用です。Windows App クライアントや資格情報に依存せず、サーバー側の RDP スタックが稼働していることを確認できます。
同梱のプローブスクリプトを使用します。
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). と表示されます。これは、問題がクライアント側(認証、アプリの状態、プロキシ、または ID)にあることを意味します。プローブが失敗した場合、問題はサーバー側またはネットワーク(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 ごとにイベントを集約し、1 回の接続試行のライフサイクルを把握してください。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 portal での管理者による操作が必要です。
カテゴリ E: クライアント ID / 期限切れの Microsoft アカウントによるポイズニング(直接 PC 接続および AVD)
根拠: RDP プロトコルプローブは成功します(サーバーは正常)が、Windows App のログに OneAuth/MSAL チェーンが表示されます:
OneAuthError_InteractionRequiredNo valid refresh tokens available in the cacheAcquireTokenInteractivelycredential completion has been canceledUser canceled sign inGATEWAY(ERR): CWVDTransport::OnOrchestrationHttpError error: UserCancelled(8)Fail OnDisconnected call
進行状況ダイアログが「Configuring remote PC...」のまま止まることがあります。これは、アプリが非表示またはキャンセルされた対話型サインインプロンプトを待っているためです。これは、期限切れのアカウントがその PC と無関係であっても、直接 PC 接続に影響を与える可能性があります。Windows App クライアントは、すべての接続タイプで同じ認証オーケストレーションを共有しているためです。
修正: Windows App を開き → 設定 → アカウント に移動し、古い 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 の設定でアクティブ時間を設定する/アクティブ時間中の自動再起動を無効にするか、ユーザーがマシンを使用していないときに再起動をスケジュールします。
管理者アクセス権がある場合は、LastBootUpTime には Get-CimInstance Win32_OperatingSystem を、イベント ID 1074 には Get-WinEvent を使用します。WSL/SSH のエンコードされたコマンドのテクニックについては、references/direct_pc_and_auth_diagnostics.md を参照してください。
ステップ 5:修正を確認する
修正を適用したら、再接続して該当する症状が解消したことを確認します。
AVD/WVD/W365 の場合:
- 接続情報を確認します。トランスポートプロトコルに
UDPまたはUDP Multicastと表示されている必要があります。 - RTT が大幅に低下していることを確認します(例:165ms から 40~60ms)。
- lsof で確認します。
lsof -i UDP -n -P 2>/dev/null | grep -i "Windows"
# Should show UDP connections if Shortpath is active
直接 PC に接続する場合:
- 進行状況ダイアログが消え、セッションウィンドウが表示される必要があります。
- 新しいセッションの Windows App ログに、マウス/キーボード入力イベント(
IHAddMouseEventToPDU、IHAddKeyboardEventToPDU)が記録され、UserCancelled(8)エラーがないことを確認します。 - 問題の原因が期限切れの Microsoft アカウントだった場合は、Windows App → 設定 → アカウントに有効なアカウントだけが残っていることを確認します。
サーバーを再起動した場合:
pingとscripts/probe_rdp_server.pyを使って、PC に再び接続できることを確認します。LastBootUpTimeが最近の時刻で、障害が発生していた時間帯と一致することを確認します。
参考資料
- references/windows_app_log_analysis.md — 詳細なログ解析パターン、エラーの特徴、GUID のライフサイクル分析、比較方法
- references/avd_transport_protocols.md — AVD のトランスポート選択の仕組み、STUN/TURN/ICE の概要、Shortpath のアーキテクチャ
- references/direct_pc_and_auth_diagnostics.md — PC への直接接続の失敗、期限切れの Microsoft アカウントによる問題、RDP プロトコルプローブの使用方法、Windows 側の再起動との相関、ダイアログが停止した状態とセッションが有効な状態の見分け方
- scripts/probe_rdp_server.py — 単体で実行できる RDP プロトコルおよび TLS のヘルスプローブ