取得できない %CLIENTNAME% をなんとかする(batあり/タスクスケジューラで利用可能)

Windows で利用できる %CLIENTNAME% という便利な環境変数をご存じでしょうか。リモートデスクトップに接続した後でコマンドプロンプトを起動し、  echo %CLIENTNAME%  と打つと、リモートデスクトップ接続元のホスト名が表示されるはずです。私は先日この環境変数の存在を知りました。しかし、早速この環境変数(%CLIENTNAME%)をタスクスケジューラ(taskschd.msc)から利用しようとするとうまく使えず、ハマってしまいました。

私は先日、リモートデスクトップ接続してきた端末をログに残し管理したいと思い、イベントビューア(eventvwr.msc)を利用することを考えたのですが、対象となる「セキュリティ」のイベントログが数日であふれてしまうようなサーバーが存在しました。イベントログをローテーションすることも考えたのですが、ログでディスクを圧迫するのもバカらしいので、タスクスケジューラを利用した独自ログを作成することにしました。

このような目的でタスクスケジューラから %CLIENTNAME% を利用しようとしたところうまく使えなかったため、今回はこのようなリモートデスクトップの接続ログをとるスクリプトと合わせて、タスクスケジューラなどの %CLIENTNAME% が使えない環境で同様の値を取得する方法を紹介します。

未確認ですが、おそらくログオンスクリプトでも同様に利用できると考えています。(試された方情報をいただけるとありがたいです。)

スポンサーリンク

結論

結論だけ知りたい人は以下です。このレジストリから取ることができます。試しにリモートデスクトップして regedit から、以下のレジストリを見てみてください。目的のリモートデスクトップ接続元のホスト名が入っていると思います。

1
HKEY_CURRENT_USER\Volatile Environment\[セッションID]\CLIENTNAME

ここで利用するセッションIDは以下のようにすると取得できます。

1
query session %username%

ページの下のほうに bat を用意しています。ご自由にご利用ください。

%CLIENTNAME% が存在しない

リモートデスクトップ接続を管理したかったので、リモート接続されるコンピュータ(RDPサーバー)のタスクスケジューラに、「トリガ」を以下のように「リモートコンピューターからのセッション開始」を設定します。

「操作」は以下のように、単純に %clientname% を表示してみます。

このタスクスケジューラの設定を実行したコンピュータにリモートログインした結果は以下の通り。%clientname% が残念な感じに表示されています。試しにこのコマンドプロンプトで set コマンドを確認してみたところ、%CLIENTNAME% という環境変数を持っていないようです。

リモートデスクトップ起動後にコマンドプロンプトを起動して、同様に set コマンドを確認したところ、%CLIENTNAME% は確かに存在しました。

なぜか、タスクスケジューラから起動されるコマンドプロンプトには、%CLIENTNAME% が存在しない。

ググって探しあてたのがこのページです。すでに接続ホスト名を取得する vbs はこのページに書いてありコピペで使えました。最初の結論に書いた通り、レジストリから読み取ることができるとのことです。

https://rcmtech.wordpress.com2/011/06/09/how-to-get-clientname-within-logon-script-on-server-2008-r2-xenapp-6/

bat で書くとこんな感じ

vbsで書いても上のサイトのパクリで能がないので bat を作ってみました。query session でセッションIDを取得し、reg query で該当のレジストリから CLIENTNAME を取得するだけの簡単なものです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@echo off
setlocal enableextensions enabledelayedexpansion || exit /b 1
chcp 437 > nul

set session_id=
set result=1

for /f "tokens=3" %%i in ('query session %username% ^| findstr Active') do set session_id=%%i

if ""%session_id%""=="""" goto exit

set client_name_path=HKCU\Volatile Environment\%session_id%\CLIENTNAME

for /f "tokens=3" %%i in ('reg query "HKCU\Volatile Environment\%session_id%" /v "CLIENTNAME"') do set client_name=%%i

if ""%client_name%""=="""" goto exit

:success
set result=0

:exit
if %result% equ 0 (
  echo %date% %time:~,-3% Login from %client_name%.
) else (
  echo %date% %time:~,-3% Failed to get the client name.
)
pause

これを先ほどのスケジューラの「操作」に仕掛けたところうまく目的のCLIENTNAMEが取得できました。(リモートデスクトップ接続を行ったクライアントのホスト名が取得できました。)

IPアドレスは、NAT 配下からアクセスすると同じアドレスになってしまいますが、ホスト名はそのままですので、ホスト名の方が便利な局面が多いと思います。