<p><style_prompt_metadata>
contents: VBA_WMI_RemoteDiskQuery
expertise: Office_Automation_Expert
language: Japanese
logic: SWbemLocator_LateBinding_Optimization
</style_prompt_metadata></p>
<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">WMIを活用したリモートPCのディスク空き容量一括取得ツールの開発</h1>
<h3 class="wp-block-heading">【背景と目的】</h3>
<p>ネットワーク経由で複数端末のストレージ残量を自動収集し、手動確認の手間と接続エラーによる処理の中断を解消します(59文字)。</p>
<h3 class="wp-block-heading">【処理フロー図】</h3>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["開始"] --> B["対象ホスト名リストの読み込み"]
B --> C["SWbemLocatorでリモート接続"]
C -->|接続成功| D["Win32_LogicalDiskをクエリ"]
C -->|接続失敗| E["エラー情報を配列に格納"]
D --> F["空き容量・総容量を取得しGB換算"]
F --> G["結果を2D配列へ格納"]
G --> H["全件完了後にシートへ一括出力"]
H --> I["終了"]
</pre></div>
<h3 class="wp-block-heading">【実装:VBAコード】</h3>
<pre data-enlighter-language="generic">Option Explicit
' ================================================================
' 概要: リモートPCのディスク情報を一括取得する
' 備考: 参照設定不要(Late Binding)
' ================================================================
Sub GetRemoteDiskFreeSpace()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
' 入力値(A列にホスト名があると想定)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then Exit Sub
Dim targetHosts As Variant
targetHosts = ws.Range("A2:A" & lastRow).Value
' 結果格納用配列 (ホスト名, ドライブ, 空き容量, 総容量, 状態)
Dim results() As Variant
ReDim results(1 To UBound(targetHosts), 1 To 5)
' 高速化設定
Application.ScreenUpdating = False
Dim locator As Object
Dim service As Object
Dim disks As Object
Dim disk As Object
Dim i As Long
On Error Resume Next
Set locator = CreateObject("WbemScripting.SWbemLocator")
For i = 1 To UBound(targetHosts)
Dim host As String
host = targetHosts(i, 1)
results(i, 1) = host
If host = "" Then GoTo NextHost
' WMI接続(タイムアウトや権限エラーを考慮)
Err.Clear
Set service = locator.ConnectServer(host, "root\cimv2")
If Err.Number <> 0 Then
results(i, 5) = "接続エラー: " & Err.Description
Else
' 論理ディスク情報の取得(DriveType=3 は固定ディスク)
Set disks = service.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")
Dim diskCount As Integer: diskCount = 0
For Each disk In disks
' 最初のドライブ情報のみ取得(実務に合わせて拡張可能)
results(i, 2) = disk.DeviceID
results(i, 3) = Round(disk.FreeSpace / 1024 / 1024 / 1024, 2) & " GB"
results(i, 4) = Round(disk.Size / 1024 / 1024 / 1024, 2) & " GB"
results(i, 5) = "正常"
Exit For ' 複数ドライブある場合はここを調整
Next
End If
NextHost:
Next i
On Error GoTo 0
' シートへ一括出力(B列~F列)
ws.Range("B2").Resize(UBound(results, 1), UBound(results, 2)).Value = results
Application.ScreenUpdating = True
MsgBox "ディスク情報の取得が完了しました。", vbInformation
End Sub
</pre>
<h3 class="wp-block-heading">【技術解説】</h3>
<ol class="wp-block-list">
<li><p><strong>SWbemLocator (Late Binding)</strong>:
<code>WbemScripting.SWbemLocator</code> を使用することで、配布先のPCで参照設定の不整合(参照不可エラー)が発生するリスクを排除しています。</p></li>
<li><p><strong>Win32_LogicalDisk クエリ</strong>:
<code>DriveType = 3</code> と指定することで、ネットワークドライブや光学ドライブを除外し、ローカルのHDD/SSDのみを効率的に抽出します。</p></li>
<li><p><strong>配列処理による高速化</strong>:
セルへの書き込みをループ内で行わず、全てのデータを一度 <code>results</code> 配列に格納してから、最後に一括してセルへ流し込むことで、処理時間を大幅に短縮しています。</p></li>
<li><p><strong>エラーハンドリング</strong>:
リモート接続特有の「RPCサーバーが利用できません」等のエラーでマクロが停止しないよう、<code>On Error Resume Next</code> と <code>Err.Number</code> のチェックを組み合わせています。</p></li>
</ol>
<h3 class="wp-block-heading">【注意点と運用】</h3>
<ul class="wp-block-list">
<li><p><strong>管理者権限とファイアウォール</strong>:
リモートPC側で WMI (DCOM) が許可されている必要があります。拒否される場合は、Windows Defender ファイアウォールの「WMI経由の管理」を許可設定にしてください。</p></li>
<li><p><strong>認証情報</strong>:
本コードは実行ユーザーの権限で接続します。別ドメインや別ユーザーとして実行する場合は、<code>ConnectServer</code> メソッドの引数にユーザー名とパスワードを渡す必要があります。</p></li>
<li><p><strong>64bit環境の考慮</strong>:
今回は Win32 API を直接叩かず、COMコンポーネント(WMI)を利用しているため、<code>PtrSafe</code> は不要ですが、VBA7以降(Excel 2010以降)であれば問題なく動作します。</p></li>
</ul>
<h3 class="wp-block-heading">【まとめ】</h3>
<ul class="wp-block-list">
<li><p><strong>一括処理</strong>: 配列を活用してセルアクセス回数を最小限に抑えるのが高速化の鍵。</p></li>
<li><p><strong>安定性</strong>: <code>On Error Resume Next</code> を局所的に使い、接続失敗したPCを飛ばして処理を継続させる。</p></li>
<li><p><strong>柔軟性</strong>: WMIクエリを変更するだけで、CPU情報やメモリ使用量などの取得にも応用可能。</p></li>
</ul>
contents: VBA_WMI_RemoteDiskQuery
expertise: Office_Automation_Expert
language: Japanese
logic: SWbemLocator_LateBinding_Optimization
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
WMIを活用したリモートPCのディスク空き容量一括取得ツールの開発
【背景と目的】
ネットワーク経由で複数端末のストレージ残量を自動収集し、手動確認の手間と接続エラーによる処理の中断を解消します(59文字)。
【処理フロー図】
graph TD
A["開始"] --> B["対象ホスト名リストの読み込み"]
B --> C["SWbemLocatorでリモート接続"]
C -->|接続成功| D["Win32_LogicalDiskをクエリ"]
C -->|接続失敗| E["エラー情報を配列に格納"]
D --> F["空き容量・総容量を取得しGB換算"]
F --> G["結果を2D配列へ格納"]
G --> H["全件完了後にシートへ一括出力"]
H --> I["終了"]
【実装:VBAコード】
Option Explicit
' ================================================================
' 概要: リモートPCのディスク情報を一括取得する
' 備考: 参照設定不要(Late Binding)
' ================================================================
Sub GetRemoteDiskFreeSpace()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
' 入力値(A列にホスト名があると想定)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then Exit Sub
Dim targetHosts As Variant
targetHosts = ws.Range("A2:A" & lastRow).Value
' 結果格納用配列 (ホスト名, ドライブ, 空き容量, 総容量, 状態)
Dim results() As Variant
ReDim results(1 To UBound(targetHosts), 1 To 5)
' 高速化設定
Application.ScreenUpdating = False
Dim locator As Object
Dim service As Object
Dim disks As Object
Dim disk As Object
Dim i As Long
On Error Resume Next
Set locator = CreateObject("WbemScripting.SWbemLocator")
For i = 1 To UBound(targetHosts)
Dim host As String
host = targetHosts(i, 1)
results(i, 1) = host
If host = "" Then GoTo NextHost
' WMI接続(タイムアウトや権限エラーを考慮)
Err.Clear
Set service = locator.ConnectServer(host, "root\cimv2")
If Err.Number <> 0 Then
results(i, 5) = "接続エラー: " & Err.Description
Else
' 論理ディスク情報の取得(DriveType=3 は固定ディスク)
Set disks = service.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")
Dim diskCount As Integer: diskCount = 0
For Each disk In disks
' 最初のドライブ情報のみ取得(実務に合わせて拡張可能)
results(i, 2) = disk.DeviceID
results(i, 3) = Round(disk.FreeSpace / 1024 / 1024 / 1024, 2) & " GB"
results(i, 4) = Round(disk.Size / 1024 / 1024 / 1024, 2) & " GB"
results(i, 5) = "正常"
Exit For ' 複数ドライブある場合はここを調整
Next
End If
NextHost:
Next i
On Error GoTo 0
' シートへ一括出力(B列~F列)
ws.Range("B2").Resize(UBound(results, 1), UBound(results, 2)).Value = results
Application.ScreenUpdating = True
MsgBox "ディスク情報の取得が完了しました。", vbInformation
End Sub
【技術解説】
SWbemLocator (Late Binding):
WbemScripting.SWbemLocator を使用することで、配布先のPCで参照設定の不整合(参照不可エラー)が発生するリスクを排除しています。
Win32_LogicalDisk クエリ:
DriveType = 3 と指定することで、ネットワークドライブや光学ドライブを除外し、ローカルのHDD/SSDのみを効率的に抽出します。
配列処理による高速化:
セルへの書き込みをループ内で行わず、全てのデータを一度 results 配列に格納してから、最後に一括してセルへ流し込むことで、処理時間を大幅に短縮しています。
エラーハンドリング:
リモート接続特有の「RPCサーバーが利用できません」等のエラーでマクロが停止しないよう、On Error Resume Next と Err.Number のチェックを組み合わせています。
【注意点と運用】
管理者権限とファイアウォール:
リモートPC側で WMI (DCOM) が許可されている必要があります。拒否される場合は、Windows Defender ファイアウォールの「WMI経由の管理」を許可設定にしてください。
認証情報:
本コードは実行ユーザーの権限で接続します。別ドメインや別ユーザーとして実行する場合は、ConnectServer メソッドの引数にユーザー名とパスワードを渡す必要があります。
64bit環境の考慮:
今回は Win32 API を直接叩かず、COMコンポーネント(WMI)を利用しているため、PtrSafe は不要ですが、VBA7以降(Excel 2010以降)であれば問題なく動作します。
【まとめ】
一括処理: 配列を活用してセルアクセス回数を最小限に抑えるのが高速化の鍵。
安定性: On Error Resume Next を局所的に使い、接続失敗したPCを飛ばして処理を継続させる。
柔軟性: WMIクエリを変更するだけで、CPU情報やメモリ使用量などの取得にも応用可能。
コメント