VBScriptでWMI(Windows Management Instrumentation)を使う方法

この記事は、Windowsの管理情報にアクセスするための仕組みであるWMI(Windows Management Instrumentation)を、VBScript(.vbs)を使って扱う方法を初心者向けにわかりやすく解説します。

WMIは、Windowsの管理タスクを自動化するための強力なフレームワークであり、リモート管理や、システム情報の取得などに便利です。

基本的な概念、実行方法、サンプルコード、よくあるエラーの対処、最後に演習問題とその解答例を用意しています。

対象読者は、VBScriptの基本(変数、ループ、基本的なオブジェクト操作)が分かる人。OSはWindows(Windows 7以降)を想定しています。


WMIとは何か

WMIは、Windowsに組み込まれた管理情報の提供インターフェースです。

ハードウェア、OS、プロセス、サービス、ディスク、ネットワークなど多くの項目にアクセスできます。プログラムやスクリプトからこれらの情報を取得・操作できるため、システム管理や監視に便利です。

WMIはCOMベースで動作しているため、VBScriptのようなCOMを扱えるスクリプト言語から手軽に利用できます。


実行の準備(cscript/wscript、権限)

cscript と wscript の違い

  • cscript.exe: コマンドラインで実行し、標準出力(コンソール)に結果を出す。ログや出力をファイルにリダイレクトしやすいので学習や運用スクリプトに向いています。
  • wscript.exe: GUI(ダイアログ)ベースで実行。メッセージボックス(MsgBox)を使うスクリプト向け。

学習・実行結果の確認には cscript を使うことをおすすめします。

コマンド例
C:\> cscript //nologo script.vbs

//nologo は余計なヘッダを表示しないオプションです。

権限

一部のWMI操作(サービスの開始/停止、リモート操作、特定のハードウェア情報取得など)は管理者権限が必要です。

管理者としてコマンドプロンプトを開いて実行するか、UACに応じた権限昇格が必要です。


VBScriptからWMIへ接続する基本コード

VBScriptでWMIに接続する代表的な書き方は以下です。

' ローカルのWMIに接続
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

' リモート接続の例(ユーザー名/パスワードを使う)
' Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,(authenticationLevel=PktPrivacy)}\\\\REMOTEHOST\root\cimv2:"
' Set objWMIService = objWMIService.ConnectServer("REMOTEHOST", "root\cimv2", "username", "password")

winmgmts:\\.\root\cimv2 は最もよく使われるネームスペースです。GetObject でWMIサービスのルートに接続します。

クエリ例(WMIのクラスを列挙)
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem")
For Each objItem In colItems
    WScript.Echo objItem.Caption
Next

主要なWMIクラス(初心者がよく使うクラス)

  • Win32_OperatingSystem: OSの名称、バージョン、インストール日など
  • Win32_ComputerSystem: コンピュータ名、ユーザー名、合計物理メモリなど
  • Win32_LogicalDisk: 各論理ドライブの容量、空き容量、ドライブの種類
  • Win32_Process: 実行中のプロセス情報(名前、PID、メモリ使用量)
  • Win32_Service: Windowsサービスの状態(開始/停止/自動/手動)
  • Win32_NetworkAdapterConfiguration: IPアドレスやDNS情報

これらはスクリプトで情報収集や簡単な自動化に非常に便利です。


実用的なサンプル

以下は学習で使える安全なサンプル集です。

各スクリプトはテキストファイルに保存し、.vbs 拡張子で実行してください(cscript //nologo ファイル.vbs)。

サンプル1: OS情報を取得する

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set colOS = objWMI.ExecQuery("SELECT * FROM Win32_OperatingSystem")
For Each os In colOS
    WScript.Echo "Caption: " & os.Caption
    WScript.Echo "Version: " & os.Version
    WScript.Echo "BuildNumber: " & os.BuildNumber
    WScript.Echo "LastBootUpTime: " & os.LastBootUpTime
Next

サンプル2: 論理ディスクの一覧(空き容量をMBで表示)

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set colDisks = objWMI.ExecQuery("SELECT DeviceID, FreeSpace, Size, FileSystem FROM Win32_LogicalDisk WHERE DriveType=3")
For Each disk In colDisks
    If Not IsNull(disk.FreeSpace) Then
        freeMB = Int(disk.FreeSpace / 1024 / 1024)
        sizeMB = Int(disk.Size / 1024 / 1024)
    Else
        freeMB = "N/A"
        sizeMB = "N/A"
    End If
    WScript.Echo disk.DeviceID & " " & freeMB & "MB free / " & sizeMB & "MB total (" & disk.FileSystem & ")"
Next

サンプル3: 実行中のプロセス一覧(名前とPID)

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set procs = objWMI.ExecQuery("SELECT Name, ProcessId FROM Win32_Process")
For Each p In procs
    WScript.Echo p.ProcessId & " - " & p.Name
Next

サンプル4: プロセスを新しく起動する(例: notepad.exe)

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set procClass = objWMI.Get("Win32_Process")
errReturn = procClass.Create("notepad.exe", Null, Null, intProcessID)
If errReturn = 0 Then
    WScript.Echo "Notepad started. PID=" & intProcessID
Else
    WScript.Echo "Failed to start process. Error code: " & errReturn
End If

よくあるエラーと対処法

  • 接続エラー(GetObjectが失敗する): ネームスペースのスペルミスやサービス(WMIサービス)が停止している可能性があります。サービス管理ツールで Windows Management Instrumentation サービスを確認してください。
  • 権限エラー: 一部の情報は管理者権限でないと取得できません。管理者として実行してください。
  • リモート接続の失敗: ネットワーク、ファイアウォール、資格情報、DCOM設定が影響します。最初はローカルで動かしてからリモートに挑戦しましょう。
  • Null/IsNullエラー: WMIのプロパティに値が入っていない場合があります。IsNull()でチェックしましょう。

セキュリティと実行上の注意点

  • WMIは強力な管理インターフェースです。不適切な操作(サービスの停止、プロセスの強制終了、設定変更)はシステムに影響を与えるため、テスト環境で確認してから本番で実行してください。
  • リモートでのWMI操作は認証情報を扱います。パスワードのハードコーディングは避け、必要な最小権限のアカウントを使用してください。

演習問題(初級編)

下の問題は、実際にVBScriptを書いてWMIを使う練習になります。すべてローカルのWindowsで cscript //nologo ファイル.vbs を使って確認してください。

問題1: OSの情報を1行で出力する

Win32_OperatingSystem から OS名(Caption)とバージョン(Version)を取得し、フォーマットして1行で表示するスクリプトを作成してください。

出力例
Windows 10 Pro - Version 10.0.19041
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set colOS = objWMI.ExecQuery("SELECT Caption, Version FROM Win32_OperatingSystem")
For Each os In colOS
    WScript.Echo os.Caption & " - Version " & os.Version
Next

問題2: Cドライブの空き容量をGBで表示する

Win32_LogicalDisk を使い、DeviceID = “C:” のドライブのFreeSpaceをGB単位(小数点第2位まで)で表示するスクリプトを書いてください。値が取得できない場合は「情報なし」と表示してください。

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set colDisks = objWMI.ExecQuery("SELECT DeviceID, FreeSpace FROM Win32_LogicalDisk WHERE DeviceID='C:'")
For Each d In colDisks
    If IsNull(d.FreeSpace) Then
        WScript.Echo "C: - 情報なし"
    Else
        freeGB = Round(d.FreeSpace / 1024 / 1024 / 1024, 2)
        WScript.Echo "C: - FreeSpace: " & freeGB & " GB"
    End If
Next

' Round 関数が無い場合の互換処理
Function Round(num, decimals)
    scale = 10 ^ decimals
    Round = Int(num * scale + 0.5) / scale
End Function

問題3: 指定したプロセス名が実行中かチェックする

引数(コマンドライン引数)でプロセス名(例: notepad.exe)を受け取り、該当プロセスが見つかれば「実行中(PID: xxx)」、見つからなければ「実行していません」と表示するスクリプトを作成してください。

If WScript.Arguments.Count = 0 Then
    WScript.Echo "使い方: cscript //nologo checkproc.vbs プロセス名.exe"
    WScript.Quit
End If
procName = WScript.Arguments(0)
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set procs = objWMI.ExecQuery("SELECT Name, ProcessId FROM Win32_Process WHERE Name='" & procName & "'")
found = False
For Each p In procs
    WScript.Echo "実行中 (PID: " & p.ProcessId & ")"
    found = True
Next
If Not found Then
    WScript.Echo "実行していません"
End If

問題4: サービスの開始状態を取得する

Win32_Service から Name = “wuauserv”(Windows Update サービス)の State を取得し、現在の状態を表示するスクリプトを作ってください(例: Running, Stopped)。管理者権限が必要となる場合があります。

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set services = objWMI.ExecQuery("SELECT Name, State FROM Win32_Service WHERE Name='wuauserv'")
For Each s In services
    WScript.Echo "Service: " & s.Name & " - State: " & s.State
Next

問題5: 起動スクリプト(応用)

notepad.exe を起動し、起動後にそのプロセスのPIDを表示するスクリプトを作成してください。起動に失敗した場合はエラーコードを表示してください。

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set procClass = objWMI.Get("Win32_Process")
errReturn = procClass.Create("notepad.exe", Null, Null, intProcessID)
If errReturn = 0 Then
    WScript.Echo "Notepad started. PID=" & intProcessID
Else
    WScript.Echo "Failed to start process. Error code: " & errReturn
End If