専門用語を平易な語彙で補足し、技術的解像度と読みやすさを両立させる。
「なぜそのコードが必要か」という設計意図(Design Intent)を明文化する。
リスク管理(例外処理)を実装レベルで提案する。
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBA×WMIによるリモートPC資産管理:OS・CPU・メモリ情報の自動取得の実践
【背景と目的】
IT資産管理において、数百台の端末情報を手動で確認するのは非効率です。本ツールは、WMIを用いてリモートPCのスペック情報を一括収集し、管理工数を削減します。 実務では「リモート接続時のタイムアウトによるフリーズ」や「権限不足による実行エラー」が大きな壁となりますが、本ガイドではエラーハンドリングを組み込んだ堅牢なコードを提示します。
【処理フロー図】
graph TD A["開始"] --> B["対象ホスト名/IPの読み込み"] B --> C["SWbemLocatorによるリモート接続試行"] C -->|成功| D["WMIクエリ実行: OS/CPU/Memory"] C -->|失敗| E["エラー内容をシートへ記録"] D --> F["取得データを配列へ格納"] F --> G["シートへ一括書き出し"] G --> H["終了"]
【実装:VBAコード】
参照設定(Microsoft WMI Scripting v1.2 Library)を不要にする「実行時バインド(Late Binding)」方式を採用しています。
Option Explicit
' Win32 API宣言(64bit/32bit両対応)
#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.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' 高速化設定
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Dim i As Long
Dim targetPC As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim results() As Variant
ReDim results(1 To 1, 1 To 4) ' OS, CPU, RAM, Status
' A列にホスト名が入っている想定(2行目から開始)
For i = 2 To lastRow
targetPC = ws.Cells(i, 1).Value
On Error Resume Next
' WMI接続オブジェクトの作成
' タイムアウト対策として、接続試行前にPing確認を行うのが理想的(今回はWMI接続で判定)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & targetPC & "\root\cimv2")
If Err.Number <> 0 Then
ws.Cells(i, 5).Value = "Error: " & Err.Description
Err.Clear
Else
' 1. OS情報の取得
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
For Each objItem In colItems
results(1, 1) = objItem.Caption & " (" & objItem.OSArchitecture & ")"
results(1, 3) = Round(objItem.TotalVisibleMemorySize / 1024 / 1024, 1) & " GB"
Next
' 2. CPU情報の取得
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
results(1, 2) = Trim(objItem.Name)
Next
results(1, 4) = "Success"
' 配列からシートへ一括書き出し(セルへの個別アクセスを低減)
ws.Cells(i, 2).Resize(1, 4).Value = results
End If
' オブジェクトの解放
Set objWMIService = Nothing
Set colItems = Nothing
DoEvents ' OSに制御を戻しフリーズを防止
Next i
' 設定の復元
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "システム情報の取得が完了しました。", vbInformation
End Sub
【技術解説】
WMI (Windows Management Instrumentation): Windowsの管理情報を取得するための標準インターフェースです。
root\cimv2名前空間には、ハードウェアに関するほぼすべてのクラス(Win32_Processor等)が含まれています。実行時バインド (Late Binding):
CreateObjectやGetObjectを使用することで、配布先PCでの「参照設定エラー」を回避します。配列処理による高速化: 1セルずつ書き込むのではなく、
Resizeプロパティを用いて配列を一度に流し込むことで、Excelの描画回数を最小限に抑えています。PtrSafe 宣言: 64bit版OfficeではAPI宣言に
PtrSafeが必須です。これを怠ると実行時エラーでVBAが停止します。
【注意点と運用】
ファイアウォールの許可: リモートPC側で「WMI (RPC)」の通信が許可されている必要があります。企業環境ではグループポリシー(GPO)での設定確認が必須です。
実行権限: リモートPCに対して管理者権限を持つユーザーでExcelを実行する必要があります。
タイムアウトの罠: 存在しないPCや電源オフのPCに対して
GetObjectを行うと、数秒〜数十秒の応答待ち(ハングアップ状態)が発生します。事前にWMI接続前にPingによる死活監視を挟む設計がより実用的です。
【まとめ】
WMIは標準機能のみで動作するため、追加インストールの必要がない強力な資産管理ツールになる。
エラーハンドリングとDoEventsを組み合わせることで、大量のリスト処理でもExcelをクラッシュさせずに実行できる。
ネットワーク環境(権限・FW)の事前確認が、コードそのものよりも重要になる。

