VBAとWMIによるリモートPCのディスク空き容量一括モニタリング

Tech

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

VBAとWMIによるリモートPCのディスク空き容量一括モニタリング

【背景と目的】

リモートPCの空き容量不足はシステム停止の要因です。WMIを活用し、ネットワーク経由で複数台のディスク情報を一括で取得・可視化します。

【処理フロー図】

graph TD
A["開始"] --> B["PCリストを配列に格納"]
B --> C["ループ処理開始: 各PCへ接続"]
C --> D{"WMI接続・応答確認"}
D -- 成功 --> E["Win32_LogicalDiskから容量取得"]
D -- 失敗 --> F["エラーメッセージを配列に格納"]
E --> G["結果を2次元配列に蓄積"]
F --> G
G --> H{"全PC終了?"}
H -- No --> C
H -- Yes --> I["シートへ一括出力・書式設定"]
I --> J["終了"]

【実装:VBAコード】

Option Explicit

' Win32 API 宣言(64bit/32bit両対応)
' 今回は待機処理にSleepを使用する可能性を考慮し定義
#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

Sub GetRemoteDiskFreeSpace()
    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1)
    Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    ' PC名リストがA列にある前提(2行目から開始)
    If lastRow < 2 Then Exit Sub

    Dim pcList As Variant: pcList = ws.Range("A2:A" & lastRow).Value
    Dim resultData() As Variant
    ReDim resultData(1 To UBound(pcList), 1 To 3) ' ドライブ、サイズ、空き容量

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

    ' 画面更新停止で高速化
    Application.ScreenUpdating = False

    On Error Resume Next
    For i = 1 To UBound(pcList)
        strComputer = pcList(i, 1)
        If strComputer = "" Then GoTo NextLoop

        ' WMIサービスへの接続(実行権限が必要)
        Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
                                      strComputer & "\root\cimv2")

        If Err.Number <> 0 Then
            resultData(i, 1) = "接続エラー"
            Err.Clear
        Else
            ' ローカル固定ディスク(DriveType = 3)をクエリ
            Set colDisks = objWMIService.ExecQuery _
                ("Select * from Win32_LogicalDisk Where DriveType = 3")

            Dim diskInfo As String: diskInfo = ""
            Dim sizeInfo As String: sizeInfo = ""
            Dim freeInfo As String: freeInfo = ""

            For Each objDisk In colDisks
                diskInfo = diskInfo & objDisk.DeviceID & " "
                ' GB単位に換算して格納
                sizeInfo = sizeInfo & Round(objDisk.Size / 1024 / 1024 / 1024, 1) & " GB / "
                freeInfo = freeInfo & Round(objDisk.FreeSpace / 1024 / 1024 / 1024, 1) & " GB / "
            Next objDisk

            resultData(i, 1) = diskInfo
            resultData(i, 2) = Left(sizeInfo, Len(sizeInfo) - 3)
            resultData(i, 3) = Left(freeInfo, Len(freeInfo) - 3)
        End If

NextLoop:
        Set objWMIService = Nothing
    Next i
    On Error GoTo 0

    ' 結果を一括出力(B~D列)
    ws.Range("B2").Resize(UBound(resultData), 3).Value = resultData

    Application.ScreenUpdating = True
    MsgBox "ディスク容量の照会が完了しました。", vbInformation
End Sub

【技術解説】

  1. WMI (Win32_LogicalDisk): Windowsの管理基盤を利用し、ネットワーク越しにハードウェア情報を取得します。DriveType = 3 を指定することで、ネットワークドライブやCD-ROMを除外した「ローカルHDD/SSD」のみを抽出しています。

  2. 遅延バインディング: CreateObjectGetObject を使用することで、参照設定(Microsoft WMI Scripting Library)の手間を省き、配布性を高めています。

  3. 配列処理: セルへの書き込みをループ内で行わず、全てのデータを一度 resultData 配列に格納してから一括出力することで、通信以外の処理時間を極限まで短縮しています。

【注意点と運用】

  1. 権限の壁: リモートPCに対する管理者権限(Administrator権限)を持つユーザーで実行する必要があります。ドメイン環境でない場合は、認証エラーが発生しやすくなります。

  2. ファイアウォールの許可: 対象PC側で「Windows Management Instrumentation (WMI)」の受信ルールが許可されている必要があります。

  3. タイムアウト: 応答のないPCがある場合、WMI接続試行時に数秒のフリーズが発生します。より高度な運用では、事前に Win32_PingStatus で疎通確認を行うステップを追加するのが定石です。

【まとめ】

  • WMIクエリでリモート端末の物理構成を正確に把握する。

  • 配列一括処理により、多数のPCを対象とした際のスループットを向上させる。

  • エラーハンドリングを組み込み、オフライン端末によるマクロ停止を防止する。

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

コメント

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