VBScriptを掌握せよ:レジストリ完全走査による「真のアプリインベントリ化」の極意
現場のエンジニア諸君。端末管理をExcelの手入力で済ませているような時代遅れのルーチンからは、今日で卒業しよう。
「インストール済みのソフト一覧を出せ」という上からの無茶振りに、GUIをポチポチ叩いて対応するのはエンジニアの仕事ではない。我々が書くべきは、OSの深淵(レジストリ)を正確に射抜き、一切の取りこぼしを許さない「堅牢な自動化スクリプト」だ。
今回は、Windowsレジストリの`Uninstall`キーを32bit/64bit双方から完全に掘り起こす、プロダクションクオリティのVBScriptを伝授する。
—
1. なぜ「単純なスクリプト」では死ぬのか
多くの入門者が書くコードには致命的な欠陥がある。
- ビットの迷宮: 64bit OSには「32bit用」と「64bit用」のUninstallレジストリが存在する。片方しか見ないツールは、インベントリとして信用できない。
- 権限の壁: `HKEY_LOCAL_MACHINE`へのアクセスは時として拒絶される。エラー処理を怠ったスクリプトは、1件の権限エラーで全体が停止する。
- リソースのリーク: `WScript.Shell`のオブジェクト生成をループ内で乱発すれば、メモリを食いつぶし、最悪の場合OSの反応を鈍らせる。
これらを回避し、「止まらない、漏らさない、汚さない」コードを書くのがプロの流儀だ。
—
2. 実装の設計思想:多重走査と排他制御
今回のスクリプトは、以下の構造で設計する。
1. レジストリ・パスの配列化: 64bit/32bitの各パスをループで処理し、DRY(Don’t Repeat Yourself)原則を守る。
2. エラー・ハンドリング: `On Error Resume Next`を局所的に使用し、読み取れないキーは「スキップ」することで全体の稼働を担保する。
3. CSVのストリーム出力: ファイルを一度開いたら閉じるまで書き込み続ける。バッファを意識した効率的なI/Oを行う。
—
3. 現場で使えるプロダクション・コード
以下のコードを `InventoryApps.vbs` として保存し、管理者権限のコマンドプロンプトで実行してほしい。
Option Explicit
‘ — 設定定数 —
Const CSV_FILE = “InstalledApps.csv”
Const HKEY_LOCAL_MACHINE = &H80000002
Dim objFSO, objFile, objRegistry
Dim arrPaths, path, subKeys, subKey
Dim strDisplayName, strDisplayVersion, strPublisher
‘ CSV出力準備
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFile = objFSO.CreateTextFile(CSV_FILE, True)
objFile.WriteLine “DisplayName,DisplayVersion,Publisher”
‘ レジストリ操作用オブジェクト
Set objRegistry = GetObject(“winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv”)
‘ 64bitと32bitの両方を探査するパス配列
arrPaths = Array( _
“SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”, _
“SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall” _
)
For Each path In arrPaths
objRegistry.EnumKey HKEY_LOCAL_MACHINE, path, subKeys
If IsArray(subKeys) Then
For Each subKey In subKeys
‘ エラー回避のため局所的にハンドリング
On Error Resume Next
strDisplayName = “”
strDisplayVersion = “”
strPublisher = “”
‘ レジストリ値取得(戻り値が0なら成功)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, path & “\” & subKey, “DisplayName”, strDisplayName
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, path & “\” & subKey, “DisplayVersion”, strDisplayVersion
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, path & “\” & subKey, “Publisher”, strPublisher
‘ 名前が空でないものだけ抽出
If strDisplayName <> “” Then
objFile.WriteLine “””” & strDisplayName & “””,””” & strDisplayVersion & “””,””” & strPublisher & “”””
End If
On Error GoTo 0
Next
End If
Next
objFile.Close
WScript.Echo “完了しました。出力ファイル: ” & CSV_FILE
—
4. 運用の極意:なぜこれが最強なのか
- CSVクォーテーションの徹底: `””` で囲むことで、ソフト名にカンマが含まれていてもCSVが崩壊しない。これはインベントリ管理の基本中の基本だ。
- WMIのStdRegProv: `WScript.Shell`で`reg query`を叩く手法は、標準出力のパースが必要となりバグの温床となる。`StdRegProv`を直接叩くことで、型安全かつ高速に値を取得している。
- 保守性: パス配列を増やせば、`HKCU`(ユーザーごとのインストール情報)への拡張も容易だ。
最後に
VBScriptは「レガシー」などではない。Windowsの内部構造を直接操作し、システム管理の自動化を最速で実現するための「魔法の杖」だ。
このコードをベースに、君たちの現場に合わせてカスタマイズしてほしい。エラーが出た?それはOSの仕様だ。その壁をどう乗り越えるか考えることこそが、エンジニアとしての真価を問われる瞬間なのだから。
健闘を祈る。
