業務でバッチファイルを使ってネットワーク共有フォルダにアクセスする場合、突然の接続断やネットワーク障害によってスクリプトが途中で止まることがあります。手動で対応していては業務効率が落ちるだけでなく、夜間バッチや定期処理では誰も気づかないまま処理が止まるリスクもあります。
本記事では、バッチファイルで共有フォルダへの接続状態を事前に確認し、エラーを検出した場合に自動で再接続を試みるリカバリ処理の実装方法を解説します。基本構文から、リトライロジック・ログ出力・セキュリティ対策まで順を追って紹介します。
この記事で学べること
- 共有フォルダへの接続確認方法(
if exist/net use) - 接続失敗時の自動再接続(リトライ処理)
pingによる事前のサーバー死活確認- 接続ログの自動記録
- パスワードを直書きしないセキュリティ対策(
cmdkey) - タスクスケジューラとの連携時の注意点
共有フォルダへの接続確認の基本
まず最も基本的な方法として、if exist を使って共有フォルダにアクセスできるかを確認します。UNCパス(\\サーバー名\共有名)を直接チェックする方法と、ネットワークドライブ(Z: など)をチェックする方法があります。
@echo off
setlocal
set "SHARE=\\192.168.1.100\shared"
if exist "%SHARE%\" (
echo [OK] 共有フォルダに接続できます。
) else (
echo [ERROR] 共有フォルダに接続できません。
)
endlocal
ドライブレターが割り当てられている場合は以下のようにチェックします。
@echo off
setlocal
set "DRIVE=Z:"
if exist "%DRIVE%\" (
echo [OK] %DRIVE% は接続済みです。
) else (
echo [ERROR] %DRIVE% は未接続です。
)
endlocal
注意:if exist の落とし穴
Windowsは一度接続に成功したパスをキャッシュすることがあります。特にタスクスケジューラ経由ではキャッシュが効かず、実際にアクセスできない場合でも if exist が通ってしまうケースがあります。確実に確認したい場合はファイルの読み書きや net use コマンドのステータス確認を併用してください。
接続エラー検出と自動再接続(基本版)
接続が切れていた場合に net use で再接続を試みる基本スクリプトです。再接続前に既存の接続を削除してからマウントし直すことで、古い接続情報が残って失敗するトラブルを防ぎます。
@echo off
setlocal
set "SHARE=\\192.168.1.100\shared"
set "DRIVE=Z:"
set "USER=DOMAIN\username"
set "PASS=password"
set "LOG=%~dp0connect_log.txt"
echo ==== 処理開始 %DATE% %TIME% ==== >> "%LOG%"
:: ドライブが接続済みか確認
if exist "%DRIVE%\" (
echo [INFO] %DRIVE% は接続済みです。 >> "%LOG%"
goto :MAIN
)
:: 未接続の場合は再接続を試みる
echo [WARN] %DRIVE% が未接続。再接続を試みます。 >> "%LOG%"
:: 既存の接続を削除(残骸を防ぐ)
net use %DRIVE% /delete /yes >nul 2>&1
:: 再接続実行
net use %DRIVE% "%SHARE%" /user:%USER% %PASS% >> "%LOG%" 2>&1
:: 再接続確認
if exist "%DRIVE%\" (
echo [INFO] 再接続に成功しました。 >> "%LOG%"
goto :MAIN
)
echo [ERROR] 再接続に失敗しました。処理を中断します。 >> "%LOG%"
echo ==== 処理終了(エラー) %DATE% %TIME% ==== >> "%LOG%"
exit /b 1
:MAIN
:: ここに本来の処理を記述
echo [INFO] 共有フォルダへのアクセスを確認しました。 >> "%LOG%"
copy "%DRIVE%\data.txt" "%~dp0backup\" >> "%LOG%" 2>&1
echo ==== 処理終了 %DATE% %TIME% ==== >> "%LOG%"
endlocal
ポイント
%~dp0でスクリプトと同じフォルダにログを出力するのがおすすめですnet use /deleteを先に実行することで古い接続情報をリセットできますgoto :MAINで共通処理部分へジャンプし、コードの重複を避けます
リトライ処理を組み込む(実務向け)
一時的なネットワーク瞬断では、少し待ってから再試行すれば復旧することがよくあります。ループを使って複数回リトライする処理を組み込むと、より堅牢なスクリプトになります。
@echo off
setlocal enabledelayedexpansion
set "SHARE=\\192.168.1.100\shared"
set "DRIVE=Z:"
set "USER=DOMAIN\username"
set "PASS=password"
set "LOG=%~dp0connect_log.txt"
set "RETRY_MAX=3"
set "RETRY_WAIT=5"
echo ==== 処理開始 %DATE% %TIME% ==== >> "%LOG%"
:: 接続確認ループ
set "CONNECTED=0"
for /L %%i in (1,1,%RETRY_MAX%) do (
if !CONNECTED! == 0 (
if exist "%DRIVE%\" (
echo [INFO] [試行%%i] %DRIVE% に接続済みです。 >> "%LOG%"
set "CONNECTED=1"
) else (
echo [WARN] [試行%%i] %DRIVE% が未接続。再接続を試みます。 >> "%LOG%"
net use %DRIVE% /delete /yes >nul 2>&1
net use %DRIVE% "%SHARE%" /user:%USER% %PASS% >nul 2>&1
if exist "%DRIVE%\" (
echo [INFO] [試行%%i] 再接続に成功しました。 >> "%LOG%"
set "CONNECTED=1"
) else (
echo [WARN] [試行%%i] 接続失敗。%RETRY_WAIT%秒後にリトライします。 >> "%LOG%"
timeout /t %RETRY_WAIT% /nobreak >nul
)
)
)
)
:: 最終判定
if !CONNECTED! == 0 (
echo [ERROR] %RETRY_MAX%回試みましたが接続できませんでした。処理を中断します。 >> "%LOG%"
echo ==== 処理終了(エラー) %DATE% %TIME% ==== >> "%LOG%"
exit /b 1
)
:: 本来の処理
echo [INFO] メイン処理を開始します。 >> "%LOG%"
copy "%DRIVE%\data.txt" "%~dp0backup\" >> "%LOG%" 2>&1
echo ==== 処理終了 %DATE% %TIME% ==== >> "%LOG%"
endlocal
このスクリプトでは setlocal enabledelayedexpansion と !CONNECTED! を使っています。FOR ループ内でフラグ変数を参照するには遅延展開が必要です。詳しくはsetlocal enabledelayedexpansionの使い方と遅延展開の仕組みを参照してください。
ping でサーバー死活確認を行ってから接続する
ネットワークドライブのマウントを試みる前に、ping でサーバー自体が応答するかを確認しておくと、接続タイムアウトで長時間待たされるのを防げます。
@echo off
setlocal
set "SERVER=192.168.1.100"
set "SHARE=\\%SERVER%\shared"
set "DRIVE=Z:"
set "LOG=%~dp0connect_log.txt"
echo ==== 処理開始 %DATE% %TIME% ==== >> "%LOG%"
:: サーバーへの ping 確認(1回のみ、タイムアウト1秒)
ping -n 1 -w 1000 %SERVER% >nul 2>&1
if errorlevel 1 (
echo [ERROR] サーバー %SERVER% に到達できません。ネットワーク障害の可能性があります。 >> "%LOG%"
echo ==== 処理終了(エラー) %DATE% %TIME% ==== >> "%LOG%"
exit /b 1
)
echo [INFO] サーバー %SERVER% への疎通を確認しました。 >> "%LOG%"
:: ドライブ接続確認
if not exist "%DRIVE%\" (
net use %DRIVE% /delete /yes >nul 2>&1
net use %DRIVE% "%SHARE%" >nul 2>&1
if not exist "%DRIVE%\" (
echo [ERROR] ドライブマウントに失敗しました。 >> "%LOG%"
exit /b 1
)
)
echo [INFO] 接続確認完了。メイン処理を開始します。 >> "%LOG%"
endlocal
注意:ping が通っても共有フォルダにアクセスできない場合があります
ping はICMPプロトコルを使うため、ファイル共有(SMBポート445)とは独立しています。pingが通っても共有フォルダの権限エラーやSMBの問題でアクセスできない場合があります。ping はあくまで「サーバーが生きているか」の簡易確認として使いましょう。
net use の戻り値でエラー内容を判別する
net use コマンドは ERRORLEVEL に戻り値をセットします。0 は成功、それ以外はエラーです。エラーコードによって原因を特定できます。
| ERRORLEVEL | 主な原因 | 対処法 |
|---|---|---|
| 0 | 成功 | − |
| 2 | ファイルが見つからない(パスが間違い) | 共有名・パスを確認 |
| 5 | アクセス拒否(権限不足) | ユーザー・パスワードを確認 |
| 53 | サーバーが見つからない(ネットワーク到達不能) | pingで疎通確認 |
| 67 | ネットワーク名が見つからない | 共有名・サービス状態を確認 |
| 86 | ネットワークパスワードが間違っている | 認証情報を確認 |
| 1219 | 同じサーバーに複数の資格情報で接続しようとしている | net use /delete で既存削除 |
@echo off
setlocal
set "DRIVE=Z:"
set "SHARE=\\192.168.1.100\shared"
net use %DRIVE% "%SHARE%" >nul 2>&1
set "ERR=%errorlevel%"
if %ERR% == 0 (
echo 接続成功
goto :END
)
if %ERR% == 53 echo [ERROR 53] サーバーに到達できません(ネットワーク障害)
if %ERR% == 5 echo [ERROR 5] アクセスが拒否されました(権限エラー)
if %ERR% == 86 echo [ERROR 86] パスワードが間違っています
if %ERR% == 1219 echo [ERROR 1219] 同一サーバーへの複数接続が競合しています
:END
endlocal
ポイント:errorlevel を変数に保存する
net use の後すぐに別のコマンドを実行すると、そのコマンドによって ERRORLEVEL が上書きされます。set "ERR=%errorlevel%" で即座に変数に保存しておくのが安全です。詳しくはエラー時に処理を中断・終了する方法を参照してください。
パスワードをスクリプトに直書きしない(セキュリティ対策)
前述のサンプルでは説明のためにパスワードを直書きしていましたが、実務では絶対に避けてください。スクリプトファイルを誰かが閲覧・共有すると認証情報が漏洩します。主な対策方法を2つ紹介します。
方法1:cmdkey で資格情報を事前登録する
Windowsの「資格情報マネージャー」に接続情報を登録しておくと、スクリプト内でパスワードを指定しなくても自動認証されます。
cmdkey /add:192.168.1.100 /user:DOMAIN\username /pass:password
登録後は以下のように書けます。パスワードの記述が不要になります。
@echo off setlocal set "DRIVE=Z:" set "SHARE=\\192.168.1.100\shared" :: パスワード指定不要(資格情報マネージャーが自動補完) net use %DRIVE% "%SHARE%" endlocal
方法2:外部ファイルから読み込む
パスワードを別ファイルに分離して、本番環境のみアクセス制限をかける方法もあります。ただし、ファイル自体の保護(アクセス権・暗号化)が前提です。
DOMAIN\username password
@echo off
setlocal enabledelayedexpansion
set "CRED_FILE=%~dp0credentials.txt"
set "DRIVE=Z:"
set "SHARE=\\192.168.1.100\shared"
:: 1行目=ユーザー名, 2行目=パスワード
set "LINE=0"
for /f "usebackq delims=" %%A in ("%CRED_FILE%") do (
set /a LINE+=1
if !LINE! == 1 set "USER=%%A"
if !LINE! == 2 set "PASS=%%A"
)
net use %DRIVE% "%SHARE%" /user:!USER! !PASS!
endlocal
完全版:リトライ+ログ+エラー通知スクリプト
実務で使える完全版スクリプトです。リトライ・ログ出力・エラー時のWindowsイベントログ書き込みを組み合わせています。
@echo off
setlocal enabledelayedexpansion
:: ===== 設定 =====
set "SERVER=192.168.1.100"
set "SHARE=\\%SERVER%\shared"
set "DRIVE=Z:"
set "USER=DOMAIN\username"
set "PASS=password"
:: ※ パスワード直書きを避けたい場合は cmdkey で事前登録し、/user/%PASS% を削除すること
set "LOG=%~dp0recover_log.txt"
set "RETRY_MAX=3"
set "RETRY_WAIT=10"
:: ===== 開始ログ =====
echo ==== 処理開始 %DATE% %TIME% ==== >> "%LOG%"
:: ===== サーバー疎通確認 =====
ping -n 1 -w 2000 %SERVER% >nul 2>&1
if errorlevel 1 (
echo [ERROR] サーバー %SERVER% への疎通失敗。 >> "%LOG%"
goto :ERROR
)
echo [INFO] サーバー疎通OK。 >> "%LOG%"
:: ===== リトライ付き接続確認 =====
set "CONNECTED=0"
for /L %%i in (1,1,%RETRY_MAX%) do (
if !CONNECTED! == 0 (
if exist "%DRIVE%\" (
set "CONNECTED=1"
echo [INFO] [試行%%i] %DRIVE% 接続済み。 >> "%LOG%"
) else (
net use %DRIVE% /delete /yes >nul 2>&1
net use %DRIVE% "%SHARE%" /user:%USER% %PASS% >nul 2>&1
if exist "%DRIVE%\" (
set "CONNECTED=1"
echo [INFO] [試行%%i] 再接続成功。 >> "%LOG%"
) else (
echo [WARN] [試行%%i] 接続失敗。%RETRY_WAIT%秒待機。 >> "%LOG%"
timeout /t %RETRY_WAIT% /nobreak >nul
)
)
)
)
if !CONNECTED! == 0 goto :ERROR
:: ===== メイン処理 =====
echo [INFO] メイン処理開始。 >> "%LOG%"
xcopy "%DRIVE%\data" "%~dp0backup\" /e /i /y >> "%LOG%" 2>&1
if errorlevel 1 (
echo [ERROR] xcopy に失敗しました。 >> "%LOG%"
goto :ERROR
)
echo [INFO] メイン処理完了。 >> "%LOG%"
echo ==== 処理終了 %DATE% %TIME% ==== >> "%LOG%"
exit /b 0
:: ===== エラー終了 =====
:ERROR
echo [ERROR] エラーにより処理を中断しました。 >> "%LOG%"
echo ==== 処理終了(エラー) %DATE% %TIME% ==== >> "%LOG%"
:: Windowsイベントログに書き込み(管理者権限が必要)
eventcreate /t ERROR /id 100 /l APPLICATION /d "recover_share.bat: 共有フォルダ接続失敗" >nul 2>&1
exit /b 1
eventcreate コマンドについて
eventcreate はWindowsイベントログにカスタムメッセージを書き込むコマンドです。管理者権限が必要ですが、タスクスケジューラと組み合わせると、エラー発生時にイベントビューアーで検知・監視ができます。エラーログのファイル出力と組み合わせてより詳細に残したい場合はバッチファイルでエラーログを自動収集して保存する方法も参照してください。
タスクスケジューラで動かす場合の注意点
タスクスケジューラからバッチを実行する場合、ユーザーがログオンしていなくても動作しますが、その際はネットワークドライブ(Z: など)が使えないことがあります。これはWindowsのセキュリティ仕様(UAC・セッション分離)によるものです。
詳細はタスクスケジューラでネットワーク共有にアクセスできないときの解決策(EnableLinkedConnections)をご参照ください。
タスクスケジューラでの動作を前提とする場合は、ドライブレターではなくUNCパスを直接使う方法が最も確実です。
@echo off
setlocal
:: ドライブレターではなくUNCパスを直接使う
set "SHARE=\\192.168.1.100\shared"
if exist "%SHARE%\" (
echo [OK] 接続確認済み。
xcopy "%SHARE%\data" "C:\backup\" /e /i /y
) else (
echo [ERROR] 共有フォルダにアクセスできません。
exit /b 1
)
endlocal
関連記事:共有フォルダ・ネットワークドライブの基礎
本記事ではエラー検出とリカバリに特化しましたが、net use の基本構文やUNCパスの使い方はバッチファイルで共有フォルダにアクセスする方法で詳しく解説しています。
また、ネットワークドライブの永続マウントや起動時の自動マウントスクリプト全般についてはnet useでネットワークドライブを自動マウントする方法も参考にしてください。
よくある質問(FAQ)
if exist が失敗することがあるif exist の代わりに dir "%DRIVE%\*" を実行してエラーレベルで判定するか、実際にファイルの読み書きを試みる方法も有効です。net use が突然エラーになる原因は?net use /delete してから再接続するのが安定します。cmdkey コマンドでWindowsの資格情報マネージャーに登録しておくと、スクリプト内でパスワードを書かずに接続できます。また、Active Directoryドメイン環境ではドメイン認証が自動的に使われるため、パスワードの指定自体が不要なケースも多いです。まとめ
バッチファイルでの共有フォルダ接続エラー検出と自動リカバリのポイントをまとめます。
- 接続確認:
if exist "%DRIVE%"または UNCパスで確認 - 自動再接続:
net use /delete→net useの順で実行 - リトライ処理:
for /Lループ+フラグ変数で複数回試行 - 事前確認:
pingでサーバー疎通チェックをしてから接続 - セキュリティ:パスワードは
cmdkeyで資格情報マネージャーに登録 - タスクスケジューラ対応:ドライブレターではなくUNCパスを使う
ネットワーク障害に強い自動回復付きバッチスクリプトを構築することで、業務処理の安定稼働と運用負担の軽減が実現できます。共有フォルダへのアクセス基礎についてはバッチファイルで共有フォルダにアクセスする方法もあわせてご確認ください。

