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

Tech

  • 専門用語を適切に用い、論理的で簡潔なビジネス文章を作成する。

  • 読者の実務レベル(中級者以上)に合わせ、技術的な背景と具体的なコード実装をセットで提示。

  • 安全性と保守性を重視し、エラーハンドリングや最新のOffice環境(64bit)への配慮を欠かさない。

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

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

【背景と目的】

IT資産管理での手動確認は非効率です。VBAとWMIを用いてネットワーク経由で複数台のスペック情報を自動取得し、管理業務を高速化する手法を解説します。

【処理フロー図】

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

''' <summary>
''' 指定したPC名のリストからシステム情報を取得し、アクティブシートに出力する
''' </summary>
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. レイトバインディング: CreateObjectGetObject を利用することで、特定のライブラリ参照設定(Microsoft WMI Scripting V1.2 Library等)を不要にし、他ユーザーへの配布時のトラブルを防止しています。

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

【注意点と運用】

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

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

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

【まとめ】

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

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

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

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

コメント

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