【ディスク容量安全確認】Drive オブジェクトを活用した空き容量事前チェックと書き込み失敗防止処理
レガシーシステムの保守、あるいはインフラの自動化スクリプトにおいて、最も愚劣な障害の一つが「容量枯渇による書き込みエラー」である。深夜に走る巨大なバックアップバッチや、CSV一括出力の最中にディスクが満杯になり、中途半端なファイルが残された挙句にシステムが沈黙する――。これを「運がなかった」で済ませるエンジニアは、チーフアーキテクトの称号に値しない。
VBScript(WSH)環境において、ファイルシステムへの書き込み前にリスクを完全に予見し、未然にプロセスを安全停止させるための極限の知見をここに共有する。
—
1. 致命的な落とし穴:なぜ「例外キャッチ」だけでは不十分なのか
多くのプログラマは、ファイル書き込み時に `On Error Resume Next` を仕込み、エラーコードを監視することで満足している。しかし、これはストレージ運用における重大なアンチパターンだ。
- トランザクションの不在: VBScriptの `TextStream` や一般的なファイルI/Oは、書き込み途中の容量枯渇に対してアトミック(不可分)な保証をしない。書き込みが途中で途絶えたファイルは、不完全な破損データとしてストレージに居座る。
- ディスクフル時の副作用: OSの仮想メモリやログ出力機構自体がブロックされ、システム全体がフリーズする危険性がある。
「書き始めてから失敗に気づく」のではなく、「書く前に実行可否を数学的に証明する」。これがプロフェッショナルのアプローチである。
—
2. Drive オブジェクトの深層:正確な空き容量の取得と罠
WSHの `FileSystemObject (FSO)` が提供する `Drive` オブジェクトは、対象ボリュームのメタデータを取得する強力なインターフェースだ。しかし、ここにもレガシー環境特有の罠が潜んでいる。
64ビット整数(Large Integer)の壁
VBScriptの数値型(`Variant/Double` または `Long`)は、巨大なTB(テラバイト)クラスのストレージを扱う際、精度落ち(オーバーフロー)を起こすリスクがある。FSOの `AvailableSpace` プロパティは `Currency` 型に近い挙動を示すが、安全な比較演算を行うためには、適切な型キャストとマージン計算が不可欠である。
—
3. 実装コード:完全防御型ディスク容量チェッカー
以下のコードは、実戦でそのまま使用できるエンタープライズグレードのスクリプトである。
単なる容量チェックにとどらず、必要容量+安全マージン(バッファ)の概念を導入し、枯渇時にはスクリプトを安全に停止(Abort)させる。
‘ ==============================================================================
‘ Script Name: SafeDiskChecker.vbs
‘ Description: Driveオブジェクトを用いた空き容量事前検証と安全停止・通知処理
‘ Author: Chief Architect
‘ ==============================================================================
Option Explicit
‘ 定数定義
Const TargetDrive = “C:” ‘ 監視対象ドライブ
Const RequiredBytes = 1073741824 ‘ 必要容量: 1 GB (1024 1024 1024)
Const SafetyMarginBytes = 524288000 ‘ 安全マージン: 500 MB (OSの動作領域確保のため)
Const ThresholdBytes = RequiredBytes + SafetyMarginBytes
Call Main()
Sub Main()
Dim fso, drv, availableSpace, totalSpace
‘ 1. FileSystemObjectのインスタンス化
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 2. ドライブ存在確認とDriveオブジェクトの取得
If Not fso.Ready(TargetDrive) Then
Call CriticalLog(“ドライブ ” & TargetDrive & ” が応答しません。メディア未挿入またはネットワーク切断の可能性があります。”)
WScript.Quit(1)
End If
Set drv = fso.GetDrive(fso.GetDriveName(TargetDrive))
‘ 3. 容量情報の取得 (AvailableSpace: 実際の利用可能容量)
‘ ※ FreeSpace はクォータ制限を考慮しない場合があるため、AvailableSpaceを推奨
availableSpace = drv.AvailableSpace
totalSpace = drv.TotalSize
‘ 4. 厳格な容量検証(ロギングと判定)
WScript.Echo “— ストレージ診断レポート —”
WScript.Echo “対象ドライブ: ” & TargetDrive
WScript.Echo “総容量: ” & FormatNumber(totalSpace / 1024 / 1024, 2) & ” MB”
WScript.Echo “空き容量: ” & FormatNumber(availableSpace / 1024 / 1024, 2) & ” MB”
WScript.Echo “必要閾値: ” & FormatNumber(ThresholdBytes / 1024 / 1024, 2) & ” MB (必要量 + マージン)”
If availableSpace < ThresholdBytes Then ' 容量不足時の安全停止処理 Call CriticalLog("【FATAL】ディスク容量が不足しています。プロセスを中断します。") ' 必要であれば、ここでイベントログへの書き込みや管理者へのメール通知、 ' あるいは別系統へのフェイルオーバー処理をここにフックする。 ' オブジェクトの明示的解放(メモリ最適化) Set drv = Nothing Set fso = Nothing WScript.Quit(2) ' 異常終了コード End If WScript.Echo "[SUCCESS] 容量チェックを正常に通過しました。メイン処理へ移行します。" ' ========================================================================== ' ここに実際のファイル出力・バックアップ処理を記述 ' ========================================================================== ' 5. 厳格なオブジェクトのライフサイクル管理 Set drv = Nothing Set fso = Nothing WScript.Quit(0) End Sub Sub CriticalLog(message) ' 標準エラー出力への書き込み(WSH標準機能) WScript.StdErr.WriteLine "[" & Now & "] " & message ' 【拡張】Windowsイベントログへ直接書き込む場合(WScript.Shellの利用) ' Dim shell ' Set shell = CreateObject("WScript.Shell") ' shell.LogEvent 1, "SafeDiskChecker: " & message ' Set shell = Nothing End Sub ---
4. チーフアーキテクトが教える「現場の知見」
オブジェクトのライフサイクルとメモリ最適化
VBScriptのCOMコンポーネント(`FileSystemObject` など)は、スクリプト終了時にガベージコレクトされるが、長時間稼働するWSHプロセスや、別のCOMオブジェクトを大量に生成するバッチの内部では、メモリリークの温床となる。
`Set drv = Nothing` および `Set fso = Nothing` による明示的な参照の切断は、COM参照カウントを即座にデクリメントし、リソースをOSに返却するための必須儀式である。これを怠るプログラマは信頼に値しない。
ネットワークドライブ(UNC / 共有フォルダ)の罠
本スクリプトをローカルではなくネットワーク共有(`\\server\share`)に対して適用する場合、`FSO.GetDrive` は機能しない。ネットワークパスに対しては、`FileSystemObject.GetFolder` を経由してアプローチするか、WMI(`Win32_LogicalDisk` または `Win32_Share`)を叩く必要がある。
大規模インフラストラクチャを統合管理するシニアエンジニアであれば、環境に応じた抽象化層をスクリプト内に一枚挟むべきであることを忘れてはならない。
—
5. 結論
自動化の美徳は「止まらないこと」ではなく、「危険を察知して安全に停止すること」にある。
ディスク容量の事前チェックという、一見地味でプリミティブな実装こそが、夜間休日の緊急呼び出しを防ぎ、システムの堅牢性を担保する最後の砦となる。コードの行数をケチらず、あらゆる異常系を想定したコードベースを構築せよ。
