<p>[SYS_OFFICE_DB_EXPERT_PROMPT_2024]
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。</p>
<h1 class="wp-block-heading">VBAとWMIによるリモートPCのディスク空き容量一括モニタリング</h1>
<h3 class="wp-block-heading">【背景と目的】</h3>
<p>リモートPCの空き容量不足はシステム停止の要因です。WMIを活用し、ネットワーク経由で複数台のディスク情報を一括で取得・可視化します。</p>
<h3 class="wp-block-heading">【処理フロー図】</h3>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["開始"] --> B["PCリストを配列に格納"]
B --> C["ループ処理開始: 各PCへ接続"]
C --> D{"WMI接続・応答確認"}
D -- 成功 --> E["Win32_LogicalDiskから容量取得"]
D -- 失敗 --> F["エラーメッセージを配列に格納"]
E --> G["結果を2次元配列に蓄積"]
F --> G
G --> H{"全PC終了?"}
H -- No --> C
H -- Yes --> I["シートへ一括出力・書式設定"]
I --> J["終了"]
</pre></div>
<h3 class="wp-block-heading">【実装:VBAコード】</h3>
<pre data-enlighter-language="generic">Option Explicit
' Win32 API 宣言(64bit/32bit両対応)
' 今回は待機処理にSleepを使用する可能性を考慮し定義
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub GetRemoteDiskFreeSpace()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' PC名リストがA列にある前提(2行目から開始)
If lastRow < 2 Then Exit Sub
Dim pcList As Variant: pcList = ws.Range("A2:A" & lastRow).Value
Dim resultData() As Variant
ReDim resultData(1 To UBound(pcList), 1 To 3) ' ドライブ、サイズ、空き容量
Dim i As Long
Dim objWMIService As Object
Dim colDisks As Object
Dim objDisk As Object
Dim strComputer As String
' 画面更新停止で高速化
Application.ScreenUpdating = False
On Error Resume Next
For i = 1 To UBound(pcList)
strComputer = pcList(i, 1)
If strComputer = "" Then GoTo NextLoop
' WMIサービスへの接続(実行権限が必要)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
If Err.Number <> 0 Then
resultData(i, 1) = "接続エラー"
Err.Clear
Else
' ローカル固定ディスク(DriveType = 3)をクエリ
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk Where DriveType = 3")
Dim diskInfo As String: diskInfo = ""
Dim sizeInfo As String: sizeInfo = ""
Dim freeInfo As String: freeInfo = ""
For Each objDisk In colDisks
diskInfo = diskInfo & objDisk.DeviceID & " "
' GB単位に換算して格納
sizeInfo = sizeInfo & Round(objDisk.Size / 1024 / 1024 / 1024, 1) & " GB / "
freeInfo = freeInfo & Round(objDisk.FreeSpace / 1024 / 1024 / 1024, 1) & " GB / "
Next objDisk
resultData(i, 1) = diskInfo
resultData(i, 2) = Left(sizeInfo, Len(sizeInfo) - 3)
resultData(i, 3) = Left(freeInfo, Len(freeInfo) - 3)
End If
NextLoop:
Set objWMIService = Nothing
Next i
On Error GoTo 0
' 結果を一括出力(B~D列)
ws.Range("B2").Resize(UBound(resultData), 3).Value = resultData
Application.ScreenUpdating = True
MsgBox "ディスク容量の照会が完了しました。", vbInformation
End Sub
</pre>
<h3 class="wp-block-heading">【技術解説】</h3>
<ol class="wp-block-list">
<li><p><strong>WMI (Win32_LogicalDisk)</strong>: Windowsの管理基盤を利用し、ネットワーク越しにハードウェア情報を取得します。<code>DriveType = 3</code> を指定することで、ネットワークドライブやCD-ROMを除外した「ローカルHDD/SSD」のみを抽出しています。</p></li>
<li><p><strong>遅延バインディング</strong>: <code>CreateObject</code> や <code>GetObject</code> を使用することで、参照設定(Microsoft WMI Scripting Library)の手間を省き、配布性を高めています。</p></li>
<li><p><strong>配列処理</strong>: セルへの書き込みをループ内で行わず、全てのデータを一度 <code>resultData</code> 配列に格納してから一括出力することで、通信以外の処理時間を極限まで短縮しています。</p></li>
</ol>
<h3 class="wp-block-heading">【注意点と運用】</h3>
<ol class="wp-block-list">
<li><p><strong>権限の壁</strong>: リモートPCに対する管理者権限(Administrator権限)を持つユーザーで実行する必要があります。ドメイン環境でない場合は、認証エラーが発生しやすくなります。</p></li>
<li><p><strong>ファイアウォールの許可</strong>: 対象PC側で「Windows Management Instrumentation (WMI)」の受信ルールが許可されている必要があります。</p></li>
<li><p><strong>タイムアウト</strong>: 応答のないPCがある場合、WMI接続試行時に数秒のフリーズが発生します。より高度な運用では、事前に <code>Win32_PingStatus</code> で疎通確認を行うステップを追加するのが定石です。</p></li>
</ol>
<h3 class="wp-block-heading">【まとめ】</h3>
<ul class="wp-block-list">
<li><p><strong>WMIクエリ</strong>でリモート端末の物理構成を正確に把握する。</p></li>
<li><p><strong>配列一括処理</strong>により、多数のPCを対象とした際のスループットを向上させる。</p></li>
<li><p><strong>エラーハンドリング</strong>を組み込み、オフライン端末によるマクロ停止を防止する。</p></li>
</ul>
[SYS_OFFICE_DB_EXPERT_PROMPT_2024]
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBAとWMIによるリモートPCのディスク空き容量一括モニタリング
【背景と目的】
リモートPCの空き容量不足はシステム停止の要因です。WMIを活用し、ネットワーク経由で複数台のディスク情報を一括で取得・可視化します。
【処理フロー図】
graph TD
A["開始"] --> B["PCリストを配列に格納"]
B --> C["ループ処理開始: 各PCへ接続"]
C --> D{"WMI接続・応答確認"}
D -- 成功 --> E["Win32_LogicalDiskから容量取得"]
D -- 失敗 --> F["エラーメッセージを配列に格納"]
E --> G["結果を2次元配列に蓄積"]
F --> G
G --> H{"全PC終了?"}
H -- No --> C
H -- Yes --> I["シートへ一括出力・書式設定"]
I --> J["終了"]
【実装:VBAコード】
Option Explicit
' Win32 API 宣言(64bit/32bit両対応)
' 今回は待機処理にSleepを使用する可能性を考慮し定義
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub GetRemoteDiskFreeSpace()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' PC名リストがA列にある前提(2行目から開始)
If lastRow < 2 Then Exit Sub
Dim pcList As Variant: pcList = ws.Range("A2:A" & lastRow).Value
Dim resultData() As Variant
ReDim resultData(1 To UBound(pcList), 1 To 3) ' ドライブ、サイズ、空き容量
Dim i As Long
Dim objWMIService As Object
Dim colDisks As Object
Dim objDisk As Object
Dim strComputer As String
' 画面更新停止で高速化
Application.ScreenUpdating = False
On Error Resume Next
For i = 1 To UBound(pcList)
strComputer = pcList(i, 1)
If strComputer = "" Then GoTo NextLoop
' WMIサービスへの接続(実行権限が必要)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
If Err.Number <> 0 Then
resultData(i, 1) = "接続エラー"
Err.Clear
Else
' ローカル固定ディスク(DriveType = 3)をクエリ
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk Where DriveType = 3")
Dim diskInfo As String: diskInfo = ""
Dim sizeInfo As String: sizeInfo = ""
Dim freeInfo As String: freeInfo = ""
For Each objDisk In colDisks
diskInfo = diskInfo & objDisk.DeviceID & " "
' GB単位に換算して格納
sizeInfo = sizeInfo & Round(objDisk.Size / 1024 / 1024 / 1024, 1) & " GB / "
freeInfo = freeInfo & Round(objDisk.FreeSpace / 1024 / 1024 / 1024, 1) & " GB / "
Next objDisk
resultData(i, 1) = diskInfo
resultData(i, 2) = Left(sizeInfo, Len(sizeInfo) - 3)
resultData(i, 3) = Left(freeInfo, Len(freeInfo) - 3)
End If
NextLoop:
Set objWMIService = Nothing
Next i
On Error GoTo 0
' 結果を一括出力(B~D列)
ws.Range("B2").Resize(UBound(resultData), 3).Value = resultData
Application.ScreenUpdating = True
MsgBox "ディスク容量の照会が完了しました。", vbInformation
End Sub
【技術解説】
WMI (Win32_LogicalDisk): Windowsの管理基盤を利用し、ネットワーク越しにハードウェア情報を取得します。DriveType = 3 を指定することで、ネットワークドライブやCD-ROMを除外した「ローカルHDD/SSD」のみを抽出しています。
遅延バインディング: CreateObject や GetObject を使用することで、参照設定(Microsoft WMI Scripting Library)の手間を省き、配布性を高めています。
配列処理: セルへの書き込みをループ内で行わず、全てのデータを一度 resultData 配列に格納してから一括出力することで、通信以外の処理時間を極限まで短縮しています。
【注意点と運用】
権限の壁: リモートPCに対する管理者権限(Administrator権限)を持つユーザーで実行する必要があります。ドメイン環境でない場合は、認証エラーが発生しやすくなります。
ファイアウォールの許可: 対象PC側で「Windows Management Instrumentation (WMI)」の受信ルールが許可されている必要があります。
タイムアウト: 応答のないPCがある場合、WMI接続試行時に数秒のフリーズが発生します。より高度な運用では、事前に Win32_PingStatus で疎通確認を行うステップを追加するのが定石です。
【まとめ】
WMIクエリでリモート端末の物理構成を正確に把握する。
配列一括処理により、多数のPCを対象とした際のスループットを向上させる。
エラーハンドリングを組み込み、オフライン端末によるマクロ停止を防止する。
ライセンス:本記事のテキスト/コードは特記なき限り
CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
コメント