バッチファイルを手動実行するとZ:などのネットワークドライブに正常にアクセスできるのに、タスクスケジューラで自動実行すると「パスが見つかりません」「アクセスが拒否されました」となる――この問題に悩んだことはないでしょうか。
原因はWindowsのUAC(ユーザーアカウント制御)によるSplit Token(トークン分離)です。タスクスケジューラの「最高の特権で実行」を有効にすると、昇格トークンが使われ、通常トークンでマップしたドライブが見えなくなります。本記事では原因の仕組みから4つの解決策、そしてEnableLinkedConnectionsの詳細設定まで順を追って解説します。
- UACのSplit Tokenがなぜネットワークドライブを見えなくするのかの仕組み
- 解決策①:UNCパスを直接使う(最も確実で推奨)
- 解決策②:タスク内でnet useを使ってドライブを明示的にマップ
- 解決策③:EnableLinkedConnectionsレジストリでドライブ共有(要再起動)
- 解決策④:実行アカウントを変更してSplit Tokenを回避
- 問題の診断方法とトラブルシューティングチェックリスト
なぜタスクスケジューラからネットワーク共有にアクセスできないのか
UACのSplit Tokenとは
Windows Vista以降、管理者グループに属するユーザーでログオンすると、UACによって2種類のトークン(アクセス許可の証明書)が作成されます。
| トークン種類 | 権限 | ネットワークドライブの見え方 |
|---|---|---|
| 標準トークン(非昇格) | 通常ユーザー権限 | Explorerでマップした Z: 等が見える |
| 昇格トークン(管理者) | 管理者権限 | 独立したドライブマップ空間(標準トークンのZ:は見えない) |
Explorerからネットワークドライブを接続すると標準トークン側に登録されます。一方、タスクスケジューラで「最高の特権で実行」を有効にすると、プロセスは昇格トークンで動作するため、標準トークン側のZ:が見えなくなります。
/RU SYSTEMでタスクを登録した場合、SYSTEMアカウントはネットワーク認証情報を持たないため、そもそもネットワーク共有にアクセスできません。こちらは解決策④で対処します。問題の切り分け:どのケースに当てはまるか
| 症状 | 原因 | 対応解決策 |
|---|---|---|
| 手動実行OK・スケジューラNG(最高権限あり) | Split Token によるドライブ分離 | ①②③ |
| SYSTEM実行でネットワーク共有にアクセス不可 | SYSTEMはネットワーク認証なし | ④ |
| 別ユーザーで実行・そのユーザーはドライブ未接続 | ユーザーごとにドライブマップが独立 | ②④ |
| ドメイン環境でログオフ中にアクセス不可 | 認証情報の保持設定 | ②(/PERSISTENT:YES)④ |
解決策①:UNCパスを直接使う(最推奨)
最も確実で副作用のない解決策は、ドライブレター(Z:)を使わずUNCパス(\\サーバー名\共有名\...)を直接指定することです。ドライブレターのマッピングをそもそも使わないので、Split Tokenの問題が発生しません。
@echo off rem 手動実行なら動くが、タスクスケジューラ(最高権限)では見えない copy "C:\data\result.csv" "Z:\reports\" >nul if %ERRORLEVEL% neq 0 echo [ERROR] コピー失敗
@echo off rem \\サーバー名\共有名 の形式で直接指定 copy "C:\data\result.csv" "\\fileserver\reports\" >nul if %ERRORLEVEL% neq 0 echo [ERROR] コピー失敗
@echo off
rem 認証が必要なサーバーはnet useで認証を通してからUNCパスで操作
net use "\\fileserver\reports" /user:domain\username "password" /PERSISTENT:NO >nul 2>&1
copy "C:\data\result.csv" "\\fileserver\reports\" >nul
if %ERRORLEVEL% equ 0 (
echo [OK] コピー成功
) else (
echo [ERROR] コピー失敗
net use "\\fileserver\reports" /delete /y >nul 2>&1
exit /b 1
)
net use "\\fileserver\reports" /delete /y >nul 2>&1
解決策②:タスク内でnet useを使ってドライブを明示的にマップ
どうしてもドライブレターが必要な場合(既存の処理がZ:前提になっている等)は、バッチの冒頭でタスク実行コンテキスト内に改めてドライブをマップします。
@echo off
setlocal
set "SERVER=\\fileserver\reports"
set "DRIVE=Z:"
set "USER=domain\username"
set "PASS=password"
rem 既存の接続を切断してから再接続
net use %DRIVE% /delete /y >nul 2>&1
net use %DRIVE% %SERVER% /user:%USER% %PASS% /PERSISTENT:NO
if %ERRORLEVEL% neq 0 (
echo [ERROR] ネットワークドライブのマップに失敗しました
exit /b 1
)
rem ここからドライブレターで操作できる
copy "C:\data\result.csv" "%DRIVE%\" >nul
if %ERRORLEVEL% equ 0 (
echo [OK] コピー成功
) else (
echo [ERROR] コピー失敗
)
rem 処理後は必ず切断
net use %DRIVE% /delete /y >nul 2>&1
解決策③:EnableLinkedConnectionsでドライブを共有する
EnableLinkedConnectionsとは
EnableLinkedConnectionsは、標準トークン(非昇格プロセス)でマップしたネットワークドライブを昇格トークン(管理者プロセス)からも見えるようにするWindowsのレジストリ設定です。Microsoftが公式に提供している解決策の一つです。
| 設定 | 値 | 効果 |
|---|---|---|
| 未設定(デフォルト) | (キーなし) | 標準トークン・昇格トークンのドライブマップが独立(問題の状態) |
| EnableLinkedConnections = 1 | DWORD: 1 | 両トークンでドライブマップを共有(再起動後に有効) |
レジストリの設定方法
@echo off
rem 管理者権限チェック
net session >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo [ERROR] 管理者として実行してください。
pause
exit /b 1
)
rem EnableLinkedConnections を有効化
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ^
/v EnableLinkedConnections /t REG_DWORD /d 1 /f
if %ERRORLEVEL% equ 0 (
echo [OK] EnableLinkedConnections を有効化しました。
echo [INFO] 設定を反映するには再起動が必要です。
) else (
echo [ERROR] レジストリの設定に失敗しました。
exit /b 1
)
@echo off rem 現在の設定を確認 reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLinkedConnections rem 無効化(削除)したい場合 rem reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLinkedConnections /f
EnableLinkedConnectionsの注意点
| 注意点 | 詳細 |
|---|---|
| 再起動が必要 | 設定後はWindowsを再起動するまで有効にならない |
| 全ユーザーに適用 | HKLM(マシン全体)の設定のため、全ユーザーに影響する |
| SYSTEMアカウントには効果なし | タスクを/RU SYSTEMで実行している場合は効果がない(解決策④で対処) |
| ドメイン環境での動作確認推奨 | グループポリシーで上書きされる場合がある |
| Windows 10/11での有効性 | 現行バージョンでも有効。ただしMicrosoftはUNCパスを推奨 |
解決策④:実行アカウントを変更してSplit Tokenを回避する
Split TokenはUACが有効な管理者アカウントで実行したときに発生します。タスクスケジューラの実行アカウントを変更することで根本的に回避できます。
方法A:専用の標準ユーザーアカウントで実行
ネットワーク共有にアクセスできる標準ユーザー(管理者グループに属さないアカウント)でタスクを実行すると、Split Tokenが発生しません。
@echo off
rem 専用の実行ユーザー(標準ユーザー)でタスクを登録
schtasks /create ^
/TN "NetworkAccessJob" ^
/TR "cmd /c cd /d C:\Scripts && netjob.bat >> C:\logs\netjob.log 2>&1" ^
/SC DAILY ^
/ST 02:00 ^
/RU "DOMAIN\taskuser" ^
/RP "password" ^
/F
rem 注意: パスワードは実際の値に変更してください
rem タスクユーザーはネットワーク共有への読み書き権限が必要
方法B:ネットワークサービスアカウントで実行
NT AUTHORITY\NETWORK SERVICEアカウントはネットワーク認証を持ちます(コンピューターアカウントで認証)。ただしドメイン環境でコンピューターアカウントに共有へのアクセス権が必要です。
schtasks /create ^
/TN "NetworkServiceJob" ^
/TR "cmd /c cd /d C:\Scripts && job.bat" ^
/SC DAILY ^
/ST 02:00 ^
/RU "NT AUTHORITY\NETWORK SERVICE" ^
/F
| 実行アカウント | ネットワーク接続 | Split Token | 推奨度 |
|---|---|---|---|
| SYSTEM | ×(ネットワーク認証なし) | なし | ネットワーク不要時のみ |
| NETWORK SERVICE | ○(コンピューター認証) | なし | ドメイン環境でよい選択 |
| 管理者ユーザー + 最高権限 | △(Split Token問題) | あり | 解決策①〜③と組み合わせ必要 |
| 標準ユーザー(専用アカウント) | ○(ユーザー認証) | なし | 最も安全・推奨 |
問題の診断方法
ステップ1:Split Tokenが原因か確認する
タスクスケジューラの「最高の特権で実行」を一時的に無効にして手動実行してみます。それでネットワーク共有にアクセスできるなら、原因はSplit Tokenです。
ステップ2:実行コンテキストのドライブ一覧をログに出力する
@echo off set "LOG=C:\logs\debug_context.log" echo ===== 実行コンテキスト診断 %DATE% %TIME% ===== >> "%LOG%" echo [USER] >> "%LOG%" whoami >> "%LOG%" echo [WHOAMI /ALL] >> "%LOG%" whoami /all >> "%LOG%" echo [NET USE] >> "%LOG%" net use >> "%LOG%" echo [DRIVES] >> "%LOG%" wmic logicaldisk get DeviceID,DriveType,ProviderName 2>&1 >> "%LOG%" echo [ERRORLEVEL NET USE Z:] >> "%LOG%" dir Z:\ >nul 2>&1 echo ERRORLEVEL=%ERRORLEVEL% >> "%LOG%" echo ===== END ===== >> "%LOG%"
このスクリプトをタスクとして実行し、ログを確認します。net useの出力にZ:がなければSplit Tokenが原因です。
ステップ3:Windowsイベントログで詳細を確認する
@echo off
rem タスクスケジューラのイベントログから失敗イベントを取得
wevtutil qe "Microsoft-Windows-TaskScheduler/Operational" ^
/q:"*[System[EventID=101 or EventID=103]]" ^
/f:text /c:10 > C:\logs\task_errors.log
echo イベントログを C:\logs\task_errors.log に保存しました
実用テンプレート:ネットワーク共有アクセス付きタスク
UNCパス(推奨)とnet use(フォールバック)を組み合わせた堅牢なテンプレートです。
@echo off
setlocal
set "LOG=C:\logs\network_task.log"
set "SERVER_PATH=\\fileserver\reports"
set "NET_USER=domain\taskuser"
set "NET_PASS=password"
echo ===== 処理開始 %DATE% %TIME% ===== >> "%LOG%"
rem ネットワーク接続確認(ping)
ping -n 1 fileserver >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo [ERROR] サーバーに到達できません: fileserver >> "%LOG%"
exit /b 1
)
rem 認証(/PERSISTENT:NOで永続化しない)
net use "%SERVER_PATH%" /user:"%NET_USER%" "%NET_PASS%" /PERSISTENT:NO >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo [ERROR] ネットワーク認証に失敗しました >> "%LOG%"
exit /b 1
)
rem === メイン処理(UNCパスで直接操作)===
copy "C:\data\result_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.csv" "%SERVER_PATH%\" >nul
if %ERRORLEVEL% equ 0 (
echo [OK] ファイルコピー成功 >> "%LOG%"
) else (
echo [ERROR] ファイルコピー失敗 >> "%LOG%"
net use "%SERVER_PATH%" /delete /y >nul 2>&1
exit /b 1
)
rem 後処理
net use "%SERVER_PATH%" /delete /y >nul 2>&1
echo [OK] 処理完了 >> "%LOG%"
echo ===== 処理終了 %DATE% %TIME% ===== >> "%LOG%"
トラブルシューティングチェックリスト
| チェック項目 | 確認方法 | 対処法 |
|---|---|---|
| 「最高の特権で実行」の設定 | タスクプロパティ→全般タブで確認 | 不要なら無効にする |
| 実行アカウントの種類 | 診断スクリプトでwhoamiを実行 | SYSTEMなら④、管理者なら①〜③ |
| ドライブマップの状態 | 診断スクリプトでnet useを実行 | 見えなければ解決策②か① |
| EnableLinkedConnections設定 | reg queryコマンドで確認 | 必要なら解決策③を適用して再起動 |
| ファイアウォール・SMBポート(445) | telnet fileserver 445 か Test-NetConnection | ファイアウォールルールを確認 |
| 共有フォルダのアクセス権 | 実行ユーザーで手動アクセス確認 | 実行アカウントに読み書き権限を付与 |
| グループポリシーの干渉 | gpresult /h gp_report.html | GPOの設定を確認・IT部門に相談 |
関連記事
- 【bat】バッチファイルをタスクスケジューラで実行するとき動作が異なる原因と解決ガイド(作業ディレクトリ・環境変数の問題も含む総合解決ガイド)
- 【bat】バッチファイルで共有フォルダにアクセスする方法(net use・UNC・認証・エラー対処の詳細)
- 【bat】net useでネットワークドライブをマウント・管理する方法(接続確認・エラー処理・タスクスケジューラ対応)
- 【bat】バッチファイルでタスクスケジューラを自動登録・更新・削除する実践ガイド(schtasksでの実行アカウント設定方法)