2014年4月16日水曜日

Windows7でリモートデスクトップ part2

前回紹介した方法では、リモートデスクトップを切断する際にわざわざバッチファイルを叩かなければならなかった。
しかも、管理者権限が必要なので毎回UACの警告が表示される。
ついでに言えば、タイムアウトなどで勝手に切断された場合はバッチファイルが実行されないため自宅のディスプレイは真っ黒のままだ。

本音を言うと、リモートデスクトップが切断されたら自動的にコンソールセッションがアクティブになって欲しい。切断するたびに特別な操作なんてやりたくないのだ。

とは言え、これ以上の方法を探しても意外と見付からない。
gpedit.mscなどで探しても、リモートデスクトップ接続時に自動的にプログラムを走らせる設定はあるが逆はない。

なので、これから紹介する方法は本ブログオリジナルの方法である。


まず最初に、リモートデスクトップの切断を検知する方法から調べてみよう。

コントロールパネルの管理者ツールからイベントビューアを起動する。
Windows7のイベントビューアはごちゃごちゃしていて見づらいが仕方がない。

アプリケーションとサービスログ > Microsoft > Windows >  TerminalServices-LocalSessionManager > Operational

と、ツリーを展開していく。ここがリモートデスクトップのログの場所だ。既に何度かリモートデスクトップを利用しているなら再接続に成功したり、切断されたり、色々な種類のログが確認できるはずだ。

では、ここから切断時のログだけをピンポイントに抜き出してみよう。

カスタムビューと書かれたラベルを右クリックし、「カスタムビューの作成」を選択する。
「ログごと」にチェックが入っていることを確認し、「イベントログ」の右のコンボボックスの▼を押して
アプリケーションとサービスログ > Microsoft > Windows >  TerminalServices-LocalSessionManager > Operational
を選択する。

ここまでは比較的簡単。大変なのはここからである。

「フィルター」のタブを「XML」に切り替える。
「手動でクエリを編集する」にチェックを入れる。確認が表示されるが「はい」を選ぶ。

<Select Path="Microsoft-Windows-TerminalServices-LocalSessionManager/Operational">*</Select>

となっている部分を

<Select Path="Microsoft-Windows-TerminalServices-LocalSessionManager/Operational">*[System[EventID=24 and Level=4] and UserData/EventXML/Address!='ローカル']</Select>

と書き換える。これで、ローカル「以外」から切断した場合だけを取得するようにXPath形式で指定したことになる。

「OK」を押し、フィルタに「リモートデスクトップ切断」とでも名前を付けて更に「OK」を押す。

これで屋外からリモートデスクトップで切断した時のログだけを抽出することが出来るようになったはずだ。


次に、「リモートデスクトップ切断」にログが追加される度にプログラムを起動する方法について説明する。

先程保存した「リモートデスクトップ切断」を右クリックし、「このカスタムビューにタスクを設定」を選択する。
「基本タスクの作成」で「リモートデスクトップ切断後の処理」とでも名前を付けて「次へ」をクリック。
「イベントログへの記録時」でカスタムイベントフィルターと表示されていることを確認して「次へ」をクリック。
「操作」で「プログラムの開始」を選択して「次へ」をクリック。
「プログラム/スクリプト」に「tscon」、「引数の追加」に「1 /DEST:console /PASSWORD:*****」と入力して「次へ」をクリック(*****は実際のパスワードを入れる)。
「[完了]をクリックしたときに、このタスクの[プロパティ]ダイアログを開く」にチェックを入れて「完了」をクリック。

まだまだ続く。次はプロパティダイアログにて。

「全般」タブの中で、「ユーザがログオンしているかどうかにかかわらず実行する」にチェックを入れる。 念のため「パスワードを保存しない」のチェックは外しておこう。そして「最上位の特権で実行する」にチェックを入れる。
「条件」タブの中で、「タスクを実行するためにスリープを解除する」にチェックを入れる。
「設定」タブの中で、「タスクを要求時に実行する」だけON、他のチェックは全てOFFにする。
「OK」を押してダイアログを閉じる。パスワードを聞かれた場合は入力する。

これで「リモートデスクトップ切断時に自動的にコンソールセッションをアクティブにする」ことが出来るようになった。もう×ボタンで閉じようが、タイムアウトで勝手に切断されようが関係ない。

作成したタスクはコントロールパネルの「管理ツール」→「タスクスケジューラ」の「イベントビューアータスク」で確認することが出来る。

以上!

2015/7/13
続きの記事を書きました。

Windows7でリモートデスクトップ part1

たまに屋外から自宅のPCを操作したくなるときがある。
そんなときに、リモートデスクトップは最もお手軽な手段の一つであろう。

自宅と同じ環境で操作したいため、屋外からは以下のコマンドでリモートデスクトップに接続することにしている。

mstsc /admin

ただ、リモートデスクトップを切断して自宅に帰ってみると、ディスプレイが真っ黒のまま何の操作も受け付けなくなっていて途方に暮れることがある。

これはコンソールセッションがアクティブになっていないことが原因である。

試しに、自宅のPCでコマンドプロンプトを起動して以下のコマンドを打ってみよう。

query session

すると、こんな感じになるのではないだろうか。


セッション名ユーザ名ID状態種類デバイス
services0Disc
>consoleHoge1Active


コンソールセッションがアクティブになっているのが分かる。

次に、屋外からリモートデスクトップで接続して同じコマンドを打ってみよう。
こんな感じになるはずだ。


セッション名ユーザ名ID状態種類デバイス
services0Disc
>rdp-tcp#0Hoge1Activerdpwd
console13Conn
rdp-tcp65536Listen


コンソールセッションとは別のセッションがアクティブになっているのが分かる。

では、どうすれば良いか。切断時にコンソールセッションがアクティブになるようにすれば良い。

×ボタンでリモートデスクトップを閉じたり、スタートメニューからログオフや切断を選ぶ代わりに、コマンドプロンプトを管理者権限で起動し、以下のコマンドを実行する。

tscon 1 /DEST:console /PASSWORD:*****

現在アクティブなIDの1番をコンソールに接続するよ、と言う意味だ。そうすると自動的にリモートデスクトップは切断され、自宅のPCが操作可能な状態に戻る。
*****には実際のパスワードを入れよう。XPの時代は指定しなくても上手く行ったのだが、7になってからはこのオプションを指定しないと上手く行かなかった。

毎回管理者権限でコマンドプロンプトを起動してコマンドを叩くのは面倒なので、バッチファイルを作成し、そのバッチファイルのショートカットを作成し、そのショートカットのプロパティ画面の詳細設定から「管理者として実行」を有効にしておく。
あとはそのショートカットをスタートメニューなりに登録し、リモートデスクトップを切断する際にそのショートカットを実行するようにすれば良い。

実はもっと上手くやる方法があるのだが、長くなったのでその説明は次回に回そう。