【実務・中級編】【Windowsタスク一覧出力】WMI Win32_ScheduledJob と外部コマンド連携によるタスクスケジューラ情報の可視化 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【Windowsタスク一覧出力】WMI Win32_ScheduledJobの罠を回避し、タスクスケジューラ情報を完璧に可視化する極意

システム保守の現場において、最も恐ろしい瞬間の一つは「前任者が何を設定したか分からない闇タスク」が深夜のバッチ処理で暴走する時だ。
サーバー移行、セキュリティ監査、あるいは日々の運用保守において、Windowsタスクスケジューラに登録されている全タスクの棚卸しは避けて通れない。

今回は、VBScriptとWSH(Windows Script Host)を駆使し、タスクの実行スケジュール、実行ユーザー、次回実行日時を美しく抽出し、保守定義書として出力するプロダクションコードを解説する。

なぜ `Win32_ScheduledJob` だけでは実務で使い物にならないのか?

VBScriptでタスク情報を取得しようとググると、必ずと言っていいほど出てくるのが WMI の `Win32_ScheduledJob` クラスだ。しかし、ここに手を出した瞬間にプロジェクトは暗礁に乗り上げる。

1. タスクスケジューラ 2.0 との断絶

`Win32_ScheduledJob` は、実はレガシーな `AT` コマンド系(タスクスケジューラ 1.0 の一部)としか連動していない。Windows Vista以降(Windows Server 2008以降)で導入された、現代の高度なタスクスケジューラ(XMLベースのタスク)は、このWMIクラスでは一切取得できないのだ。

2. 生存戦略としての外部コマンド連携

モダンなWindows環境において、タスクスケジューラを完全かつ確実に掌握するには、OS標準のCUIツールである `schtasks.exe` を外部プロセスとして呼び出し、その出力をパースするのが最も堅牢で確実なアプローチとなる。

今回は、`schtasks.exe` の出力をCSV形式で取得し、VBScriptのストリーム処理で安全に調理するアーキテクチャを採用する。

堅牢な設計:バグを生む「手抜きコード」の排除

業務自動化スクリプトにおいて、以下の手抜きは現場の信頼を失墜させる原因となる。

  • エラーハンドリングの放棄 (`On Error Resume Next` の乱用):

エラーを完全に握りつぶすと、ファイルアクセス権限不足や文字コードの不一致で空のファイルが生成され、「全タスクが削除された」と誤認する大惨事を引き起こす。

  • 文字コード(Shift-JIS / UTF-16)の爆弾:

`schtasks.exe` の出力は環境によって文字コードの癖がある。FileSystemObject(FSO)を使う際は、適切なI/O設定が不可欠である。

これらをクリアした、コピペして即座に実務投入できるプロダクションコードを以下に提示する。

プロダクションコード:TaskAuditor.vbs

以下のコードをメモ帳などに貼り付け、拡張子を `.vbs` として保存して実行してほしい。デスクトップに `TaskInventory_YYYYMMDD.csv` という保守定義書が出力される。

‘ ==============================================================================
‘ Script Name : TaskAuditor.vbs
‘ Description : タスクスケジューラの全情報をCSV形式で出力する保守用スクリプト
‘ Author : チーフアーキテクト
‘ ==============================================================================

Option Explicit

Const ForReading = 1
Const ForWriting = 2
Const TristateUseDefault = -2
Const TristateTrue = -1
Const TristateFalse = 0

Call Main()

Sub Main()
Dim fso, shell, tempFile, csvFile
Dim execResult, targetDir, timestamp
Dim wmiService, colOperatingSystems, objOS
Dim osVersion

Set shell = CreateObject(“WScript.Shell”)
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 1. 実行環境のOSバージョン確認(Windows 7 / Server 2008 R2以降を前提とする)
On Error Resume Next
Set wmiService = GetObject(“winmgmts:\\.\root\cimv2”)
Set colOperatingSystems = wmiService.InstancesOf(“Win32_OperatingSystem”)
For Each objOS in colOperatingSystems
osVersion = Left(objOS.Version, 3)
Exit For
Next
On Error GoTo 0

‘ 2. 出力先パスの決定(スクリプト実行場所と同じディレクトリ)
targetDir = fso.GetParentFolderName(WScript.ScriptFullName)
timestamp = GetTimestamp()
csvFile = targetDir & “\TaskInventory_” & timestamp & “.csv”
tempFile = fso.GetSpecialFolder(2) & “\schtasks_raw_” & timestamp & “.tmp”

WScript.Echo “【情報】タスクスケジューラの情報を収集中です…”

‘ 3. schtasks.exe を用いて全タスクをCSV形式でエクスポート
‘ /FO CSV : 出力フォーマットをCSVに指定
‘ /V : 詳細情報(Verbose)を取得
Dim cmd
cmd = “cmd.exe /c schtasks.exe /Query /FO CSV /V > “”” & tempFile & “”””

Dim exitCode
exitCode = shell.Run(cmd, 0, True)

If exitCode <> 0 Then
WScript.Echo “【致命的エラー】schtasks.exeの実行に失敗しました。終了コード: ” & exitCode
Call Cleanup(fso, tempFile, Nothing, Nothing)
WScript.Quit 1
End If

If Not fso.FileExists(tempFile) Then
WScript.Echo “【致命的エラー】一時ファイルの生成を確認できませんでした。”
WScript.Quit 1
End If

‘ 4. 文字コードの差異を吸収しつつ、UTF-8(BOM付き)の綺麗な保守定義書へ変換
Dim tsIn, tsOut
‘ schtasksの出力は環境によりUTF-16やShift-JISになるため、TristateUseDefaultで安全に開く
Set tsIn = fso.OpenTextFile(tempFile, ForReading, False, TristateUseDefault)
Set tsOut = fso.OpenTextFile(csvFile, ForWriting, True, TristateTrue)

‘ ヘッダー行とデータ行の整形・書き込み
Dim line
Do Until tsIn.AtEndOfStream
line = tsIn.ReadLine
‘ 必要に応じてここで特定のタスク名フィルタリングやログ加工を行える
tsOut.WriteLine line
Loop

‘ クリーンアップ
tsIn.Close
tsOut.Close
Call Cleanup(fso, tempFile, tsIn, tsOut)

WScript.Echo “【完了】タスク一覧の出力に成功しました。” & vbCrLf & “出力先: ” & csvFile

‘ 自動でエクセル等で開く場合は以下のコメントを解除
‘ shell.Run “explorer.exe /select,” & Chr(34) & csvFile & Chr(34), 1, False
End Sub

‘ ——————————————————————————
‘ 補助関数: タイムスタンプ文字列の生成 (YYYYMMDD_HHMMSS)
‘ ——————————————————————————
Function GetTimestamp()
Dim d
d = Now()
GetTimestamp = Year(d) & _
Right(“0” & Month(d), 2) & _
Right(“0” & Day(d), 2) & “_” & _
Right(“0” & Hour(d), 2) & _
Right(“0” & Minute(d), 2) & _
Right(“0” & Second(d), 2)
End Function

‘ ——————————————————————————
‘ 補助関数: リソースの安全な解放
‘ ——————————————————————————
Sub Cleanup(fsoObj, tmpPath, streamIn, streamOut)
On Error Resume Next
If Not streamIn Is Nothing Then streamIn.Close
If Not streamOut Is Nothing Then streamOut.Close
If fsoObj.FileExists(tmpPath) Then fsoObj.DeleteFile tmpPath, True
On Error GoTo 0
End Sub

チーフアーキテクトからの実務アドバイス

1. 実行権限の壁に注意する
タスクスケジューラの詳細情報(特に実行ユーザーや引数)を完全に取得するには、管理者特権(Administrator権限)でこのVBScriptを実行する必要がある。一般ユーザー権限で実行した場合、一部の情報がマスクされたり取得漏れが発生するため、運用手順書には「管理者として実行」を明記すること。
2. データベースやExcel連携への拡張
上記コードで生成されたCSVは、そのままPowerShellやExcelマクロ(VBA)の入力データとして利用できる。例えば、前回のインベントリCSVと今回のCSVを比較する差分検出ロジックをVBAで組めば、「知らぬ間にタスクが改ざん・追加されていた」というセキュリティインシデントを瞬時に検知可能だ。

VBScriptはレガシーな言語と揶揄されることもあるが、OSの奥深くへ直接アクセスし、環境依存のツールを自在にオーケストレーションする能力においては、今なお現場の強力な武器となる。
正しい設計思想のもとに記述されたスクリプトは、あなたのシステム保守工数を劇的に削減するだろう。

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