【テクニカル・上級編】【ネットワーク対応】UNCパス(\\Server\Share)経由のFSO操作における権限エラー対処と接続確認 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

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が返すエラーコードを注視せよ。それが、システム管理の深淵に立つ者に求められる唯一の資格だ。

何かあればまた聞け。君のコードが、明日も止まらずに稼働し続けることを願っている。

タイトルとURLをコピーしました