専門家としての威厳と、実務者に寄り添う親切さを両立したトーン。
可読性を最優先し、コードブロックや表、箇条書きを効果的に使用。
実行速度、エラーハンドリング、保守性の3点にこだわった解説。
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBA×WMIで実現するリモートPCスペック一括取得:管理工数削減ガイド
【背景と目的】
IT資産管理において、数百台のPCスペックを手作業で確認するのは現実的ではありません。本ガイドでは、VBAからWMI(Windows Management Instrumentation)を介して、リモートPCのOS・CPU・メモリ情報を自動収集する手法を解説します。ネットワーク遅延によるフリーズや接続エラーといった実務上の課題を、適切なエラーハンドリングと高速な配列処理で解決します。
【処理フロー図】
graph TD
A["開始"] --> B["対象PCリストを配列に格納"]
B --> C{"接続試行"}
C -->|成功| D["WMIクエリ実行 OS/CPU/RAM"]
C -->|失敗| E["エラー情報を記録"]
D --> F["取得データを配列に蓄積"]
E --> F
F --> G{"全台終了?"}
G -->|No| C
G -->|Yes| H["シートへ一括出力"]
H --> I["終了"]
【実装:VBAコード】
参照設定を不要にする「レイトバインディング」を採用し、配布しやすい構成にしています。また、画面更新停止と配列処理により高速化を図っています。
Option Explicit
' 64bit環境を考慮したAPI宣言(待機処理用)
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "A列にPC名またはIPアドレスを入力してください。", vbExclamation
Exit Sub
End If
' 高速化のための設定
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim targetRange As Variant
targetRange = ws.Range("A2:A" & lastRow).Value ' 対象PCリストを配列へ
Dim resultData() As Variant
ReDim resultData(1 To UBound(targetRange, 1), 1 To 4) ' OS, CPU, RAM, Status
Dim i As Long
Dim strComputer As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
For i = 1 To UBound(targetRange, 1)
strComputer = targetRange(i, 1)
If strComputer <> "" Then
On Error Resume Next
' WMIサービスへの接続(タイムアウト対策としてエラーハンドリングを重視)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
If Err.Number <> 0 Then
resultData(i, 4) = "接続失敗: " & Err.Description
Err.Clear
Else
' --- OS情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Caption From Win32_OperatingSystem")
For Each objItem In colItems
resultData(i, 1) = objItem.Caption
Next
' --- CPU情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Name From Win32_Processor")
For Each objItem In colItems
resultData(i, 2) = objItem.Name
Next
' --- メモリ情報の取得 (GB換算) ---
Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory From Win32_ComputerSystem")
For Each objItem In colItems
resultData(i, 3) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
resultData(i, 4) = "成功"
End If
On Error GoTo 0
End If
' オブジェクトの解放
Set objWMIService = Nothing
Set colItems = Nothing
Next i
' 結果を一括書き出し
ws.Range("B2").Resize(UBound(resultData, 1), 4).Value = resultData
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "情報取得が完了しました。", vbInformation
End Sub
【技術解説】
WMI (Windows Management Instrumentation): Windows OSを管理するためのインターフェースです。
GetObjectでリモートマシンの名前空間(root\cimv2)に接続することで、SQLライクなクエリ(WQL)でシステム情報を抽出できます。配列処理による高速化: セルへの書き込みは1回ごとに行うと非常に低速です。本コードでは、結果を一旦
resultData配列に格納し、最後にResizeメソッドで一括出力することで、処理時間を劇的に短縮しています。レイトバインディング:
Object型を使用することで、実行環境に依存する「Microsoft WMI Scripting V1.2 Library」への参照設定が不要になり、他者のPCでもそのまま動作します。
【注意点と運用】
ファイアウォールの許可: リモートPC側で「リモート管理 (WMI)」の通信が許可されている必要があります(TCPポート135など)。
管理者権限: 実行するユーザーは、リモートPCに対して管理者権限(Administrator権限)を持っている必要があります。ドメイン環境であれば、ドメイン管理者が実行するのがスムーズです。
タイムアウトの課題: PCがオフラインの場合、
GetObjectで接続がタイムアウトするまで数秒フリーズします。大量のPCをスキャンする場合は、事前にPingを飛ばして生存確認を行うロジックを追加することをお勧めします。
【まとめ】
WMIはエージェントレスで情報を取得できる強力なツールである。
リモート接続時はエラーハンドリング(On Error Resume Next)が不可欠。
大量データ処理時は、配列にデータを蓄積して一括出力するのがVBAの鉄則。

コメント