【VBA】WMIを活用してリモートPCのOS・CPU・メモリ情報を一括取得する自動化手法

Tech

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

【VBA】WMIを活用してリモートPCのOS・CPU・メモリ情報を一括取得する自動化手法

【背景と目的】

社内PCのスペック調査で手作業の確認が遅く、接続エラーも多発する課題をWMI自動取得で解決します。(52文字)

【処理フロー図】

graph TD
    A["開始: リストの読み込み"] --> B["WMI接続の試行"]
    B -->|成功| C["Win32クラスから情報取得"]
    B -->|失敗| D["エラー内容を記録"]
    C --> E["配列へデータ格納"]
    D --> E
    E --> F["全件処理完了?"]
    F -->|No| B
    F -->|Yes| G["シートへ一括書き出し"]
    G --> H["終了"]

【実装:VBAコード】

Option Explicit

' ==============================================================================
' 機能:WMIを使用して指定されたPC(ローカル/リモート)のシステム情報を一括取得する
' 特徴:遅延結合(参照設定不要)、二次元配列による高速転記処理
' ==============================================================================
Sub GetSystemInformationInfo()
    Dim ws As Worksheet
    Set ws = ActiveSheet

    ' 処理対象のPC名リストを取得(A2セル以降にPC名またはIPアドレスが入力されている想定)
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    If lastRow < 2 Then
        MsgBox "対象となるPC名がA列に入力されていません。", vbExclamation
        Exit Sub
    End If

    ' 高速化設定:画面描画と自動計算を停止
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ' 結果格納用の動的配列を定義 (行: PC数, 列: 取得項目数)
    Dim totalPCs As Long
    totalPCs = lastRow - 1

    Dim resultData() As Variant
    ReDim resultData(1 To totalPCs, 1 To 5)

    Dim i As Long
    Dim computerName As String

    ' ループ処理で各PCの情報を取得
    For i = 1 To totalPCs
        computerName = Trim(CStr(ws.Cells(i + 1, 1).Value))

        If computerName <> "" Then
            ' システム情報の取得を実行
            Call FetchWMIData(computerName, resultData, i)
        Else
            resultData(i, 1) = "未入力"
        End If
    Next i

    ' 取得したデータをシートへ一括出力(B2セルから展開)
    ws.Range(ws.Cells(2, 2), ws.Cells(lastRow, 6)).Value = resultData

    ' 高速化設定の解除
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True

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

' ------------------------------------------------------------------------------
' Sub関数: WMIへ接続し情報を取り出す処理
' ------------------------------------------------------------------------------
Private Sub FetchWMIData(ByVal pcName As String, ByRef dataArray() As Variant, ByVal index As Long)
    On Error GoTo ErrorHandler

    ' WMIサービスオブジェクトの生成(遅延結合)
    Dim objWMIService As Object
    Set objWMIService = GetObject("winmgmts:\\" & pcName & "\root\cimv2")

    ' 1. OS情報の取得 (Win32_OperatingSystem)
    Dim colOS As Object
    Set colOS = objWMIService.ExecQuery("SELECT Caption, Version FROM Win32_OperatingSystem")

    Dim objOS As Object
    For Each objOS In colOS
        dataArray(index, 1) = objOS.Caption ' OS名
        dataArray(index, 2) = objOS.Version ' バージョン
        Exit For
    Next objOS

    ' 2. CPU情報の取得 (Win32_Processor)
    Dim colCPU As Object
    Set colCPU = objWMIService.ExecQuery("SELECT Name FROM Win32_Processor")

    Dim objCPU As Object
    For Each objCPU In colCPU
        dataArray(index, 3) = Trim(objCPU.Name) ' CPU名称
        Exit For
    Next objCPU

    ' 3. メモリ容量の取得 (Win32_ComputerSystem) - GB単位に変換
    Dim colSys As Object
    Set colSys = objWMIService.ExecQuery("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem")

    Dim objSys As Object
    For Each objSys In colSys
        If Not IsNull(objSys.TotalPhysicalMemory) Then
            ' バイトをGB(1024^3)に換算して四捨五入
            dataArray(index, 4) = Round(CDbl(objSys.TotalPhysicalMemory) / (1024 ^ 3), 1) & " GB"
        Else
            dataArray(index, 4) = "不明"
        End If
        Exit For
    Next objSys

    ' 状態フラグ
    dataArray(index, 5) = "成功"

    ' オブジェクトの解放
    Set objWMIService = Nothing
    Exit Sub

ErrorHandler:
    ' 接続エラーやアクセス拒否が発生した場合の例外処理
    dataArray(index, 1) = "-"
    dataArray(index, 2) = "-"
    dataArray(index, 3) = "-"
    dataArray(index, 4) = "-"
    dataArray(index, 5) = "エラー: " & Err.Description

    Err.Clear
End Sub

【技術解説】

  1. 遅延結合(Late Binding)の採用 GetObject("winmgmts:...") を利用することで、WMI関連の外部ライブラリ(WMI Scripting Library)への参照設定が不要になり、配布時の環境依存エラーを防止できます。

  2. 使用しているWMIクラス

    • Win32_OperatingSystem: OSの正式名称やビルドバージョンの取得。

    • Win32_Processor: 搭載されているCPUの型番取得。

    • Win32_ComputerSystem: 実装されている物理メモリ総量の取得。

  3. 配列処理による描画オーバーヘッドの削減 セルへの1行ずつの書き込みを行わず、二次元配列 resultData に全件格納してから一括代入(Range.Value = Array)することで、大量のPCを処理する際の大幅な速度向上を実現しています。

【注意点と運用】

  • ネットワーク・認証エラー(RPCサーバー不可) リモートPCへWMI接続を行う場合、対象端末で「WMIの受信許可」および「RPC(Remote Procedure Call)サービス」が有効である必要があります。また、ドメイン管理者権限等でVBAを実行しない場合、アクセス拒否エラーが発生します。

  • 応答停止(フリーズ)の回避 電源が入っていないPCやネットワーク不通のPCを指定すると、WMI接続のタイムアウトにより数秒~数十秒処理が停止します。事前に Ping コマンド等による疎通確認ステップを組み込むことが実務上の落とし穴回避策となります。

【まとめ】

  • WMIを利用すれば、外部ライブラリ不要でリモートPCのシステム情報を自動集約できる。

  • セルへの直接書き込みを避け、二次元配列への一時保持と一括出力で高速化を図る。

  • リモート取得時は管理者権限とファイアウォール設定の事前確認が運用の鍵となる。

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

コメント

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