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でのテストからサーバー環境での無人運用まで、同じロジックで安全に実行できるツールが完成する。さあ、洗練されたコードで、泥臭い業務をスマートに解体していこう。
