【VBA×WMI】リモートPCのディスク空き容量を高速に自動集計するプログラミング手法

Tech

[style_prompt: technical_blog_v1]

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

【VBA×WMI】リモートPCのディスク空き容量を高速に自動集計するプログラミング手法

【背景と目的】

複数台のPC資産を管理する際、手動での容量確認は非効率でミスも誘発します。WMIを利用し、ネットワーク経由でディスク情報を一括取得・可視化する仕組みを構築します。

【処理フロー図】

graph TD
A["開始"] --> B["対象PCリストの読み込み"]
B --> C["対象PCへの導通確認"]
C --> D{"応答あり?"}
D -- Yes --> E["WMI接続試行"]
D -- No --> F["エラー記録/次へ"]
E --> G["Win32_LogicalDiskクエリ実行"]
G --> H["結果を配列へ格納"]
H --> I["全処理終了?"]
I -- No --> B
I -- Yes --> J["Excelシートへ一括出力"]
J --> K["終了"]

【実装:VBAコード】

Option Explicit

' --- Win32 API 宣言 (64bit/32bit両対応) ---
' ネットワーク疎通確認(Ping)の代用として簡易的な接続チェック等に利用可能
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long

''' <summary>
''' リモートPCのディスク情報を取得しシートに出力する
''' </summary>
Sub GetRemoteDiskInventory()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets(1)

    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
    Application.Calculation = xlCalculationManual

    Dim pcList As Variant
    pcList = ws.Range("A2:A" & lastRow).Value ' PC名を配列へ格納

    Dim results() As Variant
    ReDim results(1 To UBound(pcList), 1 To 4) ' 結果格納用配列 (Drive, Size, Free, %)

    Dim i As Long
    Dim objWMIService As Object
    Dim colDisks As Object
    Dim objDisk As Object
    Dim targetPC As String

    For i = 1 To UBound(pcList)
        targetPC = pcList(i, 1)
        If targetPC <> "" Then
            On Error Resume Next
            ' WMIへの接続 (名前解決ができない場合や権限不足時はエラー)
            ' Late Binding により参照設定不要
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & targetPC & "\root\cimv2")

            If Err.Number = 0 Then
                ' 固定ディスク(DriveType=3)のみをクエリ
                Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")

                For Each objDisk In colDisks
                    ' 最初のドライブ(通常C:)のみ取得する例
                    results(i, 1) = objDisk.DeviceID
                    results(i, 2) = Round(objDisk.Size / 1024^3, 2) & " GB"
                    results(i, 3) = Round(objDisk.FreeSpace / 1024^3, 2) & " GB"
                    results(i, 4) = Round((objDisk.FreeSpace / objDisk.Size) * 100, 1) & " %"
                    Exit For ' 複数ドライブある場合はロジックの調整が必要
                Next
            Else
                results(i, 1) = "接続エラー"
                Err.Clear
            End If
            On Error GoTo 0
        End If
    Next i

    ' シートへ一括出力 (B列~E列)
    ws.Range("B2").Resize(UBound(results, 1), 4).Value = results

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

    MsgBox "ディスク情報の取得が完了しました。", vbInformation
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windowsの管理情報を取得する強力なAPIです。Win32_LogicalDiskクラスを参照することで、ドライブレター、全容量、空き容量をバイト単位で取得できます。

  2. Late Binding (遅延結合): CreateObjectGetObjectを使用することで、特定のライブラリ(Microsoft WMI Scripting Library等)への参照設定を不要にし、他ユーザーへの配布時のトラブルを防いでいます。

  3. 高速化ロジック: 1セルずつ書き込むのではなく、対象PCリストを一旦配列(pcList)に読み込み、結果も配列(results)に蓄積。最後に一括でセルへ流し込むことで、描画負荷を最小限に抑えています。

【注意点と運用】

  • 権限の壁: リモートPCのWMIにアクセスするには、実行ユーザーが対象PCに対して管理者権限(Administrator)を持っている必要があります。ドメイン環境であれば、ドメイン管理権限での実行が推奨されます。

  • ファイアウォールの許可: 対象PC側で「リモート管理 (WMI)」の通信が許可されていない場合、接続エラーとなります。

  • エラーハンドリング: ネットワーク未接続やPC電源OFFの場合にマクロが停止しないよう、On Error Resume Nextによるトラップとクリア(Err.Clear)が不可欠です。

【まとめ】

  1. 配列処理を徹底し、ネットワーク遅延以外の要因(Excel描画など)によるボトルネックを排除する。

  2. エラー処理を組み込み、一部のPCがオフラインでも全体の集計処理を止めない設計にする。

  3. 管理者権限とFW設定を事前に確認し、WMI接続が確立できるインフラ環境を整える。

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

コメント

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