VBA×WMIによるリモートPC情報の一括取得:IT資産管理の自動化ガイド

Tech

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

VBA×WMIによるリモートPC情報の一括取得:IT資産管理の自動化ガイド

【背景と目的】

IT資産管理の自動化を目的とし、遠隔地のPCにログインすることなくOS・CPU・メモリ情報を一括取得してExcelへ集計する手法を解説します。 手動確認による工数増大や、リモートデスクトップ接続が制限された環境での情報収集の遅延という課題を、WMI(Windows Management Instrumentation)を活用して解決します。

【処理フロー図】

graph TD
A["開始:PCリストの読込"] --> B["WMIロケーター接続試行"]
B -->|成功| C["OS/CPU/メモリ情報をクエリ"]
B -->|失敗| D["エラー内容をシートへ記録"]
C --> E["取得データを配列へ格納"]
E --> F["Excelシートへ一括書き出し"]
F --> G["終了"]

【実装:VBAコード】

参照設定を不要にするため「レイトバインディング」を採用しています。また、処理速度向上のため画面更新抑制と配列処理を組み込んでいます。

Option Explicit

' Win32 API宣言(実行速度計測用:64bit環境対応)
#If VBA7 Then

    Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else

    Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If

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 Exit Sub

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

    Dim startTime As Long
    startTime = GetTickCount()

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

    ' 外部ライブラリを使用しないWMI接続用オブジェクト
    Dim objLocator As Object
    Set objLocator = CreateObject("WbemScripting.SWbemLocator")

    For i = 2 To lastRow
        targetHost = ws.Cells(i, 1).Value
        On Error Resume Next
        ' リモートPCへの接続(タイムアウト時はエラー)
        ' 第3引数, 第4引数にID/Passを指定可能だが、通常はドメイン権限で実行
        Set objWMIService = objLocator.ConnectServer(targetHost, "root\cimv2")

        If Err.Number <> 0 Then
            results(i - 1, 4) = "接続エラー: " & Err.Description
            Err.Clear
        Else
            ' OS情報の取得
            Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
            For Each objItem In colItems
                results(i - 1, 1) = objItem.Caption
                results(i - 1, 3) = Round(objItem.TotalVisibleMemorySize / 1024 / 1024, 1) & " GB"
            Next

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

            results(i - 1, 4) = "取得完了"
        End If
        On Error GoTo 0

        Set objWMIService = Nothing
    Next i

    ' 結果を一括出力
    ws.Range("B2").Resize(UBound(results, 1), UBound(results, 2)).Value = results

    ' 設定戻し
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
    End With

    MsgBox "処理完了。実行時間: " & (GetTickCount() - startTime) / 1000 & "秒"
End Sub

【技術解説】

  1. WMI (SWbemLocator): ConnectServer メソッドを使用することで、ネットワーク経由で対象PCの管理情報データベースにアクセスします。SQLライクな WQL を用いて、必要なプロパティ(Caption, Name等)のみを抽出しています。

  2. 配列書き出しの高速化: セルへの書き込みをループ内で行わず、一度 results 配列に格納してから Resize メソッドで一括出力することで、通信以外のオーバーヘッドを最小化しています。

  3. 環境互換性: PtrSafe を用いたAPI宣言により、32bit/64bit双方のExcel環境で動作を保証しています。

【注意点と運用】

  • 管理者権限の必須: 実行ユーザーは対象リモートPCに対して管理者権限(Domain Admin等)を持っている必要があります。

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

  • タイムアウトの発生: 存在しないホストや電源オフのPCに対しては、接続試行時に数十秒の待機が発生します。リストが多い場合は事前に Ping による生存確認を挟むロジックが有効です。

【まとめ】

  1. WMIはレイトバインディングで記述し、参照設定トラブルを回避する。

  2. エラーハンドリングを徹底し、1台のオフラインPCでマクロ全体を止めない。

  3. 結果は配列に格納し、最後にシートへ一括出力して実行速度を確保する。

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

コメント

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