VBA×WMI:リモートPCのシステム情報を一括取得する効率的アプローチ

VBA・Officeカテゴリを表すパンダのイラスト VBA・Office

IT資産管理での手動確認は非効率です。VBAとWMIを用いてネットワーク経由で複数台のスペック情報を自動取得し、管理業務を高速化する手法を解説します。本記事では、外部ライブラリの参照設定が不要なレイトバインディングと、配列による一括処理を活用した効率的なリモート情報収集コードを提供します。

【背景と目的】

複数台のWindows端末に対して、OSのバージョン、CPU、搭載メモリなどのシステム情報を個別に確認して回るのは膨大な手間がかかります。ネットワーク経由でWMI(Windows Management Instrumentation)を利用すれば、VBAからリモートPCへ接続して一括で情報を収集し、Excelのシート上に一覧化することが可能です。

【処理フロー図】

graph TD
A["開始"] --> B["対象PCリストの読み込み"]
B --> C["WMI接続試行"]
C -->|成功| D["OS・CPU・メモリ情報の取得"]
C -->|失敗| E["エラーログ記録"]
D --> F["配列へ格納"]
F --> G["シートへの一括書き出し"]
G --> H["終了"]

【実装:VBAコード】

Option Explicit

' 64bit環境に対応したAPI宣言(待機処理用)
#If Win64 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

''' 
''' 指定したPC名のリストからシステム情報を取得し、アクティブシートに出力する
''' 
Sub GetRemoteSystemInfo()
    Dim ws As Worksheet
    Set ws = ActiveSheet

    Dim pcList As Variant
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ' PC名がA列に入力されていると想定(2行目から)
    If lastRow < 2 Then Exit Sub
    pcList = ws.Range("A2:A" & lastRow).Value

    ' 結果格納用配列(PC名, OS, CPU, RAM)
    Dim results() As Variant
    ReDim results(1 To UBound(pcList, 1), 1 To 4)

    Dim i As Long
    Dim strComputer As String
    Dim objWMIService As Object
    Dim colItems As Object
    Dim objItem As Object

    ' 高速化設定
    Application.ScreenUpdating = False

    For i = 1 To UBound(pcList, 1)
        strComputer = pcList(i, 1)
        results(i, 1) = strComputer

        On Error Resume Next
        ' WMIサービスへの接続(参照設定不要のレイトバインディング)
        Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

        If Err.Number <> 0 Then
            results(i, 2) = "接続エラー: " & Err.Description
            Err.Clear
        Else
            ' OS情報の取得
            Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
            For Each objItem In colItems
                results(i, 2) = objItem.Caption & " (" & objItem.Version & ")"
                ' 総物理メモリ(KB)をGBに変換して取得
                results(i, 4) = Round(objItem.TotalVisibleMemorySize / 1024 / 1024, 1) & " GB"
            Next

            ' CPU情報の取得
            Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
            For Each objItem In colItems
                results(i, 3) = Trim(objItem.Name)
            Next
        End If
        On Error GoTo 0

        ' ネットワーク負荷軽減のための微小待機
        Sleep 50
    Next i

    ' 結果を一括出力(B列~E列)
    ws.Range("B2").Resize(UBound(results, 1), 4).Value = results

    Application.ScreenUpdating = True
    MsgBox "情報取得が完了しました。", vbInformation
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windowsの管理情報を取得するための共通基盤です。root\cimv2 ネームスペースには、ハードウェアやOSに関するクラスが網羅されています。

  2. レイトバインディング: CreateObject や GetObject を利用することで、特定のライブラリ参照設定(Microsoft WMI Scripting V1.2 Library等)を不要にし、他ユーザーへの配布時のトラブルを防止しています。

  3. 配列による一括処理: セルへの個別書き込みは低速なため、一度Variant配列に結果を格納し、最後にまとめてシートへ反映させることで処理速度を劇的に向上させています。

【注意点と運用】

  1. 権限設定: リモート接続を行うには、対象PCに対して管理者権限を持つアカウントで実行する必要があります。

  2. ファイアウォールの遮断: リモートWMI(RPC)が許可されていない環境では接続エラーとなります。グループポリシーでの設定確認が必要です。

  3. タイムアウトの考慮: 応答のないPCが含まれる場合、GetObject で処理が数秒停止します。台数が多い場合は、事前に Ping による生存確認を組み込むことを推奨します。

【まとめ】

  • WMIを活用することで、追加ソフトなしで詳細なスペック収集が可能。

  • 配列処理とScreenUpdating停止により、大量データでもストレスのない動作を実現。

  • 権限とネットワーク環境の事前確認が、安定運用の最大の鍵となる。

この記事の更新履歴

この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。

2026年9月21日

  • 削除冒頭に含まれていた未検証ドラフト表記とプロンプト指示用のプレースホルダーを削除しました。

文書情報

記事タイトル
VBA×WMI:リモートPCのシステム情報を一括取得する効率的アプローチ
作成日
更新日
Source URL
https://papanda925.com/?p=6874

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

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