VBScriptで構築する「不屈の転送エンジン」:ネットワーク瞬断を制するリトライ・レジューム設計
業務自動化の世界において、VBScriptは「枯れた技術」と揶揄されることがある。だが、OSに深く根を張り、追加のランタイムを必要とせず、管理者権限さえあれば即座に環境を選ばず動作するその特性は、エンタープライズ環境における「最後の砦」だ。
特に、不安定なネットワーク越しにUNCパス(`\\Server\Share\`)を扱う際、FSO(FileSystemObject)の標準メソッドは無力だ。一度のパケットロスで発生する例外をどう捌くか。ここが、ただのスクリプトと「堅牢な業務自動化ツール」を分かつ境界線である。
なぜ、単純なループでは不十分なのか
多くの初学者が陥る罠は、`On Error Resume Next` を乱用し、ループでエラーを無視して継続しようとすることだ。これでは、ネットワーク切断時のステータスがクリアされず、OSのキャッシュがゴミを掴み続ける。
真に堅牢な設計には、以下の3つのレイヤーが必要だ。
1. 疎通確認の強制(Ping & Net Use): OSのネットワークスタックを明示的に叩き起こす。
2. 指数バックオフ: 連続リトライによるサーバー負荷を避ける。
3. レジュームの可否判断: ファイルポインタを意識した差分コピーの戦略。
プロダクション・コード:堅牢なファイル転送アーキテクチャ
以下は、ネットワークトラブルを前提に設計された、再接続&リトライ機能付きのコピー関数である。
‘ — 堅牢なファイルコピーエンジン —
Option Explicit
Const MAX_RETRIES = 5
Const RETRY_INTERVAL = 5 ‘ 秒
Function RobustFileCopy(strSource, strDest, strUNCPath)
Dim fso, shell, i, success
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shell = CreateObject(“WScript.Shell”)
success = False
For i = 1 To MAX_RETRIES
‘ 1. ネットワーク再接続の試行
If ReconnectUNC(strUNCPath) Then
On Error Resume Next
‘ 2. ファイルコピーの実行
‘ FSOのCopyFileは上書きフラグをTrueにするのが安全
fso.CopyFile strSource, strDest, True
If Err.Number = 0 Then
success = True
Exit For
Else
WScript.Echo “Error: ” & Err.Description & ” (Try: ” & i & “)”
Err.Clear
End If
On Error GoTo 0
End If
WScript.Sleep RETRY_INTERVAL 1000
Next
RobustFileCopy = success
End Function
‘ ネットワーク接続を再構築する実務的メソッド
Function ReconnectUNC(strPath)
Dim shell, cmd
Set shell = CreateObject(“WScript.Shell”)
‘ net use で強制切断・再接続を試みる(既存接続がある場合の競合を回避)
cmd = “net use ” & strPath & ” /delete /y”
shell.Run cmd, 0, True
cmd = “net use ” & strPath
‘ 終了コード0を確認することで、接続成功を判定
ReconnectUNC = (shell.Run(cmd, 0, True) = 0)
End Function
設計上の重要ポイントと注意点
1. 「なぜ `net use` を挟むのか」という哲学
FSOは上位のAPIであり、ネットワーク層のスタック状態を直接制御できない。`net use`を呼び出すことで、Windowsの認証キャッシュをリフレッシュし、切断状態のセッションを明示的に切る。これが不安定なVPNや低品質なWi-Fi環境下で、リトライを成功させる唯一の確実な手段だ。
2. ファイル整合性の保証
大容量ファイルを扱う場合、単純なコピーでは「転送中の破損」を検知できない。プロダクション環境では、転送後に必ず「ファイルサイズ」と「最終更新日時」を比較するか、可能であればMD5ハッシュ値を計算する別ツール(`certutil`等)を呼び出して検証工程を挟むべきだ。
3. オブジェクトのライフサイクル管理
VBScriptはガベージコレクションが強力ではない。ループ内で `Set fso = CreateObject(…)` を何度も呼び出すとメモリリークの温床になる。上記のコードのように、メインのループの外側でインスタンスを管理し、エラー発生時のみ再生成する設計が、長時間稼働するバッチには必須である。
結びに:エンジニアの誇りとして
VBScriptは確かに古い。しかし、システムの本質的な複雑性に向き合う姿勢に言語の差はない。
エラーを隠蔽するのではなく、「エラーが発生する前提で、どう回復させるか」というリカバリ戦略こそが、自動化エンジニアの腕の見せ所だ。
この設計をベースに、ログ出力(`Scripting.FileSystemObject` の `OpenTextFile` で追記モード)を組み合わせれば、監視担当者が安心できる、極めて堅牢な運用ツールが完成するはずだ。
さあ、コードを書いて、泥臭いネットワーク環境をエレガントにねじ伏せてほしい。
