VBA×WMI:リモートPCのシステム構成情報を一括取得する自動化ツール

Tech

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

VBA×WMI:リモートPCのシステム構成情報を一括取得する自動化ツール

【背景と目的】

IT資産管理において、複数台のリモートPCのスペックを手動で確認するのは非効率です。本ツールはWMIを活用し、ネットワーク経由でOS・CPU・メモリ情報を迅速に自動取得します。

【処理フロー図】

graph TD
A["開始"] --> B["対象PC名/IPリストの読み込み"]
B --> C["SWbemLocatorでリモート接続を確立"]
C --> D["Win32_OperatingSystemよりOS取得"]
D --> E["Win32_ProcessorよりCPU取得"]
E --> F["Win32_PhysicalMemoryよりメモリ容量算出"]
F --> G["Excelシートへ結果を書き込み"]
G --> H["次のPCへループ/終了"]

【実装:VBAコード】

Option Explicit

' Win32 API 宣言 (64bit/32bit両対応)
' 今回はPC名の取得にAPIを使用
Private Declare PtrSafe Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" ( _
    ByVal lpBuffer As String, _
    ByRef nSize As Long) As Long

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

    Dim targetPC As String
    Dim lastRow As Long
    Dim i As Long

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

    ' B列にPC名が入っている想定 (B5から開始)
    lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row

    ' ヘッダーの作成
    ws.Range("C4:F4").Value = Array("ステータス", "OS名称", "CPUモデル", "メモリ容量(GB)")

    Dim locator As Object
    Dim service As Object
    Dim items As Object
    Dim item As Object
    Dim memSum As Double

    ' WMIロケーターの生成(レイトバインドで参照設定不要)
    Set locator = CreateObject("WbemScripting.SWbemLocator")

    For i = 5 To lastRow
        targetPC = Trim(ws.Cells(i, "B").Value)
        If targetPC <> "" Then
            On Error Resume Next
            ' リモートPCへの接続試行 (現在の認証情報を使用)
            ' 第2引数以降にユーザー名/パスワードを指定することも可能
            Set service = locator.ConnectServer(targetPC, "root\cimv2")

            If Err.Number <> 0 Then
                ws.Cells(i, "C").Value = "接続失敗: " & Err.Description
                Err.Clear
            Else
                ws.Cells(i, "C").Value = "成功"

                ' 1. OS情報の取得
                Set items = service.ExecQuery("Select Caption From Win32_OperatingSystem")
                For Each item In items
                    ws.Cells(i, "D").Value = item.Caption
                Next

                ' 2. CPU情報の取得
                Set items = service.ExecQuery("Select Name From Win32_Processor")
                For Each item In items
                    ws.Cells(i, "E").Value = item.Name
                Next

                ' 3. メモリ情報の取得 (Win32_PhysicalMemoryの合計)
                Set items = service.ExecQuery("Select Capacity From Win32_PhysicalMemory")
                memSum = 0
                For Each item In items
                    memSum = memSum + CDbl(item.Capacity)
                Next
                ' バイトをGBに変換 (1024^3)
                ws.Cells(i, "F").Value = Round(memSum / 1073741824, 1)

            End If
            On Error GoTo 0
        End If
    Next i

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

    MsgBox "情報取得が完了しました。", vbInformation
End Sub

【技術解説】

  1. SWbemLocator (WMI): CreateObject("WbemScripting.SWbemLocator") を使用することで、ライブラリの参照設定(Microsoft WMI Scripting Library)を行わずに実行可能です。これにより、配布時の環境依存エラーを防ぎます。

  2. SQLライクなクエリ: ExecQuery を使用して、必要なクラス(Win32_OperatingSystem等)から情報を抽出します。これは大規模なデータベース操作と同様の効率性を持ちます。

  3. PtrSafe: Win32 API(例:GetComputerName)を使用する際は、VBA7以降の64bit環境でも安全に動作するよう PtrSafe を付与し、メモリポインタの整合性を保っています。

【注意点と運用】

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

  • 管理者権限: リモート接続を実行するユーザーは、対象PCに対して管理者権限を持っている必要があります。ドメイン環境での実行を推奨します。

  • タイムアウト: オフラインのPCが含まれる場合、ConnectServer で待機時間が発生します。リストが多い場合は、事前に Ping 等で生存確認を行うロジックを追加するとより高速です。

【まとめ】

  1. 標準機能で完結: 外部ライブラリを使わず、WMIとVBA標準機能のみで高度な情報取得が可能です。

  2. メンテナンス性: レイトバインドの採用により、Excelのバージョンや環境を選ばず動作します。

  3. 拡張性: Win32_DiskDriveWin32_NetworkAdapter を追加することで、ディスク容量やMACアドレスの取得も容易に拡張できます。

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

コメント

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