VBAとWMIで実現するリモートPC情報の一括取得:OS・CPU・メモリの自動集計ガイド

Tech

  • 専門用語を適切に使いつつ、論理的で簡潔な文章を心がける。

  • ユーザーの目的(実務解決)を最短で達成するコードと解説を提供する。

  • 指示された構成順序、バッジ、メタデータを厳守する。

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

VBAとWMIで実現するリモートPC情報の一括取得:OS・CPU・メモリの自動集計ガイド

【背景と目的】

リモートPCのOS・CPU・メモリ情報をWMIで一括取得します。手作業による転記ミスや確認時間を削減し、ネットワーク経由での効率的な資産管理を実現します。

【処理フロー図】

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

【実装:VBAコード】

Option Explicit

' Win32 APIの宣言(64bit/32bit両対応)
#If VBA7 Then

    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else

    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

''' <summary>
''' リモートPCのシステム情報を取得し、アクティブシートに展開する
''' </summary>
Public Sub GetRemoteSystemInfo()
    Dim ws As Worksheet
    Set ws = ActiveSheet

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

    If lastRow < 2 Then
        MsgBox "A列にPC名を入力してください。", vbExclamation
        Exit Sub
    End If

    ' 高速化設定
    Application.ScreenUpdating = False

    Dim pcList() As Variant
    pcList = ws.Range("A2:A" & lastRow).Value

    Dim results() As Variant
    ReDim results(1 To UBound(pcList, 1), 1 To 4) ' OS, CPU, RAM, Status

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

    For i = 1 To UBound(pcList, 1)
        targetPC = pcList(i, 1)
        If targetPC <> "" Then
            On Error Resume Next
            ' WMI接続(タイムアウトを考慮し接続を試行)
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & targetPC & "\root\cimv2")

            If Err.Number <> 0 Then
                results(i, 4) = "接続失敗: " & Err.Description
                Err.Clear
            Else
                ' OS情報の取得
                Set colItems = objWMIService.ExecQuery("Select Caption FROM Win32_OperatingSystem")
                For Each objItem In colItems
                    results(i, 1) = objItem.Caption
                Next

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

                ' メモリ情報の取得(バイトからGBに変換)
                Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory FROM Win32_ComputerSystem")
                For Each objItem In colItems
                    results(i, 3) = Round(objItem.TotalPhysicalMemory / (1024 ^ 3), 2) & " GB"
                Next

                results(i, 4) = "成功"
            End If
            On Error GoTo 0
        End If
        ' ネットワーク負荷軽減のための待機
        Sleep 10
    Next i

    ' 結果を一括書き出し
    ws.Range("B2").Resize(UBound(results, 1), 4).Value = results

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

【技術解説】

  1. WMI (Windows Management Instrumentation): Windows OSを管理するためのインターフェースです。winmgmtsを使用することで、リモートPCのハードウェアやOS情報をSQLライクなクエリ(WQL)で取得できます。

  2. Late Binding (後方参照): CreateObjectGetObjectを使用することで、特定のライブラリ参照設定(Microsoft WMI Scripting Library等)を不要にし、配布時の互換性を高めています。

  3. 配列処理: セルへの書き込みを1回ずつ行うのではなく、一度配列(results)に格納してからシートへ一括出力することで、処理速度を劇的に向上させています。

  4. PtrSafe API: Sleep関数を使用する際、64bit環境でも動作するようにPtrSafeキーワードを使用しています。

【注意点と運用】

  1. ファイアウォールの許可: リモートPC側で「リモート管理(WMI-In)」の受信規則が許可されている必要があります。

  2. 実行権限: 実行ユーザーには、ターゲットPCに対する管理者権限(Administrator権限)が必要です。ドメイン環境ではドメイン管理者が推奨されます。

  3. エラーハンドリング: ネットワーク断絶やPCがシャットダウンしている場合、GetObjectでエラーが発生します。On Error Resume Nextで処理をスキップさせつつ、ステータス列にエラー内容を記録するように設計しています。

【まとめ】

  • 一括取得: WMIクエリにより、OS名・CPU名・物理メモリ容量をネットワーク越しに取得可能。

  • 高速化: 配列へのデータ格納と一括書き出しにより、多数のPCも短時間で処理。

  • 保守性: Win32 APIの64bit対応と外部ライブラリ参照の回避により、環境を選ばず運用可能。

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

コメント

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