【入門編】【インフラ管理】WMI (Windows Management Instrumentation) を経由したリモートPCのプロセス・サービス監視 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptとWMIでインフラ管理を自動化!リモートPCのプロセス・サービス監視をマスターしよう

皆さん、こんにちは!VBScriptの世界へようこそ。インフラ管理の現場で、日々のルーチンワークに追われていませんか?「あのPCのCPU使用率が高いな…」「このサービス、また止まってるよ…」なんて、手作業で確認したり、再起動したりするのは大変ですよね。

そんな悩みを解決するために、今回はVBScriptとWindows Management Instrumentation (WMI) を使って、リモートPCのプロセスやサービスを監視・管理するスクリプトの作り方を、基礎から丁寧に解説していきます。マクロの記録だけでは物足りなくなってきたあなたも、きっと「なるほど!」と膝を打つはず。

このブログを読み終える頃には、WMIを使ったリモート管理の基本がしっかり身につき、日々の業務を効率化する第一歩を踏み出せているはずですよ!さあ、一緒にVBScriptの奥深い世界を探求していきましょう!

1. VBScriptとWSH(Windows Script Host)って、そもそも何?

まず、VBScriptの前に、これを実行してくれる「Windows Script Host(WSH)」について軽く触れておきましょう。

  • VBScript (Visual Basic Scripting Edition): Microsoftが開発した、Windows上で動作するスクリプト言語です。VB(Visual Basic)に似た構文で、比較的学習しやすいのが特徴です。HTMLにJavaScriptを埋め込むように、Windowsの様々な操作を自動化するために使われます。
  • WSH (Windows Script Host): VBScriptやJavaScriptなどのスクリプトを実行するためのWindowsの標準機能です。コマンドプロンプトやエクスプローラーからスクリプトファイルをダブルクリックするだけで実行できます。WSHがあるおかげで、特別な開発環境を用意しなくても、すぐにスクリプトを動かせるんですね。

VBScriptのここがすごい!

  • 手軽に始められる: テキストエディタ(メモ帳で十分!)があれば、すぐにコードを書き始められます。
  • Windows操作の自動化に強い: ファイル操作、レジストリ操作、アプリケーションの起動など、Windowsの様々な機能をAPI経由で操作できます。
  • COMオブジェクトを扱える: これがWMIを使う上で非常に重要になります。COM(Component Object Model)という仕組みを使うことで、様々なアプリケーションやOSの機能にアクセスできるんです。

2. WMI(Windows Management Instrumentation)の扉を開けよう!

さて、本日の主役、WMIの登場です。WMIは、Windowsシステムの管理情報を取得したり、設定を変更したりするための強力なインターフェースです。例えるなら、Windowsの「取扱説明書」や「操作パネル」のようなもの。これを使えば、OSやハードウェア、アプリケーションの状態をプログラムから自在に読み取ったり、操作したりできるんです。

WMIの3つの柱

WMIを理解するために、以下の3つの要素を覚えておきましょう。

1. WMIリポジトリ (Repository): Windowsシステムに関するあらゆる情報(CPU、メモリ、ディスク、プロセス、サービス、ユーザー情報など)が保存されているデータベースのようなものです。
2. WMIプロバイダ (Provider): WMIリポジトリに保存されている情報を、実際のOSやハードウェアから取得したり、変更したりする役割を担います。例えば、CPUの情報を取得するにはCPUプロバイダが、サービスの情報を取得するにはサービスプロバイダが活躍します。
3. WMIサービス (WinMgmt): WMIリポジトリ、プロバイダ、そしてWMIにアクセスするアプリケーション(今回の場合はVBScript)を仲介する、OSのサービスです。

WMIクエリ言語 (WQL – WMI Query Language)

WMIから情報を取得するには、「WQL」というSQLに似たクエリ言語を使います。これを使えば、「CPU使用率が80%以上のプロセスをすべて取得する」といった、具体的な条件を指定して情報を引き出すことができます。

例: `SELECT FROM Win32_Processor`
これは、システムに搭載されているCPUに関する情報をすべて取得するクエリです。

VBScriptからWMIにアクセスするには?

VBScriptからWMIにアクセスするには、`GetObject` 関数を使って `winmgmts` という特別なオブジェクトを取得します。このオブジェクトを通じて、WMIリポジトリに接続し、クエリを実行したり、クラスのインスタンスを操作したりできるのです。

‘ WMIサービスへの接続オブジェクトを取得
‘ “.” はローカルコンピュータを意味します。リモートの場合はコンピュータ名を指定します。
‘ “root\cimv2” は、OSの管理情報が格納されている名前空間です。
Set objWMIService = GetObject(“winmgmts:\\.\root\cimv2”)

3. リモートPCのCPU/メモリ使用率を取得するスクリプト

まずは、リモートPCのCPUとメモリの使用率を取得するスクリプトから始めましょう。WMIを使えば、驚くほど簡単に取得できます。

CPU使用率の取得

CPU使用率は、`Win32_Processor` クラスの `LoadPercentage` プロパティから取得できます。

‘—————————————————————————
‘ CPU使用率を取得するスクリプト (リモート対応)
‘—————————————————————————

‘ 監視したいリモートコンピュータ名 (ローカルの場合は “.” を指定)
Const REMOTE_COMPUTER = “YOUR_REMOTE_PC_NAME” ‘ ← ここを監視したいPC名に変更してください

‘ WMIサービスへの接続オブジェクトを取得
On Error Resume Next ‘ エラーが発生しても処理を続行する
Set objWMIService = GetObject(“winmgmts:\\” & REMOTE_COMPUTER & “\root\cimv2”)
If Err.Number <> 0 Then
WScript.Echo “エラー: WMIサービスに接続できませんでした。” & vbCrLf & _
“コンピュータ名、またはネットワーク接続を確認してください。” & vbCrLf & _
“エラーコード: ” & Err.Number & ” – ” & Err.Description
WScript.Quit
End If
On Error GoTo 0 ‘ エラーハンドリングを元に戻す

‘ Win32_Processor クラスから情報を取得
‘ 複数のCPUコアがある場合、LoadPercentage は平均値として返されます
Set colProcessors = objWMIService.ExecQuery(“SELECT LoadPercentage FROM Win32_Processor”)

Dim dblTotalCpuLoad, intProcessorCount
dblTotalCpuLoad = 0
intProcessorCount = 0

‘ 各CPUコアのLoadPercentageを合計する
For Each objProcessor in colProcessors
dblTotalCpuLoad = dblTotalCpuLoad + objProcessor.LoadPercentage
intProcessorCount = intProcessorCount + 1
Next

‘ 平均CPU使用率を計算
Dim dblAverageCpuLoad
If intProcessorCount > 0 Then
dblAverageCpuLoad = dblTotalCpuLoad / intProcessorCount
WScript.Echo “コンピュータ名: ” & REMOTE_COMPUTER
WScript.Echo “CPU使用率: ” & Round(dblAverageCpuLoad, 2) & “%”
Else
WScript.Echo “コンピュータ名: ” & REMOTE_COMPUTER
WScript.Echo “CPU情報を取得できませんでした。”
End If

‘ オブジェクトを解放
Set colProcessors = Nothing
Set objWMIService = Nothing

WScript.Echo vbCrLf & “処理が完了しました。”

コードのポイント:

  • `REMOTE_COMPUTER = “YOUR_REMOTE_PC_NAME”`: ここを監視したいPCの名前に変更してください。ローカルPCで実行する場合は `”.”` を指定します。
  • `GetObject(“winmgmts:\\” & REMOTE_COMPUTER & “\root\cimv2”)`: リモートPCのWMIサービスに接続しています。
  • `objWMIService.ExecQuery(“SELECT LoadPercentage FROM Win32_Processor”)`: WQLを使って、CPUの `LoadPercentage` プロパティを取得するクエリを実行しています。
  • `For Each … Next`: 複数のCPUコアがある場合、それぞれの `LoadPercentage` を取得し、平均を計算しています。
  • エラーハンドリング: `On Error Resume Next` と `If Err.Number <> 0 Then` を使って、WMI接続に失敗した場合のエラー処理を入れています。リモート接続では、ネットワークの問題や権限の問題で失敗することがよくあるので、この処理は非常に重要です。

メモリ使用率の取得

メモリ使用率は、`Win32_OperatingSystem` クラスから `TotalVisibleMemorySize` と `FreePhysicalMemory` を取得し、計算することで求められます。

‘—————————————————————————
‘ メモリ使用率を取得するスクリプト (リモート対応)
‘—————————————————————————

‘ 監視したいリモートコンピュータ名 (ローカルの場合は “.” を指定)
Const REMOTE_COMPUTER = “YOUR_REMOTE_PC_NAME” ‘ ← ここを監視したいPC名に変更してください

‘ WMIサービスへの接続オブジェクトを取得
On Error Resume Next
Set objWMIService = GetObject(“winmgmts:\\” & REMOTE_COMPUTER & “\root\cimv2”)
If Err.Number <> 0 Then
WScript.Echo “エラー: WMIサービスに接続できませんでした。” & vbCrLf & _
“コンピュータ名、またはネットワーク接続を確認してください。” & vbCrLf & _
“エラーコード: ” & Err.Number & ” – ” & Err.Description
WScript.Quit
End If
On Error GoTo 0

‘ Win32_OperatingSystem クラスからメモリ情報を取得
Set colOperatingSystems = objWMIService.ExecQuery(“SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem”)

Dim objOS
For Each objOS in colOperatingSystems
‘ メモリサイズはKB単位で取得される
Dim totalMemoryKB, freeMemoryKB, usedMemoryKB
totalMemoryKB = objOS.TotalVisibleMemorySize
freeMemoryKB = objOS.FreePhysicalMemory

‘ 使用メモリを計算
usedMemoryKB = totalMemoryKB – freeMemoryKB

‘ 使用率を計算 (0除算を防ぐ)
Dim memoryUsagePercentage
If totalMemoryKB > 0 Then
memoryUsagePercentage = (usedMemoryKB / totalMemoryKB) 100
Else
memoryUsagePercentage = 0
End If

WScript.Echo “コンピュータ名: ” & REMOTE_COMPUTER
WScript.Echo “総メモリ容量 (KB): ” & totalMemoryKB
WScript.Echo “空きメモリ容量 (KB): ” & freeMemoryKB
WScript.Echo “使用メモリ量 (KB): ” & usedMemoryKB
WScript.Echo “メモリ使用率: ” & Round(memoryUsagePercentage, 2) & “%”
Next

‘ オブジェクトを解放
Set colOperatingSystems = Nothing
Set objWMIService = Nothing

WScript.Echo vbCrLf & “処理が完了しました。”

コードのポイント:

  • `TotalVisibleMemorySize`: システムが認識できる物理メモリの合計容量 (KB単位)。
  • `FreePhysicalMemory`: 現在空いている物理メモリの容量 (KB単位)。
  • これらの値を使って、使用メモリ量と使用率を計算しています。

4. 特定プロセスの強制終了

「このプロセス、リソースを食いつぶしてるから止めたい!」そんな時に役立つのが、プロセスの強制終了です。WMIを使えば、リモートPC上のプロセスを安全に(?)停止させることができます。

‘—————————————————————————
‘ 特定プロセスの強制終了スクリプト (リモート対応)
‘—————————————————————————

‘ 監視・操作したいリモートコンピュータ名 (ローカルの場合は “.” を指定)
Const REMOTE_COMPUTER = “YOUR_REMOTE_PC_NAME” ‘ ← ここを監視したいPC名に変更してください
‘ 終了させたいプロセスの名前 (例: “notepad.exe”, “chrome.exe”)
Const PROCESS_TO_TERMINATE = “notepad.exe” ‘ ← ここを終了させたいプロセス名に変更してください

‘ WMIサービスへの接続オブジェクトを取得
On Error Resume Next
Set objWMIService = GetObject(“winmgmts:\\” & REMOTE_COMPUTER & “\root\cimv2”)
If Err.Number <> 0 Then
WScript.Echo “エラー: WMIサービスに接続できませんでした。” & vbCrLf & _
“コンピュータ名、またはネットワーク接続を確認してください。” & vbCrLf & _
“エラーコード: ” & Err.Number & ” – ” & Err.Description
WScript.Quit
End If
On Error GoTo 0

‘ Win32_Process クラスから、指定したプロセス名に一致するものを検索
‘ WHERE句でプロセス名を指定します。LIKE演算子で部分一致も可能ですが、ここでは完全一致を使います。
Dim strWQL
strWQL = “SELECT ProcessId FROM Win32_Process WHERE Name = ‘” & PROCESS_TO_TERMINATE & “‘”
Set colProcesses = objWMIService.ExecQuery(strWQL)

Dim intProcessesTerminated, objProcess

intProcessesTerminated = 0

If colProcesses.Count > 0 Then
For Each objProcess in colProcesses
‘ プロセスのTerminateメソッドを呼び出して強制終了
‘ Terminateメソッドは、成功するとリターンコード0を返します。
‘ (ただし、成功しない場合も0を返すことがあるため、注意が必要です)
Dim result
result = objProcess.Terminate()

If result = 0 Then
WScript.Echo “プロセス ‘” & PROCESS_TO_TERMINATE & “‘ (ID: ” & objProcess.ProcessId & “) を正常に終了しました。”
intProcessesTerminated = intProcessesTerminated + 1
Else
WScript.Echo “プロセス ‘” & PROCESS_TO_TERMINATE & “‘ (ID: ” & objProcess.ProcessId & “) の終了に失敗しました。リターンコード: ” & result
End If
Next
WScript.Echo vbCrLf & intProcessesTerminated & “個のプロセスを終了しました。”
Else
WScript.Echo “プロセス ‘” & PROCESS_TO_TERMINATE & “‘ は見つかりませんでした。”
End If

‘ オブジェクトを解放
Set colProcesses = Nothing
Set objWMIService = Nothing

WScript.Echo vbCrLf & “処理が完了しました。”

コードのポイント:

  • `PROCESS_TO_TERMINATE = “notepad.exe”`: 終了させたいプロセス名(実行ファイル名)を指定します。
  • `objWMIService.ExecQuery(“SELECT ProcessId FROM Win32_Process WHERE Name = ‘” & PROCESS_TO_TERMINATE & “‘”)`: `Win32_Process` クラスから、指定した名前のプロセスの `ProcessId` を取得しています。
  • `objProcess.Terminate()`: 取得したプロセスオブジェクトの `Terminate` メソッドを呼び出し、プロセスを強制終了します。
  • 注意点: `Terminate` メソッドは、必ずしも成功するとは限りません。システムプロセスや管理者権限が必要なプロセスは、終了できない場合があります。また、終了コードが必ずしも正確に成功/失敗を示さない場合もあるため、注意が必要です。

5. サービスの再起動

「このサービス、調子が悪くなったから再起動したい!」これもWMIにお任せください。`Win32_Service` クラスを使えば、サービスの開始、停止、再起動が可能です。

‘—————————————————————————
‘ サービスを再起動するスクリプト (リモート対応)
‘—————————————————————————

‘ 監視・操作したいリモートコンピュータ名 (ローカルの場合は “.” を指定)
Const REMOTE_COMPUTER = “YOUR_REMOTE_PC_NAME” ‘ ← ここを監視したいPC名に変更してください
‘ 再起動したいサービス名 (例: “Spooler”, “W3SVC”)
Const SERVICE_TO_RESTART = “Spooler” ‘ ← ここを再起動したいサービス名に変更してください

‘ WMIサービスへの接続オブジェクトを取得
On Error Resume Next
Set objWMIService = GetObject(“winmgmts:\\” & REMOTE_COMPUTER & “\root\cimv2”)
If Err.Number <> 0 Then
WScript.Echo “エラー: WMIサービスに接続できませんでした。” & vbCrLf & _
“コンピュータ名、またはネットワーク接続を確認してください。” & vbCrLf & _
“エラーコード: ” & Err.Number & ” – ” & Err.Description
WScript.Quit
End If
On Error GoTo 0

‘ Win32_Service クラスから、指定したサービス名に一致するものを検索
Dim strWQL
strWQL = “SELECT FROM Win32_Service WHERE Name = ‘” & SERVICE_TO_RESTART & “‘”
Set colServices = objWMIService.ExecQuery(strWQL)

Dim objService, result

If colServices.Count > 0 Then
For Each objService in colServices
‘ サービスの状態を取得
Dim serviceState
serviceState = objService.State

WScript.Echo “サービス ‘” & SERVICE_TO_RESTART & “‘ の現在の状態: ” & serviceState

‘ サービスが実行中の場合のみ停止処理を行う
If serviceState = “Running” Then
WScript.Echo “サービスを停止しています…”
result = objService.StopService()
If result = 0 Then
WScript.Echo “サービスを正常に停止しました。”
Else
WScript.Echo “サービス ‘” & SERVICE_TO_RESTART & “‘ の停止に失敗しました。リターンコード: ” & result
‘ 停止に失敗したら、それ以上進まずに処理を終了
Set colServices = Nothing
Set objWMIService = Nothing
WScript.Quit
End If
End If

‘ サービスが停止している場合のみ開始処理を行う (または、停止成功後に開始)
‘ サービスが停止しているか、または正常に停止できた場合
‘ 再度サービスの状態を取得して確認する方が確実ですが、ここでは簡略化します。
WScript.Echo “サービスを開始しています…”
result = objService.StartService()

If result = 0 Then
WScript.Echo “サービス ‘” & SERVICE_TO_RESTART & “‘ を正常に開始しました。”
Else
WScript.Echo “サービス ‘” & SERVICE_TO_RESTART & “‘ の開始に失敗しました。リターンコード: ” & result
End If
Exit For ‘ サービスは一意なので、最初に見つかったもので処理を終了
Next
Else
WScript.Echo “サービス ‘” & SERVICE_TO_RESTART & “‘ は見つかりませんでした。”
End If

‘ オブジェクトを解放
Set colServices = Nothing
Set objWMIService = Nothing

WScript.Echo vbCrLf & “処理が完了しました。”

コードのポイント:

  • `SERVICE_TO_RESTART = “Spooler”`: 操作したいサービス名(サービス管理ツールで表示される「名前」)を指定します。
  • `objWMIService.ExecQuery(“SELECT FROM Win32_Service WHERE Name = ‘” & SERVICE_TO_RESTART & “‘”)`: `Win32_Service` クラスから、指定した名前のサービス情報を取得しています。
  • `objService.State`: サービスの現在の状態(Running, Stoppedなど)を取得します。
  • `objService.StopService()`: サービスを停止します。
  • `objService.StartService()`: サービスを開始します。
  • 再起動のロジック: まずサービスが実行中であれば停止し、その後開始しています。これにより、安全な再起動処理を実現しています。

6. 陥りやすいエラーとその対策

VBScriptでWMIを使う上で、よく遭遇するエラーとその対策をいくつかご紹介します。

  • エラー: WMIサービスに接続できませんでした。
  • 原因:
  • リモートPC名が間違っている。
  • リモートPCがネットワークに接続されていない、または電源が入っていない。
  • リモートPCのファイアウォールでWMI通信(DCOM)がブロックされている。
  • スクリプトを実行しているユーザーに、リモートPCへのアクセス権限がない。
  • 対策:
  • PC名を正確に確認する。
  • `ping` コマンドなどでネットワーク接続を確認する。
  • リモートPCのファイアウォール設定で、「Windows Management Instrumentation (WMI)」の受信規則を有効にする。
  • リモートPCの「ローカルセキュリティポリシー」や「グループポリシー」で、リモートWMIアクセスを許可するユーザーを確認・設定する。管理者権限で実行してみる。
  • エラー: 無効なプロパティです。
  • 原因: 指定したクラス名やプロパティ名が間違っている。
  • 対策: WMIクラスやプロパティは、Microsoftのドキュメント(MSDNなど)で正確な名前を確認しましょう。`Get-CimClass` (PowerShell) や `wmic` コマンドラインツールで、クラスやプロパティの存在を確認するのも有効です。
  • エラー: オブジェクトは、このプロパティまたはメソッドをサポートしていません。
  • 原因: WMIクラスのインスタンス(個々のオブジェクト)に対して、存在しないメソッドを呼び出そうとしている。例えば、`Win32_Process` クラスのインスタンスに対して `StartService` メソッドを呼び出そうとした場合など。
  • 対策: 操作したい対象がどのWMIクラスのインスタンスなのかを正しく理解し、そのクラスが提供するメソッドを呼び出すようにしましょう。
  • エラー: アクセスが拒否されました。
  • 原因: リモートPCでスクリプトを実行するための権限がない。
  • 対策:
  • リモートPCのローカル管理者グループに、スクリプトを実行するユーザーを追加する。
  • ドメイン環境であれば、ドメイン管理者権限を持つユーザーで実行する。
  • WMIのセキュリティ設定を確認する。

7. さあ、自動化の扉を開こう!

いかがでしたでしょうか?
今回は、VBScriptとWMIを使って、リモートPCのCPU/メモリ使用率の取得、プロセスの強制終了、サービスの再起動といった、インフラ管理の基本となるタスクを自動化する方法をご紹介しました。

これらのスクリプトは、そのままコピー&ペーストしてすぐに活用できます。まずはご自身のPCや、テスト用のPCで試してみてください。そして、`REMOTE_COMPUTER` や `PROCESS_TO_TERMINATE`、`SERVICE_TO_RESTART` の部分を色々と変更して、色々なケースを試してみるのが上達への近道です。

ここをクリアすれば、VBScript (Visual Basic Scripting Edition) と WMI の基本はバッチリですよ!

今回紹介した内容は、WMIのほんの入り口に過ぎません。WMIには、ディスクの空き容量、イベントログの取得、ユーザーアカウントの管理など、まだまだたくさんの機能が眠っています。ぜひ、今回学んだ知識を足がかりに、さらに深いWMIの世界を探求してみてください。

あなたのインフラ管理業務が、このスクリプトによって少しでも楽になることを願っています!Happy Scripting!

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