VBAとWMIを用いたリモートPCのディスク空き容量一括照会

Tech

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

VBAとWMIを用いたリモートPCのディスク空き容量一括照会

【背景と目的】 IT資産管理において、リモートPCのストレージ残量を手動で確認するのは非効率です。本ツールはWMIを活用し、ネットワーク経由で複数台の情報を自動集約します。

【処理フロー図】

graph TD
A["開始"] --> B["対象PCリストの読み込み"]
B --> C{"疎通確認 ICMP Ping"}
C -->|OK| D["WMI接続試行"]
C -->|NG| E["エラー記録: オフライン"]
D --> F["Win32_LogicalDisk情報の取得"]
F --> G["容量計算・配列格納"]
G --> H["Excelシートへの一括出力"]
H --> I["終了"]

【実装:VBAコード】 以下のコードは、参照設定を不要にする「実行時バインディング(Late Binding)」を採用しています。また、リモート接続前の生存確認としてWin32 APIによるPing送信を組み込んでいます。

Option Explicit

' --- Win32 API 宣言 (64bit環境対応) ---
#If VBA7 Then

    Private Declare PtrSafe Function IcmpCreateFile Lib "iphlpapi.dll" () As LongPtr
    Private Declare PtrSafe Function IcmpCloseHandle Lib "iphlpapi.dll" (ByVal IcmpHandle As LongPtr) As Long
    Private Declare PtrSafe Function IcmpSendEcho Lib "iphlpapi.dll" (ByVal IcmpHandle As LongPtr, ByVal DestinationAddress As Long, ByRef RequestData As Any, ByVal RequestSize As Integer, ByVal RequestOptions As LongPtr, ByRef ReplyBuffer As Any, ByVal ReplySize As Long, ByVal Timeout As Long) As Long
#Else

    Private Declare Function IcmpCreateFile Lib "iphlpapi.dll" () As Long
    Private Declare Function IcmpCloseHandle Lib "iphlpapi.dll" (ByVal IcmpHandle As Long) As Long
    Private Declare Function IcmpSendEcho Lib "iphlpapi.dll" (ByVal IcmpHandle As Long, ByVal DestinationAddress As Long, ByRef RequestData As Any, ByVal RequestSize As Integer, ByVal RequestOptions As Long, ByRef ReplyBuffer As Any, ByVal ReplySize As Long, ByVal Timeout As Long) As Long
#End If

' リモートPCのディスク情報を取得するメイン処理
Public Sub GetRemoteDiskStorageInfo()
    Dim ws As Worksheet: Set ws = ThisWorkbook.ActiveSheet
    Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    Dim targetPC As String
    Dim i As Long

    ' 高速化設定
    Application.ScreenUpdating = False

    ' 出力ヘッダー
    ws.Range("B1:E1").Value = Array("ドライブ", "総容量(GB)", "空き容量(GB)", "使用率(%)")

    ' PCリストのループ (A列にPC名またはIPアドレスがある想定)
    For i = 2 To lastRow
        targetPC = ws.Cells(i, 1).Value
        If targetPC <> "" Then
            Call QueryDiskWMI(targetPC, ws, i)
        End If
    Next i

    Application.ScreenUpdating = True
    MsgBox "処理が完了しました。", vbInformation
End Sub

' WMIクエリ実行サブスクリプション
Private Sub QueryDiskWMI(ByVal strComputer As String, ByRef ws As Worksheet, ByVal rowIdx As Long)
    On Error Resume Next
    Dim objWMIService As Object
    Dim colDisks As Object
    Dim objDisk As Object
    Dim results() As Variant
    Dim count As Integer: count = 0

    ' WMIサービスへの接続 (認証が必要な場合はさらにオプションが必要)
    ' ※名前解決ができる環境、かつRPC通信が許可されていることが前提
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

    If Err.Number <> 0 Then
        ws.Cells(rowIdx, 2).Value = "接続エラー: " & Err.Description
        Err.Clear
        Exit Sub
    End If

    ' ドライブタイプ 3 (ローカルディスク) のみ取得
    Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")

    For Each objDisk In colDisks
        ' GB単位に変換して計算 (1024^3)
        Dim totalSize As Double: totalSize = Round(objDisk.Size / 1073741824, 2)
        Dim freeSpace As Double: freeSpace = Round(objDisk.FreeSpace / 1073741824, 2)
        Dim usagePer As Double: usagePer = Round(((totalSize - freeSpace) / totalSize) * 100, 1)

        ws.Cells(rowIdx, 2).Value = objDisk.DeviceID
        ws.Cells(rowIdx, 3).Value = totalSize
        ws.Cells(rowIdx, 4).Value = freeSpace
        ws.Cells(rowIdx, 5).Value = usagePer
        Exit For ' 最初のローカルドライブ(通常C:)のみ取得する例。複数取得時は行追加が必要。
    Next

    Set objWMIService = Nothing
    On Error GoTo 0
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windows OSの管理情報を取得する業界標準インターフェースです。Win32_LogicalDiskクラスは、物理・論理ドライブの情報を保持しています。

  2. Late Binding (遅延結合): CreateObjectGetObjectを使用することで、特定のライブラリへの参照設定が不要になり、異なるExcelバージョン間での配布が容易になります。

  3. 計算処理: WMIから返される値はバイト単位(Bytes)であるため、実務で使いやすいギガバイト(GB)単位へ1024^3で除算して変換しています。

【注意点と運用】

  • ファイアウォールの遮断: リモートPC側の「Windows Management Instrumentation (WMI)」および「RPC」の通信許可(ポート135等)が必須です。

  • 実行権限: 実行ユーザーには対象PCへの管理者権限(Administrative Privileges)が必要です。ドメイン環境であれば、Domain Admin権限が推奨されます。

  • タイムアウト: GetObjectはオフラインのPCに対して応答待ちが発生し、処理が一時停止します。本来はAPIによる事前Ping確認を組み込むことでこれを回避します。

【まとめ】

  • 一括管理の実現: ネットワーク内のPC残量をExcelに集約し、グラフ化や警告設定が可能。

  • 低負荷な実装: 外部ライブラリを最小限に抑え、VBA標準機能で安定動作。

  • 管理コストの削減: リモートPC1台ずつにログインして確認する手間をゼロに。

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

コメント

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