Windows Virtual Desktop #7 msrdcw.exe の設定の保存先を探る

この記事のWVDは”Windows Virtual Desktop Spring 2020 Release”が対象です。

Windows 向けのリモートデスクトップクライアントの実体は msrdcw.exe になりますが、このmsrdcw.exe は最初のサインインを担い、別のプロセスとして msrdc.exe が通信処理を行っていることがわかってきました。 調べた結果を共有します。

そもそも このmsrdcw.exe の設定の保存先を調べる理由ですが実運用の展開を見据えて以下の点を明らかにする必要があるためです。

  1. 物理端末への初期インストールの方法の確立 (物理端末のマスタイメージに含めることができるか、含めた場合に利用者個別の設定を運用開始後に正常に保持できるか)
  2. 物理端末を展開後、システム管理者が設定などをコントロール(変えたり、ロックしたり)できるか(msrdcw.exe に標準で機能がない場合も他ツールと連携して実施できるかどか)

1. リモートデスクトップクライアント のファイル群

以下の記事で紹介した通り、リモートデスクトップクライアントの実体は msrdcw.exe コマンドで、そのファイルは “%LOCALAPPDATA%\Apps\Remote Desktop” にインストール時に配置されます。 

“%LOCALAPPDATA%\Apps\Remote Desktop” にインストールされるということで物理端末のマスタイメージにインストールしてもインストールしたアカウントのプロファイルにしか配置されず、異なるユーザでは利用できないことがわかります。  

プロファイル以外の場所にコピーして使う話もありますがレジストリにも情報は持つため検証とその検証結果によってはカスタマイズが必要そうです。 Windows 10 IoT などシンクライアント環境であればサインインユーザを共通化してマスタイメージへのインストールアカウントと利用者のアカウントを一致させれば単純に解決します。 あとはマニュアルを作ってエンドユーザに実施してもらうか。

Google のChrome ブラウザなんかも基本は各アカウントのプロファイルの配下にインストールされます。ただ、Chrome の場合はプロファイルの外にインストールする別のインストーラも提供されています。 リモートデスクトップクライアントも同様な措置が今後とられるとよいのかなとは思います。

と書いていたのですが公式ドキュメントにやり方がありました。

1.1. “%LOCALAPPDATA%\Apps\Remote Desktop” の中身

Remote Desktop フォルダには34のフォルダ、115のファイルがあります。

115ファイルのうち77個は34のフォルダ配下です。

1.2. アイコン

Assets フォルダにアイコンがあります。

1.3. ローカライズ

その他のフォルダはローカライズに関するデータになります。 

試しに”ja”フォルダを見てみます。 ライセンスのドキュメントとdll があります。

ライセンスのドキュメントの中身ですが、まず総則として複製が許容されているとのこと。 そもそもこれがNGだと物理端末のマスタイメージにインストールしての複製が出来ないのでライセンス条項的にはOK であることがわかります。

話は脱線しますが、昔からVDI ではアプリケーション のライセンスの確認は手間のかかるものでした。 仮想デスクトップにインストールするアプリケーションすべてについてライセンス条項を確認し、メーカーへも必要に応じて問合せしました。 オープンソースやフリーソフトで複製を認めないものもよくありました。 無償だから複製してもよいわけではなく、必ず使用許諾でその使用権がどこに(端末なのかユーザなのか組織なのかなど)あるかを確認し適切な対応を行う必要があります。

お客様から初回起動時の許諾の確認を消せないか?という相談もよくありました(アプリからすると各利用者に許諾を求めているのでマスタ側やデフォルトプロファイルで許諾済とするのはNGなケース。フリーソフトでも同様)。  ライセンシングの対象がノード単位の場合、ユーザ単位や組織単位へ変更することも。 あとはアプリケーション ベンダーさんが仮想化の仕組みに明るくない場合もその説明から始まるので手間がかかります。 

Windows 10 のマルチセッション もアプリケーション ベンダーさんからするとソフトウェアの動作可否、サポート可否の判断は難しいと考えます。 1台のクライアントOSは同時に1ユーザしか使わないという前提でアプリケーションを設計、開発しているケースは非常に多いです。 過去100を超えるアプリケーションについてVDI マスタへのインストールの前にProcess Monitor によるチェック(どんなプロセスが動くか、そのプロセスはファイル、レジストリのどこにRead / Write)を実施してきました。 アプリケーションの設定をLocal Machine のレジストリに持っている、C:\Program files\XXXX のアプリケーションインストールフォルダに持っている、SQL Server やその他データベースの類に持っている、など結果マルチセッション(この時はServer OS)はNGと判断したケースはありました。 あとはアプリケーションのメモリの使い方やサービス起動しているため NG のケースもありました。 

ビデオコーデックにも気になる記載が。 ビデオコーデックは個人使用および非商業的使用を前提とするとのこと。 画面転送の処理内部で AVC / VC-1 / MPEG-4 を使っているのかな? 仮に商用利用だとすると別途ライセンスの準備がいるということなのか。 ここら辺あんまり詳しくない。

2ページ目。 まあ他でもよくある完全合意。 この後で紹介する “NOTICE.txt” の中身も含めて確認し合意してね、という話です。

3ページ目。

私もすべてのケースですべてのライセンス条項をくまなくチェックするということは出来ていません(時間も手間もかかり、また法知識の面からも100%は出来ない)。 ただ、お客様のシステムへインストールを代行実施する場合はざっとでもよいので目を通し、許諾部分のスクリーンショットを渡していました。

1.4. アプリケーション

アプリケーションは以下の2つです。 今回の調査の対象となります

  • msrdc.exe
    • 接続後の画面転送通信を担当
  • msrdcw.exe
    • WVD へのサインインを担当

msrdc.exe

参考までに”msrdc.exe” をそのまま起動すると使用方法が案内されます。 従来のリモートデスクトップ接続用のコマンド”mstsc”と近い感じ(mstsc ほどオプションはないですが)。 この.RDPファイルを準備できれば “msrdcw.exe” の介さずに Windows Virtual Desktop に接続できるのかは現時点では不明。

msrdcw.exe

“msrdcw.exe” をそのまま実行するとリモートデスクトップクライアントが起動します。 

下のスクリーンショットでは”このワークスペースにアクセスできなくなっています。 このワークスペースは削除できます。 または、詳細についてはテクニカル サポートにお問い合わせください”とありますがこれは単純にworkspace を削除しているためです(検証時に作成し、その都度削除)。

1.5. その他ファイル

フォルダ内のファイルと2つのアプリケーションを除くと36個のファイルがあります。 msrdcw.exe と対となる”msrdcw.exe.config”、XMLの構成ファイル、”NOTICE.txt”、あとはDLL です。

“NOTICE.txt” ではリモートデスクトップクライアントで使用している複数のライブラリに関するライセンス条項の説明がありますので確認しておきましょう。

リモートデスクトップクライアント を利用した後もこのフォルダのファイルのタイムスタンプに違いはありません。 リモートデスクトップクライアントの設定情報やAzure AD でサインインした情報は別の場所に保管しているはず。 Process Monitor で突き止めます。

2. Process Monitor による調査

VDI をやられている方は皆さん利用しているはずの Process Monitor はこちらから入手可能です。 Process Monitor を利用することでアプリケーションがどこ(ファイル・レジストリ・ネットワーク)にいつ Read / Write しているかわかります。 今回の調査にうってつけです。

Process Monitor と並んで Windows Performance Analyzer もとても有用なツールです。 こちらはOS起動の大分早い時点からパフォーマンスのログを取得できます。プロセスやスレッド単位でCPUやメモリ、ディスクのリソース消費を確認することが出来ます。 OSの起動が遅い、サインインが遅いといった場合はこれを使えばまず間違いなく原因を特定できます。まあ大体はアンチウイルスが重たいのですが。  使ったことが無い方いれば是非使ってみてください。

Process Monitor を起動し、Filter で”msrdc.exe” , “msrdcw.exe” に絞ります。

こんな風に2つのプロセスのOperation(CreateFileやRegOpenKeyなど)とPath (ファイルパスやレジストリキー、画面にはないですがネットワークパス)、Result で結果、Detail に内容を確認できます。

細々と解説するのもアレなのでポイントを。 データはCSV に保存し、Excel で見ていきます。

2.1. msrdcw.exe の Write operation

Write している対象は以下です。

C:\ProgramData\NVIDIA Corporation\~

この2行は除外します。 

C:\Users\USERPORFILE\AppData\Roaming\Microsoft\Windows\Start Menu\ ~

この4行は除外します。 リンクファイルのため。

C:\Users\USERPORFILE\AppData\Local\Temp\DiagOutputDir\RdClientAutoTrace

この6行も除外します。 これはクライアントアプリケーションのログのため(マニュアル)。 

ETL 形式のログが残るので Windows Performance Analyzer で詳細を確認出来ます。 

ETL ファイルを開くとこんな感じで何が起きているかを細かく見ていけます。 ただ認証に成功・失敗、繋がった・繋がらないは直感的には確認できません。もうちょっと簡単なログ、テキストファイルで何時何分に接続を開始して認証に成功したとか失敗したとか、があったほうありがたいかなと。

C:\Users\USERPROFILE\AppData\Local\Microsoft\TokenBroker\Cache

ここにはToken っぽい情報が残ります。 

ファイルの中身はこんな感じ。 そのままInternet にさらした場合のリスクが図れないのでマスクもしておきます。

このフォルダが今回求めていたリモートデスクトップクライアントの設定や過去の認証情報のデータの格納先のようです。

2つのフォルダの中を見てみると”.rdp” を拡張子にもつファイルが格納されています。 リモートデスクトップクライアントを起動しながらの確認が必要ですがリモートデスクトップクライアントがWindows Virtual Desktop に接続したあとにこれらの.rdp ファイルをダウンロードしていると推測します。

そしてのJSONファイル”ISubscription.json” がAzure AD のサインイン情報を保持しているようです。 私の環境に関わる情報はマスクしますが以下の情報を確認できます。

2.2. ISubscription.json

“ISubscription.json” の中身を見ていきます。 Internet で検索しても何も情報が出てきませんがそのほうがやる気が出るというものです。

中身を見る限り以下の構造です。元のJSONは改行がなく見るのがつらいのでこちらで改行をいれています。

Azure AD の接続情報
Azure AD アカウントや更新時間などを格納

“$type”:”RdClient.Common.Models.Subscription,RdClient.Common”,
“CurrentVersion”:2,
“Username”:”XXXXXX@m.bigriver.jp”,
“TenantCollection”:[{“$type”:”RdClient.Common.Models.Tenant, RdClient.Common”,
“LastUpdated”:”2020-05-10T01:11:20.7666653+09:00″,
“TenantId”:”db4f2146-8bfe-4f3f-aecd-0db8d9b5a321″,

workspace の接続情報
フィードから取得したworkspace名、他情報を格納。基本的にはリモートデスクトップクライアントから接続した際にWVD から提供される情報が登録される

“Title”:”bigriver-ws”,
“Description”:””,
“Url”:”https://rdweb.wvd.microsoft.com/api/arm/feeddiscovery/tenants/db4f2146-8bfe-4f3f-aecd-0db8d9b5a321/webfeed”,
“LogoPath”:””,
“SupportUrl”:””,
“SupportPhoneNumber”:””,
“PrivacyUrl”:””,
“OperationResult”:0,
“CurrentState”:1,
“RemoteResourceCollection”:[{“$type”:”RdClient.Common.Models.RemoteResource, RdClient.Common”,
“Id”:”b26a91fa-bca5-421f-789f-08d7f12e2002″,
“Alias”:”b26a91fa-bca5-421f-789f-08d7f12e2002″,

接続先のアプリケーション情報
アプリケーションに関する情報を格納。”.rdp” ファイルのパス、ディスプレイの設定、更新情報など。

“Title”:”SessionDesktop”,
“RdpFilePath”:”C:\Users\USERPROFILE\AppData\Local\rdclientwpf\db4f2146-8bfe-4f3f-aecd-0db8d9b5a321\b26a91fa-bca5-421f-789f-08d7f12e2002.rdp”,
“IconPath”:”C:\Users\USERPROFILE\AppData\Local\rdclientwpf\db4f2146-8bfe-4f3f-aecd-0db8d9b5a321\b26a91fa-bca5-421f-789f-08d7f12e2002.Ico”,
“PngPath”:”C:\Users\USERPROFILE\AppData\Local\rdclientwpf\db4f2146-8bfe-4f3f-aecd-0db8d9b5a321\b26a91fa-bca5-421f-789f-08d7f12e2002.Png”,
“IconDimension”:”0,0″,
“IsRemoteApp”:false,
“DisplaySettings”:

{“$type”:”RdClient.Common.Models.DisplaySettings,RdClient.Common”,
“ModelId”:”b2114daa-9a24-4ac4-94f7-d85b5b845787″,
“ScaleFactor”:100,
“DisplayResolution”:{“$type”:”RdClient.Common.Models.DisplayResolution, RdClient.Common”,
“ModelId”:”90a9e1c3-3b9b-4457-8238-3eb3737dc4ab”,
“Height”:0,”Width”:0,”ScaleFactors”:[100]},
“DynamicResolution”:true,
“FitWindow”:true,
“FullScreen”:true,
“MultiMon”:true,
“MaximizeToCurrentDisplays”:true,
“SingleMonInWindowedMode”:true,
“DisplayConfiguration”:2,
“SelectedMonitors”:”0″,
“UseDefaultSettings”:false},


“ShowByDefault”:false,
“ModelId”:”ffbedaf5-1b9f-4413-bfab-8b55baa5c412″,
“RdpFileETag”:”_aVfO_Bn3lNSL06QLGotHCGBQnJjVTpc7wehLG8HBDU”,
“IconETag”:””,
“PngETag”:””,
“ExecutableHash”:”b26a91fa-bca5-421f-789f-08d7f12e2002″,
“DisplaySettingsView”:{“$type”:”RdClient.Common.Models.DisplaySettings, RdClient.Common”,
“ModelId”:”b2114daa-9a24-4ac4-94f7-d85b5b845787″,
“ScaleFactor”:100,
“DisplayResolution”:{“$type”:”RdClient.Common.Models.DisplayResolution, RdClient.Common”,
“ModelId”:”90a9e1c3-3b9b-4457-8238-3eb3737dc4ab”,
“Height”:0,”Width”:0,”ScaleFactors”:[100]},
“DynamicResolution”:true,
“FitWindow”:true,
“FullScreen”:true,
“MultiMon”:true,
“MaximizeToCurrentDisplays”:true,
“SingleMonInWindowedMode”:true,
“DisplayConfiguration”:2,
“SelectedMonitors”:”0″,
“UseDefaultSettings”:false}}],
“ModelId”:”3aa8a64f-0aaa-4942-a514-de94df31909c”}],


“LastUpdated”:”2020-05-10T12:47:03.1266437+09:00″,
“LastSuccessfulUpdate”:”2020-05-10T12:47:03.1266437+09:00″,
“Url”:”https://rdweb.wvd.microsoft.com/api/arm/feeddiscovery”,
“ModelId”:”dbc69614-023c-4dc0-b2ef-dfde65bd861d”,
“ClaimsHint”:”Authority=https://login.windows.net/common/;Client=a85cf173-4192-42f8-81fa-777a763e6e2c;Redirect=https://www.wvd.microsoft.com/webclient;Resource=https://www.wvd.microsoft.com;Site=501413″,
“OperationResult”:0,
“IsEmptyWorkspace”:false},

Fall 2019 のリソース
Fall 2019 のTenant など

Windows Virtual Desktop Fall 2019 でテストした時の残骸で利用する予定もないので説明は割愛。  Spring 2020 と共通の項目もあるしそうでないものもある。

3. まとめ

Windows Virtual Desktop への接続で利用するリモートデスクトップクライアントについてどこに構成情報などを保持しているか確認することが出来ました。 物理端末への展開や運用など本番環境で検討に必要となる情報はあらかた確認できたかなと。

なお物理端末でのマスタイメージによる大量展開ですが公式ドキュメントにやり方がありました。 大丈夫そうです。

一番の収穫は”ISubscription.json” が構成情報の格納先とわかったことです。ただ、運用中にこのファイルを管理者再度で変更、配布するのは簡単ではなさそうです。 配布方法は3rd Party ツールなりなんとでもなりますがいかんせんこのJSONの情報のほとんどはWindows Virtual Desktop のメタデータとして管理されているものでフィードとして取得しています。 一部分だけを変えても今だと4時間毎に更新されるでしょう。 

あとはmsrdc.exe コマンドと .rdp ファイルをうまく使えば接続のショートカットも作れるかもしれません。(まだ試していないのとライセンス条項を見てしまったのでちょっとグレーかも)

まあ今はpreview なので今後機能がどんどん追加されていくことでしょう。 最近ですと一か月に1回はリモートデスクトップクライアントは更新されています。 Windows 向けはこの辺にして他のOS向けの確認にうつります。

以上