【実務・中級編】【リモートデスクトップセッション判定】RDP環境とローカルコンソールを識別した挙動切り替え制御 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを掌握せよ:RDPセッション判定による「環境適応型」自動化スクリプトの極意

業務自動化の現場において、VBScriptは「枯れた技術」と揶揄されることがある。だが、真のエンジニアは知っているはずだ。Windowsの深淵に最も近い場所で、OSの挙動を直接制御できるこの言語こそ、RPAツールのブラックボックスに頼らない「軽量かつ最強の自動化兵器」であることを。

今回は、現場のエンジニアが一度は頭を抱える「リモートデスクトップ(RDP)環境とコンソール環境の識別」という難題に切り込む。

なぜ「環境判定」が必要なのか?

自動化スクリプトを構築する際、もっとも避けるべきは「RDP接続時にGUIダイアログを出してしまい、セッションがハングアップする」という事故だ。

  • コンソール環境(物理端末): `MsgBox` や `WScript.Shell.Popup` はユーザーの目に触れるため、対話的な運用が可能。
  • RDP環境(リモート): ユーザーが接続していない場合、ダイアログは表示されず、スクリプトは応答待ち状態(デッドロック)に陥り、プロセスがゾンビ化する。

この「環境依存の不確実性」を排除し、セッションの状況に応じて挙動を自動最適化する設計こそが、プロダクションレベルのコードに求められる最低条件である。

【核心】RDPセッションを判定するロジックの正体

WMIの `Win32_ComputerSystem` を用いて `Name` や `UserName` を参照する手法は一般的だが、これだけでは不十分だ。より確実にセッション状態を掴むには、環境変数とセッションIDの相関を利用する。

以下のコードは、保守性を担保しつつ、環境に応じた最適化を自動で行うための「テンプレート」である。

実践的プロダクションコード:SessionAwareExecutor.vbs

‘ ==============================================================================
‘ 機能: RDP環境判定および動的挙動制御スクリプト
‘ 概要: コンソール接続時はGUI表示、RDP時はログ記録へ切り替える堅牢な設計
‘ ==============================================================================
Option Explicit

Dim isRDP
isRDP = CheckIfRDP()

If isRDP Then
‘ RDP環境:GUIを抑制し、ログ出力のみを行う(リソース負荷を最小限に)
WriteLog “RDPセッションを検知:バックグラウンドモードで実行します。”
RunAutomatedTask False
Else
‘ コンソール環境:対話的運用を許可
MsgBox “コンソール環境:処理を開始します。”, vbInformation, “自動化ツール”
RunAutomatedTask True
End If

‘ — 判定関数 —
Function CheckIfRDP()
Dim shell, sessionName
Set shell = CreateObject(“WScript.Shell”)

‘ 環境変数 SESSIONNAME を取得。RDP接続時は “RDP-Tcp#” 等が格納される
sessionName = UCase(shell.ExpandEnvironmentStrings(“%SESSIONNAME%”))

‘ Consoleであれば物理端末、それ以外はRDPや仮想セッションとみなす
If sessionName = “CONSOLE” Then
CheckIfRDP = False
Else
CheckIfRDP = True
End If
End Function

‘ — 業務ロジック部 —
Sub RunAutomatedTask(enableGUI)
‘ ここに実際の業務処理を記述
‘ データベースやファイル連携を行う際は、必ずフルパスで指定すること
‘ カレントディレクトリの不確実性は自動化の大敵である
If enableGUI Then
‘ GUI処理
End If
‘ 共通処理
End Sub

‘ — ログ出力補助 —
Sub WriteLog(msg)
Dim fso, logFile
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set logFile = fso.OpenTextFile(“C:\Logs\AutoTool.log”, 8, True)
logFile.WriteLine Now & ” : ” & msg
logFile.Close
End Sub

現場でバグを起こさないための「設計思想」

上記のコードを単にコピペするだけでなく、以下の3点を意識してほしい。これが「動くもの」を「運用に耐えるもの」へ昇華させる境界線だ。

1. カレントディレクトリの固定

VBScriptの `WScript.ScriptFullName` を基点とし、実行ファイルのパスを絶対パスで取得する習慣をつけよ。ショートカットから実行された場合、カレントディレクトリが予期せぬ場所を指すことがある。これが「ファイルが見つかりません」というエラーの正体だ。

2. オブジェクトのライフサイクル管理

`Set obj = Nothing` を軽視してはならない。特に長期間稼働するタスクスケジューラ配下では、メモリリークが致命傷になる。使用したオブジェクトは、必ずスコープの最後で明示的に解放する癖をつけろ。

3. WMIのオーバーヘッドを考慮せよ

本稿では環境変数による判定を採用した。WMIクエリ(`Win32_ComputerSystem`等)は強力だが、環境によっては実行に1秒以上のラグが生じることがある。頻繁に呼び出されるループ内で環境判定を行うのは愚の骨頂だ。「判定は一度だけ行い、結果を変数にキャッシュする」。これがパフォーマンスを最大化する鉄則である。

結論:自動化は「環境を支配する」ことから始まる

リモートデスクトップセッションの判定は、単なる条件分岐ではない。それは、君が書いたスクリプトが「今、どこで、どんな権限で、どう振る舞うべきか」をOSに問いかける、最初のコミュニケーションだ。

この設計をマスターすれば、物理PCでのテストからサーバー環境での無人運用まで、同じロジックで安全に実行できるツールが完成する。さあ、洗練されたコードで、泥臭い業務をスマートに解体していこう。

タイトルとURLをコピーしました