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

Tech

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

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

【背景と目的】

本ツールは、社内ネットワーク上の複数PCに対して、物理的な巡回なしでストレージ容量を遠隔監視することを目的としています。 実務では「リモート接続時のタイムアウトによるフリーズ」や「権限不足による実行エラー」が大きな壁となりますが、これらを考慮した堅牢な設計を解説します。

【処理フロー図】

graph TD
A["開始"] --> B["ホスト名/IPの疎通確認"]
B -->|Ping OK| C["WMIオブジェクト接続"]
B -->|Ping NG| G["エラーログ記録"]
C --> D["Win32_LogicalDiskクエリ実行"]
D --> E["空き容量・総容量の取得と計算"]
E --> F["Excelシートへ一括書き出し"]
F --> H["終了"]
G --> H

【実装:VBAコード】

以下のコードは、参照設定の手間を省く「実行時バインディング(Late Binding)」を採用し、かつネットワークの死活監視に Win32 API を使用した実用的な構成です。

Option Explicit

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

    Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
    ' 疎通確認用(ICMP PING)
    Private Declare PtrSafe Function IcmpCreateFile Lib "icmp.dll" () As LongPtr
    Private Declare PtrSafe Function IcmpSendEcho Lib "icmp.dll" (ByVal IcmpHandle As LongPtr, ByVal DestinationAddress As Long, ByRef RequestData As Any, ByVal RequestSize As Integer, ByRef RequestOptions As Any, ByRef ReplyBuffer As Any, ByVal ReplySize As Long, ByVal Timeout As Long) As Long
#Else

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

''' <summary>
''' リモートPCのディスク情報を取得し、アクティブシートに出力するメインルーチン
''' </summary>
Public Sub GetRemoteDiskSpace()
    Dim strComputer As String
    Dim objWMIService As Object
    Dim colDisks As Object
    Dim objDisk As Object
    Dim i As Long
    Dim lastRow As Long

    ' 高速化処理
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
    End With

    ' A列に記載されたコンピュータ名を順次読み取る想定
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    For i = 2 To lastRow
        strComputer = Cells(i, 1).Value
        If strComputer = "" Then GoTo NextLoop

        On Error Resume Next
        ' WMI接続(偽装レベルをimpersonateに設定)
        Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

        If Err.Number <> 0 Then
            Cells(i, 2).Value = "接続エラー: " & Err.Description
            Err.Clear
        Else
            ' DriveType = 3 (ローカルハードディスクのみ)を抽出
            Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")

            Dim diskInfo As String: diskInfo = ""
            For Each objDisk In colDisks
                ' 容量をGB単位に変換(小数点第2位まで)
                diskInfo = diskInfo & objDisk.DeviceID & " " & _
                           Format(objDisk.FreeSpace / 1024 / 1024 / 1024, "0.00") & "GB / " & _
                           Format(objDisk.Size / 1024 / 1024 / 1024, "0.00") & "GB" & vbCrLf
            Next

            Cells(i, 2).Value = diskInfo
        End If
        On Error GoTo 0

NextLoop:
    Next i

    ' 高速化処理の解除
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
    End With

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

【技術解説】

  1. Win32_LogicalDisk クラス: Windows管理情報の中で、ドライブレター、ファイルシステム、空き容量などを保持するクラスです。DriveType = 3 を指定することで、ネットワークドライブやCD-ROMを除外し、純粋な内蔵HDD/SSDのみをターゲットにしています。

  2. 遅延バインディング (Late Binding): CreateObjectGetObject を使用することで、「Microsoft WMI Service Library」への参照設定を不要にしています。これにより、異なるExcelバージョン間での配布が容易になります。

  3. 高速化の工夫: Application.ScreenUpdating = False により、セルへの書き込み時の描画負荷を抑制しています。大量のPCをスキャンする場合に効果を発揮します。

【注意点と運用】

  • ファイアウォールの許可: リモートPC側で「Windows Management Instrumentation (WMI)」の通信がファイアウォールで許可されている必要があります(通常はTCP 135番ポートとダイナミックポートを使用)。

  • 実行権限: 実行するユーザーが対象のリモートPCに対して Administrator権限 を持っている必要があります。一般ユーザー権限では接続が拒否されます。

  • ネットワーク遅延: 存在しないホスト名に対して実行すると GetObject で長時間待機が発生します。前段でAPIによるPing確認を組み込むか、タイムアウト設定を考慮することが実務上のコツです。

【まとめ】

  1. 接続設定: 偽装レベル(impersonate)を正しく指定してリモート権限を確保する。

  2. 型定義: 実務配布を想定し、参照設定不要な Late Binding で記述する。

  3. エラーハンドリング: 1台の失敗で全体を止めないよう On Error Resume Next を適切に配置する。

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

コメント

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