本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBAとWMIで実現する「リモートPC情報一括取得システム」の構築
【背景と目的】
IT資産管理や保守にて、複数端末の情報を手動収集する負荷を解消。VBAとWMIで、OS・CPU・メモリ情報を一括取得・自動集計する仕組みを提案します。
【処理フロー図】
graph TD A["開始"] --> B["ターゲットPCリスト読み込み"] B --> C["リモートWMI接続試行"] C -->|成功| D["OS/CPU/RAM情報をクエリ"] C -->|失敗| E["エラー内容をログ出力"] D --> F["配列に結果を格納"] F --> G["ワークシートへ一括書き出し"] G --> H["終了"]
【実装:VBAコード】
Option Explicit
' Win32 APIを使用する場合のPtrSafe宣言(本コードではWMIをLate Bindingで使用)
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
''' <summary>
''' リモートPCの情報を取得し、アクティブシートに出力する
''' </summary>
Public Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' 処理高速化の設定
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Dim pcName As String
Dim i As Long
Dim results() As Variant
ReDim results(1 To lastRow - 1, 1 To 4) ' OS, CPU, RAM, Status
On Error Resume Next
For i = 2 To lastRow
pcName = ws.Cells(i, 1).Value
If pcName <> "" Then
' 情報取得処理
Call FetchWmiData(pcName, results, i - 1)
End If
Next i
' シートへ一括出力(セルへの個別書き込みを避けて高速化)
ws.Range("B2").Resize(UBound(results, 1), 4).Value = results
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "情報取得が完了しました。", vbInformation
End Sub
''' <summary>
''' WMIクエリを実行してシステム情報を配列に格納
''' </summary>
Private Sub FetchWmiData(ByVal pcName As String, ByRef results() As Variant, ByVal idx As Long)
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim connectionPath As String
' リモート接続パスの構築(名前解決ができる前提)
connectionPath = "winmgmts:{impersonationLevel=impersonate}!\\" & pcName & "\root\cimv2"
Set objWMIService = GetObject(connectionPath)
If Err.Number <> 0 Then
results(idx, 4) = "接続エラー: " & Err.Description
Err.Clear
Exit Sub
End If
' 1. OS情報の取得
Set colItems = objWMIService.ExecQuery("Select Caption From Win32_OperatingSystem")
For Each objItem In colItems
results(idx, 1) = objItem.Caption
Next
' 2. CPU情報の取得
Set colItems = objWMIService.ExecQuery("Select Name From Win32_Processor")
For Each objItem In colItems
results(idx, 2) = objItem.Name
Next
' 3. メモリ情報の取得 (単位: GBに変換)
Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory From Win32_ComputerSystem")
For Each objItem In colItems
results(idx, 3) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
results(idx, 4) = "成功"
End Sub
【技術解説】
Late Binding (遅延結合): 参照設定(Microsoft WMI Scripting Library)を不要にするため、
CreateObjectやGetObjectを使用。配布時の環境差異による「参照不可」エラーを防止します。WQL (WMI Query Language):
Select * From...形式でSQLのようにOS内部情報を取得。Win32_OperatingSystem(OS名)、Win32_Processor(CPU名)、Win32_ComputerSystem(物理メモリ)を利用しています。高速化ロジック: セルへの書き込みをループ内で行わず、一度配列(
results)に格納してからResizeメソッドで一括出力。100台規模の処理でもオーバーヘッドを最小化します。
【注意点と運用】
管理者権限とファイアウォール: リモートPC側で「WMIの許可」および「RPC通信(TCP 135番等)」が許可されている必要があります。ドメイン環境でない場合、接続が拒否されるケースが多いです。
タイムアウト: 存在しないPC名やオフラインの端末に対しては、
GetObjectで数十秒フリーズする場合があります。事前にPingコマンド等で死活確認を行うロジックの追加を推奨します。UACの影響: ローカル管理者権限を持つユーザーでExcelを実行する必要があります。
【まとめ】
権限の確認: 実行ユーザーが対象PCの管理者権限を持っていることが大前提です。
配列の活用: セル操作を最小限に抑えることで、大量端末の処理速度を劇的に向上させます。
エラー処理の徹底: 接続失敗を想定し、
On Error Resume Nextとステータスログ出力をセットで運用しましょう。

