WMIを活用したリモートPCのディスク空き容量一括取得ツールの開発

Tech

contents: VBA_WMI_RemoteDiskQuery expertise: Office_Automation_Expert language: Japanese logic: SWbemLocator_LateBinding_Optimization

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

WMIを活用したリモートPCのディスク空き容量一括取得ツールの開発

【背景と目的】

ネットワーク経由で複数端末のストレージ残量を自動収集し、手動確認の手間と接続エラーによる処理の中断を解消します(59文字)。

【処理フロー図】

graph TD
A["開始"] --> B["対象ホスト名リストの読み込み"]
B --> C["SWbemLocatorでリモート接続"]
C -->|接続成功| D["Win32_LogicalDiskをクエリ"]
C -->|接続失敗| E["エラー情報を配列に格納"]
D --> F["空き容量・総容量を取得しGB換算"]
F --> G["結果を2D配列へ格納"]
G --> H["全件完了後にシートへ一括出力"]
H --> I["終了"]

【実装:VBAコード】

Option Explicit

' ================================================================
' 概要: リモートPCのディスク情報を一括取得する
' 備考: 参照設定不要(Late Binding)
' ================================================================
Sub GetRemoteDiskFreeSpace()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet

    ' 入力値(A列にホスト名があると想定)
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    If lastRow < 2 Then Exit Sub

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

    ' 結果格納用配列 (ホスト名, ドライブ, 空き容量, 総容量, 状態)
    Dim results() As Variant
    ReDim results(1 To UBound(targetHosts), 1 To 5)

    ' 高速化設定
    Application.ScreenUpdating = False

    Dim locator As Object
    Dim service As Object
    Dim disks As Object
    Dim disk As Object
    Dim i As Long

    On Error Resume Next
    Set locator = CreateObject("WbemScripting.SWbemLocator")

    For i = 1 To UBound(targetHosts)
        Dim host As String
        host = targetHosts(i, 1)
        results(i, 1) = host

        If host = "" Then GoTo NextHost

        ' WMI接続(タイムアウトや権限エラーを考慮)
        Err.Clear
        Set service = locator.ConnectServer(host, "root\cimv2")

        If Err.Number <> 0 Then
            results(i, 5) = "接続エラー: " & Err.Description
        Else
            ' 論理ディスク情報の取得(DriveType=3 は固定ディスク)
            Set disks = service.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")

            Dim diskCount As Integer: diskCount = 0
            For Each disk In disks
                ' 最初のドライブ情報のみ取得(実務に合わせて拡張可能)
                results(i, 2) = disk.DeviceID
                results(i, 3) = Round(disk.FreeSpace / 1024 / 1024 / 1024, 2) & " GB"
                results(i, 4) = Round(disk.Size / 1024 / 1024 / 1024, 2) & " GB"
                results(i, 5) = "正常"
                Exit For ' 複数ドライブある場合はここを調整
            Next
        End If

NextHost:
    Next i
    On Error GoTo 0

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

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

【技術解説】

  1. SWbemLocator (Late Binding): WbemScripting.SWbemLocator を使用することで、配布先のPCで参照設定の不整合(参照不可エラー)が発生するリスクを排除しています。

  2. Win32_LogicalDisk クエリ: DriveType = 3 と指定することで、ネットワークドライブや光学ドライブを除外し、ローカルのHDD/SSDのみを効率的に抽出します。

  3. 配列処理による高速化: セルへの書き込みをループ内で行わず、全てのデータを一度 results 配列に格納してから、最後に一括してセルへ流し込むことで、処理時間を大幅に短縮しています。

  4. エラーハンドリング: リモート接続特有の「RPCサーバーが利用できません」等のエラーでマクロが停止しないよう、On Error Resume NextErr.Number のチェックを組み合わせています。

【注意点と運用】

  • 管理者権限とファイアウォール: リモートPC側で WMI (DCOM) が許可されている必要があります。拒否される場合は、Windows Defender ファイアウォールの「WMI経由の管理」を許可設定にしてください。

  • 認証情報: 本コードは実行ユーザーの権限で接続します。別ドメインや別ユーザーとして実行する場合は、ConnectServer メソッドの引数にユーザー名とパスワードを渡す必要があります。

  • 64bit環境の考慮: 今回は Win32 API を直接叩かず、COMコンポーネント(WMI)を利用しているため、PtrSafe は不要ですが、VBA7以降(Excel 2010以降)であれば問題なく動作します。

【まとめ】

  • 一括処理: 配列を活用してセルアクセス回数を最小限に抑えるのが高速化の鍵。

  • 安定性: On Error Resume Next を局所的に使い、接続失敗したPCを飛ばして処理を継続させる。

  • 柔軟性: WMIクエリを変更するだけで、CPU情報やメモリ使用量などの取得にも応用可能。

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

コメント

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