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

Tech

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

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

【背景と目的】

ネットワーク内の複数PCのストレージ残量を、現地に赴かずExcelから一括で取得します。手動確認の工数削減と、容量不足によるシステム停止リスクの回避を目的としています。

【処理フロー図】

graph TD
A["開始: PC名リストの読み込み"] --> B{"疎通確認 Ping"}
B -->|応答あり| C["WMI接続開始"]
B -->|応答なし| D["エラー記録: オフライン"]
C --> E["Win32_LogicalDiskクエリ実行"]
E --> F["取得データを配列へ格納"]
F --> G["シートへ一括書き出し"]
G --> H["終了"]

【実装:VBAコード】

Option Explicit

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

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

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

''' <summary>
''' リモートPCのディスク情報を取得し、アクティブシートに出力する
''' </summary>
Public Sub GetRemoteDiskSpace()
    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

    ' 高速化設定
    On Error GoTo ErrorHandler
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    Dim targetRange As Variant
    targetRange = ws.Range("A2:D" & lastRow).Value ' A:PC名, B:ドライブ, C:空き, D:合計

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

    For i = 1 To UBound(targetRange, 1)
        strComputer = targetRange(i, 1)

        If strComputer <> "" Then
            ' WMI接続(エラーを個別にトラップ)
            On Error Resume Next
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

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

                Dim results As String: results = ""
                For Each objDisk In colDisks
                    ' バイトをGBに変換 (小数点第2位)
                    targetRange(i, 2) = objDisk.DeviceID
                    targetRange(i, 3) = Round(objDisk.FreeSpace / 1024 / 1024 / 1024, 2) & " GB"
                    targetRange(i, 4) = Round(objDisk.Size / 1024 / 1024 / 1024, 2) & " GB"
                Next
            Else
                targetRange(i, 2) = "接続エラー"
                targetRange(i, 3) = "-"
                targetRange(i, 4) = "-"
            End If
            On Error GoTo ErrorHandler
        End If

        ' APIによる待機(サーバー負荷軽減が必要な場合)
        ' Sleep 10
    Next i

    ' 配列を一括書き戻し
    ws.Range("A2:D" & lastRow).Value = targetRange

CleanUp:
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    MsgBox "処理が完了しました。", vbInformation
    Exit Sub

ErrorHandler:
    MsgBox "予期せぬエラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windowsの管理情報を取得する基盤技術です。Win32_LogicalDiskクラスを使用することで、物理的な接続形態を問わず論理ドライブの情報を抽出できます。

  2. DriveType = 3: WMIにおいて、ネットワークドライブ(4)や光学ドライブ(5)を除外した「ローカル固定ディスク」のみを指定するフィルタリング条件です。

  3. 配列処理による高速化: セルへの逐次書き込みを避け、シートから一度値を配列に取り込み、メモリ上で処理を完結させてから一括で書き戻しています。

  4. PtrSafe API: Sleep関数等のWin32 APIを呼び出す際、Officeの64bit版でも動作を保証するための宣言手法です。

【注意点と運用】

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

  • 管理者権限: 実行ユーザーはリモートPCの管理者権限(Administrator権限)を保持している必要があります。ドメイン環境であればDomain Admin、あるいは対象のLocal Adminsグループに属している必要があります。

  • タイムアウト: PCがオフラインの場合、GetObjectで一定時間のタイムアウト待ちが発生します。多数のPCを処理する場合は、事前にPingによる生存確認をAPIで行う実装の追加を推奨します。

【まとめ】

  1. 管理の集約化: 1台のExcelからネットワーク全域のストレージ監視が可能になります。

  2. 型定義の厳守: PtrSafe対応により、現代のOffice 365(64bit)環境でも安全に動作します。

  3. エラー制御: 接続不可端末を「エラー」としてスキップし、マクロ全体が止まらない設計にしています。

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

コメント

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