VBAとWMIで実現する:リモートPCのシステム構成情報を一括取得する自動化ツール

Tech

本記事は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

【技術解説】

  1. WMI (Windows Management Instrumentation): Windows OSの構成情報を管理するための基盤インターフェースです。GetObject でリモートPCの root\cimv2 名前空間に接続します。

  2. 遅延バインディング (Late Binding): CreateObjectGetObject を使用することで、特定のタイプライブラリへの参照設定(Reference Setting)なしで動作させ、環境依存のエラーを回避しています。

  3. 配列による一括処理: セルへの書き込みはオーバーヘッドが大きいため、すべての取得結果を一度 Variant 配列に格納し、最後に Resize メソッドでシートへ一括出力することで処理時間を大幅に短縮しています。

【注意点と運用】

  • ファイアウォールの許可: リモートPC側で「Windows Management Instrumentation (WMI)」の通信(RPC)が許可されている必要があります。

  • 実行権限: リモートPCに対して管理者権限を持つユーザーでマクロを実行する必要があります。ドメイン環境であれば、ドメイン管理者の権限が推奨されます。

  • 応答なしへの対策: ネットワーク的に存在しないIPを指定すると、GetObject で数十秒間フリーズする場合があります。事前に Ping 等で生存確認を行うロジックを組み込むことで、より堅牢なツールとなります。

【まとめ】

  • 一括処理が鍵: セル書き込みを最小限に抑え、配列を活用して高速化を図る。

  • 例外処理の徹底: On Error Resume Next を活用し、1台のオフラインPCでマクロ全体を止めない設計にする。

  • 環境の事前確認: WMI通信を妨げるファイアウォール設定や権限不足が最大の「落とし穴」であることを意識する。

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

コメント

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