UNCパスの深淵:VBScriptにおけるネットワークI/Oの「作法」と「真実」
VBScriptを駆使してエンタープライズ環境を渡り歩いてきた諸君であれば、一度は経験があるはずだ。ローカルドライブでは完璧に動作するFSO(FileSystemObject)が、UNCパス(`\\Server\Share`)を指定した瞬間に「パスが見つかりません」あるいは「アクセス拒否」の深淵に突き落とされる現象を。
これは単なる権限の問題ではない。Windowsのセッション管理、認証トークン、そしてネットワークI/Oの非同期性に潜む「レガシーの呪縛」だ。今日は、この泥沼を回避し、堅牢なシステムを構築するための極限の知見を授ける。
—
1. UNCパスの宿命と「認証の壁」
FSOは非常に優秀だが、その背後で動く `Scripting.FileSystemObject` は、対話型セッションのコンテキストに強く依存する。タスクスケジューラやサービス経由で実行する場合、SYSTEMアカウントや特定のサービスアカウントには、ネットワーク共有への認証情報がキャッシュされていないことがほとんどだ。
認証エラーを回避する「WNetAddConnection2」の活用
`Net Use` コマンドを `WScript.Shell` で叩くのは素人のやり方だ。実行のたびにシェルを呼び出すオーバーヘッドは無視できず、何より標準出力のハンドリングが甘くなる。真のエンジニアは、Windows APIを直接呼び出す。
‘ Win32 APIの定義:ネットワーク接続をプログラム的に制御する
Const RESOURCETYPE_DISK = &H1
Const CONNECT_TEMPORARY = &H0
‘ API呼び出し用のラッパー関数
Function ConnectToUNC(strPath, strUser, strPass)
Dim objNetwork
Set objNetwork = CreateObject(“WScript.Network”)
‘ APIを直接叩くのがベストだが、VBScriptではWScript.NetworkのMapNetworkDriveが現実的
‘ ただし、接続前に存在チェックを行うのがプロの流儀
On Error Resume Next
objNetwork.MapNetworkDrive “”, strPath, False, strUser, strPass
If Err.Number <> 0 Then
‘ ここでエラーコードをハンドリングし、再試行ロジックへ移行する
ConnectToUNC = False
Else
ConnectToUNC = True
End If
On Error GoTo 0
Set objNetwork = Nothing
End Function
—
2. ネットワーク遅延を制する:存在確認の哲学
UNCパスは不安定だ。ルーターの瞬断やサーバーの過負荷が、`FSO.FolderExists` を誤作動させる。単一の確認だけで「存在しない」と判断するのは愚策である。
「冪等性」と「リトライ」の実装
ファイルシステムがネットワーク越しである場合、OSはキャッシュを優先する。我々は、少なくとも3回のリトライと、指数バックオフ(待ち時間を少しずつ増やす)を実装すべきだ。
Function SafeFolderExists(strUNCPath)
Dim fso, i
Set fso = CreateObject(“Scripting.FileSystemObject”)
For i = 1 To 3
If fso.FolderExists(strUNCPath) Then
SafeFolderExists = True
Exit Function
End If
WScript.Sleep (1000 i) ‘ ネットワークのゆらぎを考慮した待機
Next
SafeFolderExists = False
Set fso = Nothing ‘ メモリリークを許さない
End Function
—
3. メモリ管理とオブジェクトのライフサイクル
VBScriptにおいて `Set obj = Nothing` を軽視する者は、いずれシステムを停止させる。特にネットワークI/Oを伴うループ処理では、オブジェクトの開放漏れはハンドル数の枯渇を招く。
- スコープの最小化: 可能な限り、関数内でオブジェクトを生成し、その関数内で破棄する。
- 明示的解放: `Set obj = Nothing` は単なる儀式ではない。COM参照カウントをデクリメントし、即座にメモリを解放するための「意志表示」である。
—
4. 現場で使える「堅牢な接続」のテンプレート
最後に、実戦でそのまま使える構成を示す。UNC操作を行う際は、必ず以下の骨格を守れ。
Option Explicit
Sub Main()
Dim strUNC : strUNC = “\\TargetServer\SharedFolder”
Dim fso
‘ 1. まず存在チェック
If Not SafeFolderExists(strUNC) Then
‘ 2. 失敗なら認証処理へ
If Not ConnectToUNC(strUNC, “domain\user”, “password”) Then
WScript.Echo “致命的エラー: ネットワーク接続失敗”
WScript.Quit 1
End If
End If
‘ 3. ここで初めてFSOを操作
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ … 業務ロジック …
‘ 4. 徹底したクリーンアップ
Set fso = Nothing
End Sub
—
結論:自動化とは「エラーを前提とすること」
ネットワーク越しにファイルシステムを扱う以上、エラーは「発生するもの」としてコードを書かなければならない。VBScriptは古い言語だが、その背後で動くWindows APIは依然として現役の強力な武器だ。
「なぜ動かないのか」と悩む前に、ネットワーク層の認証状態と、APIが返すエラーコードを注視せよ。それが、システム管理の深淵に立つ者に求められる唯一の資格だ。
何かあればまた聞け。君のコードが、明日も止まらずに稼働し続けることを願っている。
