[style_prompt: technical_blog_v1]
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
【VBA×WMI】リモートPCのディスク空き容量を高速に自動集計するプログラミング手法
【背景と目的】
複数台のPC資産を管理する際、手動での容量確認は非効率でミスも誘発します。WMIを利用し、ネットワーク経由でディスク情報を一括取得・可視化する仕組みを構築します。
【処理フロー図】
graph TD
A["開始"] --> B["対象PCリストの読み込み"]
B --> C["対象PCへの導通確認"]
C --> D{"応答あり?"}
D -- Yes --> E["WMI接続試行"]
D -- No --> F["エラー記録/次へ"]
E --> G["Win32_LogicalDiskクエリ実行"]
G --> H["結果を配列へ格納"]
H --> I["全処理終了?"]
I -- No --> B
I -- Yes --> J["Excelシートへ一括出力"]
J --> K["終了"]
【実装:VBAコード】
Option Explicit
' --- Win32 API 宣言 (64bit/32bit両対応) ---
' ネットワーク疎通確認(Ping)の代用として簡易的な接続チェック等に利用可能
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
''' <summary>
''' リモートPCのディスク情報を取得しシートに出力する
''' </summary>
Sub GetRemoteDiskInventory()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "A列にPC名を入力してください。", vbExclamation
Exit Sub
End If
' 高速化設定
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim pcList As Variant
pcList = ws.Range("A2:A" & lastRow).Value ' PC名を配列へ格納
Dim results() As Variant
ReDim results(1 To UBound(pcList), 1 To 4) ' 結果格納用配列 (Drive, Size, Free, %)
Dim i As Long
Dim objWMIService As Object
Dim colDisks As Object
Dim objDisk As Object
Dim targetPC As String
For i = 1 To UBound(pcList)
targetPC = pcList(i, 1)
If targetPC <> "" Then
On Error Resume Next
' WMIへの接続 (名前解決ができない場合や権限不足時はエラー)
' Late Binding により参照設定不要
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & targetPC & "\root\cimv2")
If Err.Number = 0 Then
' 固定ディスク(DriveType=3)のみをクエリ
Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")
For Each objDisk In colDisks
' 最初のドライブ(通常C:)のみ取得する例
results(i, 1) = objDisk.DeviceID
results(i, 2) = Round(objDisk.Size / 1024^3, 2) & " GB"
results(i, 3) = Round(objDisk.FreeSpace / 1024^3, 2) & " GB"
results(i, 4) = Round((objDisk.FreeSpace / objDisk.Size) * 100, 1) & " %"
Exit For ' 複数ドライブある場合はロジックの調整が必要
Next
Else
results(i, 1) = "接続エラー"
Err.Clear
End If
On Error GoTo 0
End If
Next i
' シートへ一括出力 (B列~E列)
ws.Range("B2").Resize(UBound(results, 1), 4).Value = results
' 高速化設定の解除
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
MsgBox "ディスク情報の取得が完了しました。", vbInformation
End Sub
【技術解説】
WMI (Windows Management Instrumentation): Windowsの管理情報を取得する強力なAPIです。
Win32_LogicalDiskクラスを参照することで、ドライブレター、全容量、空き容量をバイト単位で取得できます。Late Binding (遅延結合):
CreateObjectやGetObjectを使用することで、特定のライブラリ(Microsoft WMI Scripting Library等)への参照設定を不要にし、他ユーザーへの配布時のトラブルを防いでいます。高速化ロジック: 1セルずつ書き込むのではなく、対象PCリストを一旦配列(
pcList)に読み込み、結果も配列(results)に蓄積。最後に一括でセルへ流し込むことで、描画負荷を最小限に抑えています。
【注意点と運用】
権限の壁: リモートPCのWMIにアクセスするには、実行ユーザーが対象PCに対して管理者権限(Administrator)を持っている必要があります。ドメイン環境であれば、ドメイン管理権限での実行が推奨されます。
ファイアウォールの許可: 対象PC側で「リモート管理 (WMI)」の通信が許可されていない場合、接続エラーとなります。
エラーハンドリング: ネットワーク未接続やPC電源OFFの場合にマクロが停止しないよう、
On Error Resume Nextによるトラップとクリア(Err.Clear)が不可欠です。
【まとめ】
配列処理を徹底し、ネットワーク遅延以外の要因(Excel描画など)によるボトルネックを排除する。
エラー処理を組み込み、一部のPCがオフラインでも全体の集計処理を止めない設計にする。
管理者権限とFW設定を事前に確認し、WMI接続が確立できるインフラ環境を整える。

コメント