VBScriptで挑む「セキュリティの要塞化」:Seceditログ解析によるGPO自動監査の実践
業務自動化の現場において、VBScriptは「レガシー」などと揶揄されることがある。しかし、Windows環境で追加のランタイムを一切必要とせず、管理者権限さえあればOSの深淵に触れられるこの言語は、大規模な環境監査において今なお最強の武器だ。
今回は、SeceditコマンドでエクスポートしたセキュリティテンプレートをVBScriptでパースし、会社標準ポリシーからの逸脱を自動検知する「セキュリティ自動診断ツール」の設計思想を伝授する。単に動けばいいコードではなく、「堅牢性・保守性・再利用性」を極めたアーキテクチャを構築せよ。
—
1. なぜ「Secedit」なのか、なぜ「VBScript」なのか
セキュリティ設定の確認にGUI(secpol.msc)を使うのは、エンジニアの仕事ではない。`secedit /export /cfg output.inf` を使えば、OSの全権限設定をテキストファイルとして吐き出せる。
しかし、このINFファイルは非常に冗長で、そのままでは比較しにくい。ここでVBScriptの出番だ。テキスト処理において、VBScriptの `Scripting.FileSystemObject` と `Dictionary` オブジェクトの組み合わせは、メモリ効率が極めて高く、数万行のログ解析でも瞬時に終わる。
2. アーキテクチャの鉄則:疎結合なデータ構造
今回作成するツールは、以下の3フェーズで構築する。
1. データ抽出: シェルを実行し、INFファイルを生成する。
2. パース処理: INFをDictionaryオブジェクトへロードし、キー・バリュー形式に変換する。
3. 比較・診断: 標準ポリシー(マスター)と現行設定を比較し、差分をレポートする。
実装コード:Secedit解析エンジンの核
以下のコードは、保守性を考慮した「クラスライブラリ的アプローチ」を採用している。
‘ SecurityAuditor.vbs
Option Explicit
Dim fso, shell, dictActual, dictStandard
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shell = CreateObject(“WScript.Shell”)
Set dictActual = CreateObject(“Scripting.Dictionary”)
‘ 1. セキュリティ設定のエクスポート
Dim tempPath: tempPath = fso.GetSpecialFolder(2) & “\sec_export.inf”
shell.Run “secedit /export /cfg “”” & tempPath & “”””, 0, True
‘ 2. INFファイルのパース処理
ParseInfFile tempPath, dictActual
‘ 3. 診断ロジック(例:パスワードの最小文字数)
CheckPolicy “MinimumPasswordLength”, 8, dictActual
Sub ParseInfFile(path, dict)
Dim file, line, parts
Set file = fso.OpenTextFile(path, 1)
Do Until file.AtEndOfStream
line = Trim(file.ReadLine)
‘ セクションヘッダは無視し、キー=値のみを抽出
If InStr(line, “=”) > 0 And Left(line, 1) <> “[” Then
parts = Split(line, “=”)
dict.Add Trim(parts(0)), Trim(parts(1))
End If
Loop
file.Close
End Sub
Sub CheckPolicy(key, expectedValue, dict)
If dict.Exists(key) Then
If CLng(dict(key)) < expectedValue Then
WScript.Echo "[ALERT] " & key & " は標準以下です。現状: " & dict(key)
End If
End If
End Sub
---
3. 本番環境で「バグらせない」ための3つの極意
コードを書くとき、以下の点を守らなければ、現場で必ずトラブルに見舞われる。
① 文字エンコーディングの罠
`secedit` が出力するINFファイルは、システム環境によってはUTF-16LEとなる場合がある。`OpenTextFile` の第3引数で `True`(Unicode指定)を考慮しないと、文字化けが発生しパースが失敗する。必要に応じて `ADODB.Stream` を使った読み込みに切り替える設計にしておけ。
② 権限の管理(昇格の自動化)
このスクリプトは管理者権限で実行されないと、空のファイルを生成するか、アクセス拒否が発生する。スクリプト冒頭で `WScript.Arguments.Named.Exists(“elevated”)` をチェックし、未昇格なら `Shell.ShellExecute` で `runas` 動詞を使って自己再起動するロジックを組み込むのが、「自動化エンジニア」の嗜みだ。
③ ログの永続化
診断結果を画面に出すだけではプロフェッショナルとは言えない。必ず `fso.CreateTextFile` を使い、CSVまたはTSV形式でログを吐き出せ。後続のBIツールやExcelでの可視化を考慮し、「データは常に機械可読な形式で残す」のが鉄則だ。
—
4. 最後に:エンジニアとしての矜持
VBScriptは古い言語かもしれないが、OSの挙動を理解し、低レイヤーのログを自在にハンドリングする能力は、時代が変わっても変わらない「本質」だ。
今回紹介したコードは、単なるパースツールではない。あなたのインフラを「監視可能な状態」に引き上げるための足がかりだ。このスクリプトをタスクスケジューラに登録し、全端末からログを集約する仕組みを作れば、それは立派なセキュリティガバナンスの自動化基盤となる。
さあ、退屈な手作業のチェックリストを捨て、コードに診断を委ねろ。それが、現代のエンジニアが取るべき最適解だ。
