本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBAとWMIで実現する:リモートPCのシステム構成情報を一括取得する自動化ツール
【背景と目的】
IT資産管理や障害調査において、複数端末のスペック情報を手動で収集するのは非効率です。接続遅延や権限エラーによるマクロの中断を防ぎ、OS・CPU・メモリ情報を高速に取得する仕組みを構築します。
【処理フロー図】
graph TD
A["開始"] --> B["対象ホスト名/IPの読み込み"]
B --> C{"接続試行"}
C -->|成功| D["WMIクエリ実行 OS/CPU/RAM"]
C -->|失敗| E["エラーログ記録"]
D --> F["配列へデータ格納"]
E --> G{"次ホストあり?"}
F --> G
G -->|Yes| C
G -->|No| H["シートへ一括出力"]
H --> I["終了"]
【実装:VBAコード】
参照設定を不要にするため、実行時バインディング(Late Binding)を採用しています。また、描画停止と配列処理により処理速度を最適化しています。
Option Explicit
' ================================================================
' システム情報取得ツール(WMIリモート接続版)
' 機能を安定させるため、エラーハンドリングと一括出力を実装
' ================================================================
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then
MsgBox "A列に対象のPC名またはIPアドレスを入力してください。", vbExclamation
Exit Sub
End If
' 高速化設定
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim hosts As Variant
hosts = ws.Range("A2:A" & lastRow).Value ' A列からホスト名を取得
Dim results() As Variant
ReDim results(1 To UBound(hosts, 1), 1 To 5) ' 結果格納用配列(OS, CPU, Cores, RAM, Error)
Dim i As Long
Dim strHost As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
On Error Resume Next
For i = 1 To UBound(hosts, 1)
strHost = hosts(i, 1)
If strHost <> "" Then
' WMIサービスへの接続(タイムアウト設定はOS標準に依存)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strHost & "\root\cimv2")
If Err.Number <> 0 Then
results(i, 5) = "接続失敗: " & Err.Description
Err.Clear
Else
' --- OS情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Caption from Win32_OperatingSystem")
For Each objItem In colItems
results(i, 1) = objItem.Caption
Next
' --- CPU情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Name, NumberOfCores from Win32_Processor")
For Each objItem In colItems
results(i, 2) = objItem.Name
results(i, 3) = objItem.NumberOfCores & " Cores"
Next
' --- メモリ情報の取得 (GB換算) ---
Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory from Win32_ComputerSystem")
For Each objItem In colItems
results(i, 4) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
results(i, 5) = "成功"
End If
End If
Set objWMIService = Nothing
Next i
On Error GoTo 0
' 結果をシートに一括出力(B列からF列)
ws.Range("B2").Resize(UBound(results, 1), 5).Value = results
' 高速化設定の解除
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "情報取得が完了しました。", vbInformation
End Sub
【技術解説】
WMI (Windows Management Instrumentation): Windows OSの構成情報を管理するための基盤インターフェースです。
GetObjectでリモートPCのroot\cimv2名前空間に接続します。遅延バインディング (Late Binding):
CreateObjectやGetObjectを使用することで、特定のタイプライブラリへの参照設定(Reference Setting)なしで動作させ、環境依存のエラーを回避しています。配列による一括処理: セルへの書き込みはオーバーヘッドが大きいため、すべての取得結果を一度
Variant配列に格納し、最後にResizeメソッドでシートへ一括出力することで処理時間を大幅に短縮しています。
【注意点と運用】
ファイアウォールの許可: リモートPC側で「Windows Management Instrumentation (WMI)」の通信(RPC)が許可されている必要があります。
実行権限: リモートPCに対して管理者権限を持つユーザーでマクロを実行する必要があります。ドメイン環境であれば、ドメイン管理者の権限が推奨されます。
応答なしへの対策: ネットワーク的に存在しないIPを指定すると、
GetObjectで数十秒間フリーズする場合があります。事前にPing等で生存確認を行うロジックを組み込むことで、より堅牢なツールとなります。
【まとめ】
一括処理が鍵: セル書き込みを最小限に抑え、配列を活用して高速化を図る。
例外処理の徹底:
On Error Resume Nextを活用し、1台のオフラインPCでマクロ全体を止めない設計にする。環境の事前確認: WMI通信を妨げるファイアウォール設定や権限不足が最大の「落とし穴」であることを意識する。

コメント