VBAとWMIで実現するリモートPCのディスク空き容量一括照会

Tech

【執筆作法】

  • 専門性と親しみやすさを両立したテックブログスタイル。

  • 結論から書き、次に詳細、最後に運用のコツを配置する。

  • 視覚的理解を助けるため、Mermaid図解と構造化された見出しを多用する。

  • ソースコードは「コピー&ペーストで動作する」レベルの品質を維持する。

  • リスク管理(例外処理)を必ず言及する。 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

VBAとWMIで実現するリモートPCのディスク空き容量一括照会

【背景と目的】

多数のPCの空き容量を確認する際、手動ログインは非効率で時間もかかります。本ツールはWMIを利用し、ネットワーク越しに容量を自動取得して業務を効率化します。

【処理フロー図】

graph TD
A["開始"] --> B["PC名リストを取得"]
B --> C{"PCに接続可能か?"}
C -->|Yes| D["WMIでディスク情報を照会"]
C -->|No| E["エラー情報を記録"]
D --> F["空き容量を配列に格納"]
F --> G["シートへ一括出力"]
G --> H["終了"]

【実装:VBAコード】

参照設定を不要にするため、実行時バインディング(Late Binding)を採用しています。

Option Explicit

' =================================================================
' 概要: リモートPCの論理ディスク情報を取得する
' 機能: Win32_LogicalDiskクラスを利用して空き容量を算出
' =================================================================
Sub GetRemoteDiskSpace()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    If lastRow < 2 Then
        MsgBox "A列にターゲットとなるPC名(またはIP)を入力してください。", vbExclamation
        Exit Sub
    End If

    ' 高速化のための設定
    On Error Resume Next
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    Dim i As Long
    Dim strComputer As String
    Dim objWMIService As Object
    Dim colDisks As Object
    Dim objDisk As Object
    Dim results() As Variant
    ReDim results(1 To lastRow - 1, 1 To 3) ' 空き容量, 全容量, 使用率

    For i = 2 To lastRow
        strComputer = ws.Cells(i, 1).Value
        If strComputer <> "" Then
            ' WMIへの接続を試行
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

            If Err.Number <> 0 Then
                results(i - 1, 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 usageInfo As String: usageInfo = ""

                For Each objDisk In colDisks
                    ' バイト単位をGBに変換(小数点第2位まで)
                    diskInfo = diskInfo & objDisk.DeviceID & " " & Format(objDisk.FreeSpace / 1024 / 1024 / 1024, "0.00") & " GB / "
                    sizeInfo = sizeInfo & Format(objDisk.Size / 1024 / 1024 / 1024, "0.00") & " GB / "
                    usageInfo = usageInfo & Format((1 - (objDisk.FreeSpace / objDisk.Size)) * 100, "0.0") & " % / "
                Next

                results(i - 1, 1) = Left(diskInfo, Len(diskInfo) - 3)
                results(i - 1, 2) = Left(sizeInfo, Len(sizeInfo) - 3)
                results(i - 1, 3) = Left(usageInfo, Len(usageInfo) - 3)
            End If
        End If
        Set objWMIService = Nothing
    Next i

    ' シートへ一括出力(セルへの個別書き込みを避けて高速化)
    ws.Range("B2").Resize(UBound(results, 1), 3).Value = results

    ' 設定を元に戻す
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    MsgBox "ディスク情報の取得が完了しました。", vbInformation
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windows OSの管理情報にアクセスするためのインターフェースです。Win32_LogicalDisk クラスを使用することで、物理的な接続形態を問わず論理ドライブの情報を取得できます。

  2. DriveType = 3: ネットワークドライブ(4)やリムーバブルディスク(2)を除外し、内蔵HDD/SSD(3)のみを対象としています。

  3. 高速化の工夫: 1セルずつ書き込むのではなく、結果を一度 results 配列に格納し、最後に Resize メソッドで一括出力しています。これにより、PC台数が多い場合でも描画のオーバーヘッドを最小化しています。

【注意点と運用】

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

  • 実行権限: 実行ユーザーが対象PCに対して管理者権限(Administrator相当)を持っている必要があります。ドメイン環境ではドメイン管理者が実行するのが一般的です。

  • タイムアウトの課題: PCがオフラインの場合、GetObject で応答待ちが発生し処理が一時停止します。大量のPCをスキャンする場合は、事前に Ping コマンド等で死活確認を行うステップを追加することを推奨します。

【まとめ】

  • WMIを活用すればログイン不要で情報収集が可能

  • 一括書き込み(配列処理)でVBAの処理速度は劇的に向上する

  • 権限とネットワーク設定(Firewall)が成功の鍵となる

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

コメント

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