VBA×WMI:リモートPCのディスク空き容量を高速取得する実務ソリューション

Tech

  • 語り口: 徹底してプロフェッショナルかつ実用的。無駄な修飾語を削ぎ落とし、技術的正確性を最優先する。

  • 構成: 階層構造を明確にし、読者が「どこに何が書かれているか」を直感的に理解できるようにする。

  • 視覚的工夫: コードブロック、Mermaid図解、強調太字を効果的に配置し、情報の密度を高める。

  • 思想: 常に「保守性」と「再利用性」を念頭に置いたロジックを提示する。 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

VBA×WMI:リモートPCのディスク空き容量を高速取得する実務ソリューション

【背景と目的】

IT資産管理において、複数台のリモートPCのディスク残量を手動で確認するのは非効率です。ネットワーク遅延や接続拒否への耐性を備えた自動化ロジックを実現します。

【処理フロー図】

graph TD
A["開始"] --> B["ターゲットPCリストの読み込み"]
B --> C["SWbemLocatorでリモート接続試行"]
C -->|成功| D["Win32_LogicalDiskをクエリ"]
C -->|失敗| E["エラーログを記録"]
D --> F["ローカルディスクのみ抽出"]
F --> G["容量計算・配列格納"]
G --> H["Excelシートへ一括書き出し"]
H --> I["終了"]

【実装:VBAコード】

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

Option Explicit

' --------------------------------------------------------------------------------
' 目的: リモートPCのディスク容量情報を取得し、アクティブシートに出力する
' 備考: 管理者権限が必要。FirewallでのWMI通過許可が前提条件。
' --------------------------------------------------------------------------------
Sub GetRemoteDiskFreeSpace()
    Dim pcName As String
    Dim objWMIService As Object
    Dim colDisks As Object
    Dim objDisk As Object
    Dim rowIdx As Long
    Dim results() As Variant
    Dim i As Long

    ' 高速化設定
    Application.ScreenUpdating = False

    ' ターゲットPC名(実務ではセル範囲からループさせることを推奨)
    pcName = "RemotePC001" ' ←ここに対象ホスト名またはIPを入力

    ' 出力用配列の初期化 (PC名, ドライブ, 合計容量, 空き容量, 使用率)
    ReDim results(1 To 1, 1 To 5)

    On Error Resume Next
    ' WMIサービスへの接続(遅延対策のためLocatorを使用)
    Dim objLocator As Object
    Set objLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMIService = objLocator.ConnectServer(pcName, "root\cimv2")

    If Err.Number <> 0 Then
        Debug.Print "接続失敗: " & pcName & " (" & Err.Description & ")"
        On Error GoTo 0
        GoTo Cleanup
    End If
    On Error GoTo 0

    ' 論理ディスク情報の取得 (DriveType 3 = ローカルディスク)
    Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")

    rowIdx = 2 ' 出力開始行
    For Each objDisk In colDisks
        With ActiveSheet
            .Cells(rowIdx, 1).Value = pcName
            .Cells(rowIdx, 2).Value = objDisk.DeviceID
            ' ByteからGBへ変換 (2の30乗で除算)
            .Cells(rowIdx, 3).Value = Round(objDisk.Size / 1073741824, 2) & " GB"
            .Cells(rowIdx, 4).Value = Round(objDisk.FreeSpace / 1073741824, 2) & " GB"
            ' 使用率の計算
            .Cells(rowIdx, 5).Value = Format(1 - (objDisk.FreeSpace / objDisk.Size), "Percent")
        End With
        rowIdx = rowIdx + 1
    Next objDisk

Cleanup:
    Set objWMIService = Nothing
    Set colDisks = Nothing
    Set objLocator = Nothing
    Application.ScreenUpdating = True

    MsgBox "処理が完了しました。", vbInformation
End Sub

【技術解説】

  1. SWbemLocatorの活用: GetObject("winmgmts:...") よりも、SWbemLocator を使用して ConnectServer メソッドを呼び出す方が、タイムアウト制御や認証情報の指定(必要時)において柔軟性が高く、リモート環境に適しています。

  2. DriveType = 3: ネットワークドライブや光学ドライブを除外し、物理的な「ローカル固定ディスク」のみを抽出するためのフィルタリングです。

  3. Late Binding: CreateObject を使用することで、配布先のExcel環境に特定のライブラリが参照設定されていなくても動作する互換性を確保しています。

【注意点と運用】

  1. 権限の壁: リモートPCに対して「管理者権限」を持つユーザーで実行する必要があります。ドメイン環境でない場合は、認証情報の明示的なパスが必要です。

  2. Firewall設定: ターゲットPC側で「Windows Management Instrumentation (WMI)」の受信ルールが許可されている必要があります。

  3. エラーハンドリング: ネットワーク切断時、ConnectServer はタイムアウトまで数秒フリーズします。大量のPCをスキャンする場合は、On Error Resume Next でスキップし、接続不可リストを別途作成する設計が必須です。

【まとめ】

  • 一括取得の効率化: 手動確認を排し、WMIクエリで必要データのみをピンポイントで抽出する。

  • GB単位への変換: 戻り値はByte単位であるため、1073741824 (1024^3) で除算して人間が読みやすい形式に整える。

  • 環境の疎通確認: コード実行前に ping コマンド等で疎通が取れるか確認するステップを組み込むと、より堅牢なツールとなる。

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

コメント

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