共有フォルダの「肥大化」を根絶せよ:FSOを用いた高速・高精度な重複ファイル検出術
現場の共有サーバーが「謎の容量不足」に陥る原因の8割は、無秩序なファイルの複製です。これを人力で探すのは愚の骨頂。VBScript(FSO)を正しく使えば、サーバーに負荷をかけすぎず、かつ高精度に重複をあぶり出すツールは数分で構築可能です。
多くのエンジニアが陥る「全ファイルを力技でハッシュ計算する」という設計は捨ててください。実務では「サイズ」を一次フィルタリング、「名称」を二次フィルタリングに使うのが、パフォーマンスと精度の黄金比です。
—
なぜ「ハッシュ計算」から入ってはいけないのか
ファイルの中身(ハッシュ値)を比較すれば重複は確実に検知できます。しかし、数TBの共有フォルダで全ファイルのMD5を計算すれば、ディスクI/Oがボトルネックとなり、業務時間中にサーバーを停止させるような高負荷を招きます。
私の推奨する戦略は「多段フィルタリング」です。
1. Size(ファイルサイズ): 完全に一致するものだけをグループ化(高速)
2. Name(ファイル名): サイズが同じものの中で、名称が一致するものをリストアップ
3. (必要であれば)DateLastModified: 最終更新日時でさらなる絞り込み
このアプローチであれば、メタデータの読み取りだけで済むため、サーバーへの負荷は最小限に抑えられます。
—
実践:プロダクションレベルの重複検出スクリプト
このコードは、再帰的にフォルダを探索し、辞書オブジェクト(Dictionary)を活用して「サイズ×名称」のキーを生成します。
‘ FileDupeChecker.vbs
Option Explicit
‘ メイン処理
Dim objFSO, objDict, targetFolder
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objDict = CreateObject(“Scripting.Dictionary”)
‘ 検索対象のフォルダパスを指定
targetFolder = “C:\Target\SharedFolder”
‘ 出力先CSVの準備
Dim objOutFile
Set objOutFile = objFSO.CreateTextFile(“DuplicateList.csv”, True)
objOutFile.WriteLine(“FilePath,FileSize,FileName”)
‘ 再帰探索開始
ScanFolder objFSO.GetFolder(targetFolder), objDict, objOutFile
objOutFile.Close
WScript.Echo “完了しました。DuplicateList.csvを確認してください。”
‘ フォルダ再帰関数
Sub ScanFolder(objFolder, objDict, objOutFile)
Dim objFile, objSubFolder, fileKey
‘ ファイルの処理
For Each objFile In objFolder.Files
‘ キー定義: サイズと名前を結合(一意の識別子)
fileKey = objFile.Size & “|” & objFile.Name
If objDict.Exists(fileKey) Then
‘ 重複発見!リストに書き出し
objOutFile.WriteLine objFile.Path & “,” & objFile.Size & “,” & objFile.Name
Else
‘ 初出のファイルは辞書に追加
objDict.Add fileKey, objFile.Path
End If
Next
‘ サブフォルダを再帰的に探索
For Each objSubFolder In objFolder.SubFolders
ScanFolder objSubFolder, objDict, objOutFile
Next
End Sub
—
エンジニアが守るべき3つの鉄則
このコードをそのまま本番環境で運用するために、以下の「設計の極意」を理解してください。
1. FSOのメモリリークを警戒せよ
VBScriptのオブジェクトは参照カウント方式です。大量のファイルを処理する際、`Set objFolder = Nothing` 等の明示的な解放を怠ると、メモリ消費が右肩上がりになります。今回の設計では再帰で`objFolder`を局所的に生成・解放していますが、巨大なツリーを扱う際はメモリ使用率を常に監視してください。
2. ネットワークパスの「UNCパス」問題
共有フォルダを「Z:」のようなドライブレターで指定するのは危険です。再起動時にマウントが外れる可能性があります。必ず `\\ServerName\ShareName` の形式(UNCパス)で指定してください。FSOはUNCパスを完全にサポートしています。
3. 権限(Permission Denied)への備え
システム管理者の領域を探索する場合、特定のフォルダで「アクセス拒否」のエラーが発生し、スクリプトが停止します。プロダクションコードでは、必ず `On Error Resume Next` を適切に配置し、エラーが発生したフォルダをスキップする例外処理(Err.Numberをチェック)を組み込むのが、「落ちないスクリプト」の最低条件です。
—
次のステップ:さらなる効率化へ
もし「ファイル名が違っても中身が同じ(リネームされた重複)」を検出したい場合は、ファイルサイズで絞り込んだ候補のみに対して、SHA-256などのハッシュ値を計算するフェーズを組み込んでください。
「最初から全力で計算しない」。 これこそが、大規模環境を扱うプロフェッショナルの技術です。このスクリプトを足掛かりに、あなたの共有サーバーから「無駄なコピー」を根絶してください。健闘を祈ります。
