VBA×WMIによるリモートPC資産管理:OS・CPU・メモリ情報の自動取得の実践

Tech

【執筆作法】

  1. 専門用語を平易な語彙で補足し、技術的解像度と読みやすさを両立させる。

  2. 「なぜそのコードが必要か」という設計意図(Design Intent)を明文化する。

  3. リスク管理(例外処理)を実装レベルで提案する。

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

VBA×WMIによるリモートPC資産管理:OS・CPU・メモリ情報の自動取得の実践

【背景と目的】

IT資産管理において、数百台の端末情報を手動で確認するのは非効率です。本ツールは、WMIを用いてリモートPCのスペック情報を一括収集し、管理工数を削減します。 実務では「リモート接続時のタイムアウトによるフリーズ」や「権限不足による実行エラー」が大きな壁となりますが、本ガイドではエラーハンドリングを組み込んだ堅牢なコードを提示します。

【処理フロー図】

graph TD
A["開始"] --> B["対象ホスト名/IPの読み込み"]
B --> C["SWbemLocatorによるリモート接続試行"]
C -->|成功| D["WMIクエリ実行: OS/CPU/Memory"]
C -->|失敗| E["エラー内容をシートへ記録"]
D --> F["取得データを配列へ格納"]
F --> G["シートへ一括書き出し"]
G --> H["終了"]

【実装:VBAコード】

参照設定(Microsoft WMI Scripting v1.2 Library)を不要にする「実行時バインド(Late Binding)」方式を採用しています。

Option Explicit

' Win32 API宣言(64bit/32bit両対応)
#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.Sheets(1)

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    ' 高速化設定
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
    End With

    Dim i As Long
    Dim targetPC As String
    Dim objWMIService As Object
    Dim colItems As Object
    Dim objItem As Object
    Dim results() As Variant
    ReDim results(1 To 1, 1 To 4) ' OS, CPU, RAM, Status

    ' A列にホスト名が入っている想定(2行目から開始)
    For i = 2 To lastRow
        targetPC = ws.Cells(i, 1).Value
        On Error Resume Next

        ' WMI接続オブジェクトの作成
        ' タイムアウト対策として、接続試行前にPing確認を行うのが理想的(今回はWMI接続で判定)
        Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & targetPC & "\root\cimv2")

        If Err.Number <> 0 Then
            ws.Cells(i, 5).Value = "Error: " & Err.Description
            Err.Clear
        Else
            ' 1. OS情報の取得
            Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
            For Each objItem In colItems
                results(1, 1) = objItem.Caption & " (" & objItem.OSArchitecture & ")"
                results(1, 3) = Round(objItem.TotalVisibleMemorySize / 1024 / 1024, 1) & " GB"
            Next

            ' 2. CPU情報の取得
            Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
            For Each objItem In colItems
                results(1, 2) = Trim(objItem.Name)
            Next

            results(1, 4) = "Success"

            ' 配列からシートへ一括書き出し(セルへの個別アクセスを低減)
            ws.Cells(i, 2).Resize(1, 4).Value = results
        End If

        ' オブジェクトの解放
        Set objWMIService = Nothing
        Set colItems = Nothing
        DoEvents ' OSに制御を戻しフリーズを防止
    Next i

    ' 設定の復元
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
    End With

    MsgBox "システム情報の取得が完了しました。", vbInformation
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windowsの管理情報を取得するための標準インターフェースです。root\cimv2 名前空間には、ハードウェアに関するほぼすべてのクラス(Win32_Processor等)が含まれています。

  2. 実行時バインド (Late Binding): CreateObjectGetObject を使用することで、配布先PCでの「参照設定エラー」を回避します。

  3. 配列処理による高速化: 1セルずつ書き込むのではなく、Resize プロパティを用いて配列を一度に流し込むことで、Excelの描画回数を最小限に抑えています。

  4. PtrSafe 宣言: 64bit版OfficeではAPI宣言に PtrSafe が必須です。これを怠ると実行時エラーでVBAが停止します。

【注意点と運用】

  • ファイアウォールの許可: リモートPC側で「WMI (RPC)」の通信が許可されている必要があります。企業環境ではグループポリシー(GPO)での設定確認が必須です。

  • 実行権限: リモートPCに対して管理者権限を持つユーザーでExcelを実行する必要があります。

  • タイムアウトの罠: 存在しないPCや電源オフのPCに対して GetObject を行うと、数秒〜数十秒の応答待ち(ハングアップ状態)が発生します。事前に WMI 接続前に Ping による死活監視を挟む設計がより実用的です。

【まとめ】

  1. WMIは標準機能のみで動作するため、追加インストールの必要がない強力な資産管理ツールになる。

  2. エラーハンドリングとDoEventsを組み合わせることで、大量のリスト処理でもExcelをクラッシュさせずに実行できる。

  3. ネットワーク環境(権限・FW)の事前確認が、コードそのものよりも重要になる。

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

コメント

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