VBA×WMIで実現するリモートPCスペック一括取得:管理工数削減ガイド

Tech

  • 専門家としての威厳と、実務者に寄り添う親切さを両立したトーン。

  • 可読性を最優先し、コードブロックや表、箇条書きを効果的に使用。

  • 実行速度、エラーハンドリング、保守性の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

【技術解説】

  1. WMI (Windows Management Instrumentation): Windows OSを管理するためのインターフェースです。GetObject でリモートマシンの名前空間(root\cimv2)に接続することで、SQLライクなクエリ(WQL)でシステム情報を抽出できます。

  2. 配列処理による高速化: セルへの書き込みは1回ごとに行うと非常に低速です。本コードでは、結果を一旦 resultData 配列に格納し、最後に Resize メソッドで一括出力することで、処理時間を劇的に短縮しています。

  3. レイトバインディング: Object 型を使用することで、実行環境に依存する「Microsoft WMI Scripting V1.2 Library」への参照設定が不要になり、他者のPCでもそのまま動作します。

【注意点と運用】

  • ファイアウォールの許可: リモートPC側で「リモート管理 (WMI)」の通信が許可されている必要があります(TCPポート135など)。

  • 管理者権限: 実行するユーザーは、リモートPCに対して管理者権限(Administrator権限)を持っている必要があります。ドメイン環境であれば、ドメイン管理者が実行するのがスムーズです。

  • タイムアウトの課題: PCがオフラインの場合、GetObject で接続がタイムアウトするまで数秒フリーズします。大量のPCをスキャンする場合は、事前に Ping を飛ばして生存確認を行うロジックを追加することをお勧めします。

【まとめ】

  • WMIはエージェントレスで情報を取得できる強力なツールである。

  • リモート接続時はエラーハンドリング(On Error Resume Next)が不可欠。

  • 大量データ処理時は、配列にデータを蓄積して一括出力するのがVBAの鉄則。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

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