バッチファイルを手動実行すると共有フォルダや Z: ドライブにアクセスできるのに、タスクスケジューラ経由だと「パスが見つかりません」「アクセスが拒否されました」と失敗することがあります。
主な原因は、タスクの実行ユーザー、SYSTEM アカウント、「最高の特権で実行」によるUACの Split Token、ネットワークドライブのマップ先の違いです。この記事では、まず原因を切り分け、UNCパス、net use、実行アカウント変更、EnableLinkedConnections のどれを使うべきかを整理します。
- UACのSplit Tokenがなぜネットワークドライブを見えなくするのかの仕組み
- 解決策①:UNCパスを直接使う(最も確実で推奨)
- 解決策②:タスク内でnet useを使ってドライブを明示的にマップ
- 解決策③:EnableLinkedConnectionsレジストリでドライブ共有(要再起動)
- 解決策④:実行アカウントを変更してSplit Tokenを回避
- 問題の診断方法とトラブルシューティングチェックリスト
Z: などのドライブレターを使わず、\\server\share のUNCパスを直接指定することです。認証が必要ならタスク内で net use を実行し、SYSTEM 実行なら共有へアクセスできる実行ユーザーに変えるのが基本です。まず見る原因早見表
| 症状 | よくある原因 | 最初の対処 |
|---|---|---|
手動実行では Z: が見えるが、タスクでは見えない |
ユーザーごとのドライブマップ差、Split Token | Z: をやめてUNCパスへ変更 |
| 「最高の特権で実行」を付けると失敗する | 昇格トークン側にネットワークドライブがない | 最高権限を外す、またはUNCパスを使う |
SYSTEM で実行すると共有に入れない |
SYSTEMは通常のユーザー認証情報を持たない | 共有権限を持つ専用ユーザーで実行 |
| UNCパスでもアクセス拒否される | 実行ユーザーに共有権限/NTFS権限がない | 実行ユーザーを確認し、権限を付与 |
| 認証が必要な共有で失敗する | タスク実行時に資格情報が登録されていない | バッチ冒頭で net use する |
@echo off set "LOG=C:\logs\task-share-debug.log" echo ===== %DATE% %TIME% ===== >> "%LOG%" echo [whoami] >> "%LOG%" whoami >> "%LOG%" 2>&1 echo [net use] >> "%LOG%" net use >> "%LOG%" 2>&1 echo [check unc] >> "%LOG%" dir "\\fileserver\reports" >> "%LOG%" 2>&1 echo ERRORLEVEL=%ERRORLEVEL% >> "%LOG%"
目的別ショートカット
| 目的 | 読む場所 | 使う主な対処 |
|---|---|---|
| Zドライブをやめて安定させたい | UNCパスを直接使う | \\server\share |
| 既存処理がZドライブ前提で変えにくい | net useで明示的にマップ | net use Z: |
| 最高の特権で実行すると失敗する | EnableLinkedConnections | レジストリ設定、またはUNC移行 |
| SYSTEM実行で共有に入れない | 実行アカウントを変更 | 専用ユーザー/NETWORK SERVICE |
| 原因をログで切り分けたい | 問題の診断方法 | whoami / net use |
| そのまま使える形がほしい | 実用テンプレート | UNC + net use + ログ |
なぜタスクスケジューラからネットワーク共有にアクセスできないのか
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)の目的別記事一覧
- schtasksコマンドでタスクスケジューラを制御する方法
- net useでネットワークドライブを自動マウントする方法
- バッチファイルでログを出力する方法
- バッチファイルで管理者権限を自動取得する方法
よくある質問
Z: が、タスク実行時のユーザーや昇格トークンでは存在しないことがあります。まずは Z: を使わずUNCパスへ変更するのが最も安定します。SYSTEM はローカルPC上では強い権限を持ちますが、共有フォルダへアクセスするための通常ユーザーの認証情報を持ちません。共有にアクセスする処理は専用ユーザーで実行するのが基本です。Z: がタスク側では見えないことがあります。この場合はUNCパスへ変更するか、タスク内で net use してください。