【bat】バッチファイルの「アクセスが拒否されました」エラー完全解決ガイド|原因別対策・管理者権限・ACL・ファイルロック・実践パターンまで

【bat】バッチファイルの「アクセスが拒否されました」エラーの解決方法 bat

バッチファイルで「アクセスが拒否されました(Access is denied.)」が出たとき、原因はひとつではありません。管理者権限の不足・ACL設定ミス・他プロセスによるファイルロック・読み取り専用属性・保護フォルダへの書き込みなど、様々な原因が考えられます。

この記事では原因別に対策を体系的に解説し、バッチファイル内でエラーを適切にハンドリングする実践パターンまで紹介します。

この記事でわかること

  • 「アクセスが拒否されました」が発生する8つの原因と見分け方
  • 管理者権限での実行方法(右クリック・スクリプト自己昇格)
  • icacls でファイル・フォルダの権限(ACL)を修正する方法
  • ファイルロックの確認と解除(taskkill・待機)
  • 読み取り専用属性の解除(attrib)
  • 保護フォルダへの書き込み回避策
  • ERRORLEVEL を使ったエラーハンドリングとリトライ
  • 落とし穴5選・実践例3本・FAQ6問
スポンサーリンク
  1. 1. 原因別早見表
  2. 2. 管理者権限の不足が原因の場合
    1. 2-1. 手動で管理者として実行する
    2. 2-2. バッチ自身が管理者権限で動いているか確認する
    3. 2-3. バッチが自動的に管理者権限を要求する(UAC昇格)
  3. 3. ACL(アクセス権限)不足が原因の場合
    1. 3-1. icacls で現在の権限を確認する
    2. 3-2. icacls で権限を付与する
    3. 3-3. 一時的に権限を取得してから元に戻す
  4. 4. ファイルロックが原因の場合
    1. 4-1. ロックしているプロセスを確認する
    2. 4-2. プロセスを終了してからファイル操作する
    3. 4-3. リトライループで待機する
  5. 5. 読み取り専用属性が原因の場合
    1. 5-1. 属性を確認する
    2. 5-2. 読み取り専用属性を解除してから操作する
  6. 6. 保護フォルダへの書き込みが原因の場合
    1. 6-1. 一時フォルダや AppData を使う
    2. 6-2. rd でフォルダ削除できないとき
  7. 7. ネットワーク共有フォルダが原因の場合
  8. 8. パス・文字列の問題が原因の場合
  9. 9. タスクスケジューラから実行したときだけ失敗する場合
  10. 10. ERRORLEVEL によるエラーハンドリングとリトライ
  11. 11. 落とし穴5選と対策
    1. 落とし穴1:net session で管理者チェックするとドメイン環境でFalseになることがある
    2. 落とし穴2:icacls のパスに末尾の \ を付けるとエラーになる
    3. 落とし穴3:rd /s /q でも「アクセスが拒否されました」が出る場合
    4. 落とし穴4:UAC昇格後にカレントディレクトリが変わる
    5. 落とし穴5:エラーメッセージが英語(”Access is denied.”)で出る場合
  12. 12. 実践例3本
    1. 実践例1:管理者権限チェック付き一括ファイルコピースクリプト
    2. 実践例2:ファイル削除リトライ付き安全削除スクリプト
    3. 実践例3:アクセス権診断スクリプト
  13. 13. まとめ:原因別対策早見表
  14. FAQ

1. 原因別早見表

まず「どの操作をしたときにエラーが出るか」で原因を絞り込みましょう。

操作・状況 主な原因 対策セクション
レジストリ操作・サービス起停止・システムフォルダへの書き込み 管理者権限の不足 → 2節
特定フォルダへのコピー・削除ができない ACL(アクセス制御リスト)の設定不足 → 3節
使用中のファイルを削除・上書きできない 他プロセスによるファイルロック → 4節
ファイルを編集・削除できない 読み取り専用属性が設定されている → 5節
C:\Windows や C:\Program Files への書き込みが失敗 保護フォルダへの直接書き込み → 6節
ネットワーク共有フォルダへの操作が失敗 ネットワーク権限・認証の問題 → 7節
長いパスや日本語・特殊文字を含むパスで失敗 パス・文字列の問題 → 8節
タスクスケジューラから実行したときだけ失敗 実行ユーザー・権限の違い → 9節

2. 管理者権限の不足が原因の場合

もっとも多い原因です。レジストリ操作・Windowsサービスの起動停止・システムフォルダへの書き込みなど、管理者権限が必要な操作はバッチを「管理者として実行」しないと失敗します。

2-1. 手動で管理者として実行する

バッチファイルを右クリック → 「管理者として実行」で実行します。

2-2. バッチ自身が管理者権限で動いているか確認する

@echo off
:: 管理者権限チェック
net session >nul 2>&1
if errorlevel 1 (
    echo [ERROR] このスクリプトは管理者権限で実行してください
    echo 右クリック → 管理者として実行 を選んでください
    pause
    exit /b 1
)
echo [OK] 管理者権限で実行中です

2-3. バッチが自動的に管理者権限を要求する(UAC昇格)

詳細は バッチファイルで管理者権限を自動取得する方法管理者権限で自動実行するバッチファイルの作り方 を参照してください。

@echo off
:: 管理者権限チェック → なければ UAC 昇格して自己再実行
net session >nul 2>&1
if errorlevel 1 (
    echo 管理者権限が必要です。UAC プロンプトが表示されます...
    powershell -NoProfile -Command "Start-Process cmd -ArgumentList '/c "%~f0"' -Verb RunAs"
    exit /b
)

:: ここから本処理(管理者権限あり)
echo [OK] 管理者として実行しています
pause

3. ACL(アクセス権限)不足が原因の場合

ファイルやフォルダの NTFS アクセス制御リスト(ACL)で操作に必要な権限が与えられていない場合です。管理者権限が必要な処理が失敗するときの解決策 も参照してください。

3-1. icacls で現在の権限を確認する

:: 対象フォルダの権限を表示
icacls "C:\work\target"

:: 出力例:
:: C:\work\target BUILTIN\Administrators:(I)(OI)(CI)(F)
::                 NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
::                 BUILTIN\Users:(I)(OI)(CI)(RX)
::  ↑ Users はRX(読み取り・実行のみ)= 書き込みができない

3-2. icacls で権限を付与する

@echo off
:: 現在のユーザーにフルコントロールを付与
icacls "C:\work\target" /grant "%USERNAME%":(F) /t
if errorlevel 1 (
    echo [ERROR] 権限の変更に失敗しました(管理者権限が必要です)
    exit /b 1
)
echo [OK] フルコントロール権限を付与しました

:: 代表的な権限フラグ
:: (F) フルコントロール
:: (M) 変更(書き込み・削除可)
:: (RX) 読み取り・実行
:: (R) 読み取りのみ
:: /t サブフォルダ・ファイルにも再帰適用

3-3. 一時的に権限を取得してから元に戻す

@echo off
setlocal

set "TARGET=C:\work\protected_dir"

:: 権限を追加
icacls "%TARGET%" /grant "%USERNAME%":(F) /t >nul

:: 操作を実行
xcopy /e /y "C:\src\*" "%TARGET%\" >nul

:: 権限を元に戻す(付与した権限を削除)
icacls "%TARGET%" /remove "%USERNAME%" /t >nul
echo 処理完了(権限を元に戻しました)

4. ファイルロックが原因の場合

ほかのプロセスがファイルを開いている(ロックしている)と、削除・上書きができません。

4-1. ロックしているプロセスを確認する

:: tasklist でプロセス一覧を確認(特定のプロセス名を検索)
tasklist /fi "imagename eq notepad.exe"

:: 詳細なロック情報は Sysinternals の handle.exe が便利(別途インストール必要)
:: handle.exe "C:\work\locked_file.txt"

4-2. プロセスを終了してからファイル操作する

@echo off
setlocal

set "TARGET_FILE=C:\work\data.log"

:: notepad.exe が開いていれば強制終了
tasklist /fi "imagename eq notepad.exe" 2>nul | find "notepad.exe" >nul
if not errorlevel 1 (
    echo notepad.exe を終了します...
    taskkill /f /im notepad.exe >nul 2>&1
    timeout /t 2 /nobreak >nul
)

:: ファイル操作
del "%TARGET_FILE%" >nul 2>&1
if errorlevel 1 (
    echo [ERROR] ファイルを削除できません(まだロック中の可能性があります)
    exit /b 1
)
echo [OK] 削除しました

プロセス終了の詳細は プロセスの終了を待つ全方法まとめ も参照してください。

4-3. リトライループで待機する

プロセスがファイルを解放するのを待つ場合は、一定間隔でリトライします。

@echo off
setlocal

set "TARGET=C:\work\output.log"
set "MAX_RETRY=10"
set "WAIT_SEC=3"

:retry
del "%TARGET%" >nul 2>&1
if not errorlevel 1 (
    echo [OK] ファイルを削除しました
    exit /b 0
)

set /a MAX_RETRY-=1
if %MAX_RETRY% LEQ 0 (
    echo [ERROR] リトライ上限に達しました。ファイルがロックされています。
    exit /b 1
)
echo [WAIT] ファイルがロック中。%WAIT_SEC% 秒後にリトライします(残り %MAX_RETRY% 回)
timeout /t %WAIT_SEC% /nobreak >nul
goto :retry

5. 読み取り専用属性が原因の場合

ファイルに読み取り専用属性(readonly)が設定されていると、上書き・削除ができません。

5-1. 属性を確認する

:: attrib コマンドで属性を確認
attrib "C:\work\config.ini"

:: 出力例:
:: A  R   C:\work\config.ini
:: R = 読み取り専用(Read-only)が設定されている
:: A = アーカイブ属性

5-2. 読み取り専用属性を解除してから操作する

@echo off
setlocal

set "TARGET=C:\work\config.ini"

:: 読み取り専用属性を解除(-R)
attrib -r "%TARGET%"

:: 操作実行
del "%TARGET%" >nul 2>&1
if errorlevel 1 (
    echo [ERROR] 削除に失敗しました
    exit /b 1
)
echo [OK] 削除しました

:: フォルダ配下すべての読み取り専用を解除
attrib -r "C:\work\*" /s /d

ファイル削除の詳細は ファイルを削除する方法完全ガイドファイル削除で「アクセスが拒否されました」が出るときの対策 も参照してください。

6. 保護フォルダへの書き込みが原因の場合

C:\WindowsC:\Program FilesC:\ProgramData などの保護フォルダは、管理者権限があっても直接操作できないケースがあります。

6-1. 一時フォルダや AppData を使う

@echo off
setlocal

:: 保護フォルダへの書き込みはNG → %TEMP% や %APPDATA% を使う
set "WORK_DIR=%TEMP%\myapp_%RANDOM%"
mkdir "%WORK_DIR%"

:: 作業フォルダで処理
echo 設定内容 > "%WORK_DIR%\config.txt"

:: 完了後に作業フォルダを削除
rd /s /q "%WORK_DIR%"
echo 処理完了

6-2. rd でフォルダ削除できないとき

@echo off
:: 通常の rd で失敗する場合は robocopy で空フォルダと同期する方法
set "TARGET=C:\work\stuck_folder"

:: 空フォルダを作成して robocopy でミラーリング(実質フォルダを空にする)
set "EMPTY=%TEMP%\empty_%RANDOM%"
mkdir "%EMPTY%"
robocopy "%EMPTY%" "%TARGET%" /mir >nul
rd /s /q "%EMPTY%"
rd /s /q "%TARGET%"
echo [OK] フォルダを削除しました

フォルダ削除の詳細は バッチファイルでフォルダを削除する方法 も参照してください。

7. ネットワーク共有フォルダが原因の場合

@echo off
setlocal

set "SHARE=\\server\share"

:: 共有フォルダへの接続確認
net use "%SHARE%" >nul 2>&1
if errorlevel 1 (
    echo [INFO] 共有フォルダに接続します...
    net use "%SHARE%" /user:DOMAIN\username password >nul 2>&1
    if errorlevel 1 (
        echo [ERROR] 共有フォルダへの接続に失敗しました
        exit /b 1
    )
)

:: アクセス可能か確認してから操作
if not exist "%SHARE%\" (
    echo [ERROR] 共有フォルダが見つかりません
    exit /b 1
)

copy "C:\local\data.csv" "%SHARE%\data.csv" >nul
if errorlevel 1 (
    echo [ERROR] 共有フォルダへのコピーに失敗しました
    exit /b 1
)
echo [OK] コピー完了

8. パス・文字列の問題が原因の場合

スペースや特殊文字を含むパスは引用符で囲まないと「アクセスが拒否されました」と同様のエラーになります。パスにスペースが含まれているとエラーになるときの解決策 も参照してください。

:: NG: スペースを含むパスを引用符なしで使う
copy C:\my folder\file.txt D:\output\
:: → "my" を別のコマンド引数として解釈してアクセス拒否

:: OK: 必ず引用符で囲む
copy "C:\my folder\file.txt" "D:\output\"

:: NG: 変数に格納したパスも引用符が必要
set SRC=C:\my folder\file.txt
copy %SRC% "D:\output\"

:: OK: 変数展開も引用符で保護
set "SRC=C:\my folder\file.txt"
copy "%SRC%" "D:\output\"

9. タスクスケジューラから実行したときだけ失敗する場合

タスクスケジューラのタスク設定で実行ユーザーが違う、または「最上位の特権で実行する」にチェックが入っていないことが原因です。

:: タスクスケジューラで管理者権限が必要なタスクを登録する場合
:: schtasks コマンドで /RL HIGHEST (最上位権限)を指定
schtasks /create /tn "MyAdminTask" /tr "cmd /c C:\work\admin_task.bat" /sc daily /st 08:00 /ru SYSTEM /rl highest

:: または既存タスクの実行レベルを変更
schtasks /change /tn "MyTask" /ru SYSTEM /rl highest

詳細は 管理者権限で自動実行するバッチファイルの作り方 を参照してください。

10. ERRORLEVEL によるエラーハンドリングとリトライ

アクセス拒否エラーを検知して適切にハンドリングするパターンです。ERRORLEVELを使ったエラーハンドリング も参照してください。

@echo off
setlocal

set "SRC=C:\work\source"
set "DST=D:\backup\dest"

:: 事前チェック
if not exist "%SRC%\" (
    echo [ERROR] コピー元が見つかりません: %SRC%
    exit /b 1
)

:: 読み取り専用を解除してからコピー
attrib -r "%SRC%\*" /s >nul 2>&1

:: 出力先を作成
if not exist "%DST%\" mkdir "%DST%"

:: コピー実行
xcopy /e /y "%SRC%\*" "%DST%\" >nul 2>&1
if errorlevel 1 (
    echo [ERROR] コピーに失敗しました(errorlevel=%ERRORLEVEL%)
    echo 考えられる原因:
    echo   1. 出力先への書き込み権限がない → icacls で確認
    echo   2. ファイルがロック中          → 使用中のアプリを終了
    echo   3. 管理者権限が必要            → 管理者として再実行
    exit /b 1
)
echo [OK] コピー完了: %DST%

11. 落とし穴5選と対策

落とし穴1:net session で管理者チェックするとドメイン環境でFalseになることがある

:: net session はドメイン環境や特定の構成で正しく動作しない場合がある
net session >nul 2>&1

:: より確実な方法: fltMC.exe を使って権限確認
fltMC >nul 2>&1
if errorlevel 1 (
    echo 管理者権限がありません
) else (
    echo 管理者権限があります
)

落とし穴2:icacls のパスに末尾の \ を付けるとエラーになる

:: NG: フォルダパスに末尾の \ を付けると構文エラー
icacls "C:\work\target\" /grant Users:(F)

:: OK: 末尾の \ を付けない
icacls "C:\work\target" /grant Users:(F)

落とし穴3:rd /s /q でも「アクセスが拒否されました」が出る場合

:: 原因: フォルダ内に読み取り専用・ロック中のファイルが存在する
:: 対策1: attrib で読み取り専用をすべて解除してから rd
attrib -r -s "C:\work\target\*" /s /d
rd /s /q "C:\work\target"

:: 対策2: takeown でフォルダの所有権を取得してから削除
takeown /f "C:\work\target" /r /d y >nul
icacls "C:\work\target" /grant "%USERNAME%":(F) /t >nul
rd /s /q "C:\work\target"

落とし穴4:UAC昇格後にカレントディレクトリが変わる

:: UAC昇格(powershell Start-Process RunAs)後は
:: カレントディレクトリが C:\Windows\System32 になることがある
:: 対策: バッチのパスを %~dp0 で保存して明示的に使う

@echo off
:: バッチのあるフォルダに移動
cd /d "%~dp0"

net session >nul 2>&1
if errorlevel 1 (
    powershell -NoProfile -Command "Start-Process cmd -ArgumentList '/c cd /d "%~dp0" && "%~f0"' -Verb RunAs"
    exit /b
)

:: 管理者権限あり・%~dp0 にいる状態で処理
echo [OK] %CD%

落とし穴5:エラーメッセージが英語(”Access is denied.”)で出る場合

:: Windows の言語設定によってはエラーメッセージが英語で出る
:: find コマンドでメッセージ内容を判定するのは不安定
:: → ERRORLEVEL を使って判定するのが確実

copy "C:\work\test.txt" "C:\Windows\" >nul 2>&1
if errorlevel 1 (
    echo アクセス拒否またはコピー失敗(errorlevel=%ERRORLEVEL%)
)

:: NG: find でエラーメッセージを拾おうとするのは言語依存で不安定
:: copy ... 2>&1 | find "拒否" はロケールによって動かない

12. 実践例3本

実践例1:管理者権限チェック付き一括ファイルコピースクリプト

@echo off
setlocal enabledelayedexpansion

:: ── 管理者権限チェック ──
net session >nul 2>&1
if errorlevel 1 (
    echo 管理者権限が必要です。昇格します...
    powershell -NoProfile -Command "Start-Process cmd -ArgumentList '/c "%~f0"' -Verb RunAs"
    exit /b
)

set "SRC=C:\deploy\app"
set "DST=C:\Program Files\MyApp"
set "LOG=C:\work\deploy.log"

echo [%date% %time%] デプロイ開始 >> "%LOG%"

:: 宛先フォルダが存在しなければ作成
if not exist "%DST%\" mkdir "%DST%"

:: 読み取り専用属性を解除
attrib -r "%DST%\*" /s >nul 2>&1

:: コピー実行
xcopy /e /y "%SRC%\*" "%DST%\" >> "%LOG%" 2>&1
if errorlevel 1 (
    echo [ERROR] コピー失敗。ログ: %LOG%
    exit /b 1
)

echo [%date% %time%] デプロイ完了 >> "%LOG%"
echo [OK] %DST% にデプロイしました

実践例2:ファイル削除リトライ付き安全削除スクリプト

FOR ループ内から goto するとループが終了するため、サブルーチン(call)を使ってリトライを実装します。

@echo off
setlocal enabledelayedexpansion

set "TARGET_DIR=C:\work\logs"
set "MAX_RETRY=5"
set "WAIT_SEC=5"
set "DELETED=0"
set "FAILED=0"

:: FOR ループ内で goto するとループが終了するため call でサブルーチンを呼ぶ
for %%F in ("%TARGET_DIR%\*.log") do (
    call :delete_with_retry "%%F"
)

echo ===== 結果: 削除 !DELETED! 件 / 失敗 !FAILED! 件 =====
if !FAILED! GTR 0 exit /b 1
exit /b 0

:delete_with_retry
set "FILE=%~1"
set "RETRY=0"
:del_retry
del "%FILE%" >nul 2>&1
if !errorlevel!==0 (
    set /a DELETED+=1
    exit /b 0
)
set /a RETRY+=1
if !RETRY! LEQ %MAX_RETRY% (
    echo [WAIT] %~nx1 がロック中。%WAIT_SEC% 秒後にリトライ(!RETRY!/%MAX_RETRY%)
    timeout /t %WAIT_SEC% /nobreak >nul
    goto :del_retry
)
echo [ERROR] %~nx1 の削除失敗(ロック解除できず)
set /a FAILED+=1
exit /b 1

実践例3:アクセス権診断スクリプト

問題発生時の原因調査に使える診断スクリプトです。

@echo off
setlocal

set "TARGET=%~1"
if "%TARGET%"=="" (
    echo 使い方: %~nx0 診断対象パス
    exit /b 1
)

echo ===== アクセス権診断: %TARGET% =====

:: 1. 管理者権限チェック
net session >nul 2>&1
if errorlevel 1 ( echo [権限] 現在の実行: 一般ユーザー ) else ( echo [権限] 現在の実行: 管理者 )

:: 2. ファイル・フォルダ存在確認
if exist "%TARGET%" ( echo [存在] あり ) else ( echo [存在] なし & exit /b 1 )

:: 3. 属性確認
echo [属性]
attrib "%TARGET%"

:: 4. ACL確認
echo [ACL]
icacls "%TARGET%"

:: 5. 書き込みテスト
echo test > "%TARGET%\__access_test__.tmp" 2>nul
if errorlevel 1 (
    echo [書込] NG(書き込み権限がありません)
) else (
    del "%TARGET%\__access_test__.tmp" >nul
    echo [書込] OK
)

echo ===== 診断完了 =====

13. まとめ:原因別対策早見表

原因 確認コマンド 対策
管理者権限の不足 net session 管理者として実行・UAC昇格
ACL権限不足 icacls "パス" icacls /grant で権限付与
ファイルロック tasklist taskkill でプロセス終了・リトライ待機
読み取り専用属性 attrib "ファイル" attrib -r で属性解除
保護フォルダへの書き込み 対象パスを確認 %TEMP%%APPDATA% を使う
ネットワーク権限 net use 認証・接続設定を確認
スペース・特殊文字 パスを確認 引用符で囲む・%~1 を使う
タスクスケジューラの権限設定 タスク設定を確認 /rl highest または SYSTEM ユーザーで実行

FAQ

Q. 管理者として実行しているのに「アクセスが拒否されました」が出ます。
A. 管理者権限があっても ACL でアクセスが拒否されている場合があります。icacls "対象パス" で権限を確認し、必要な権限((F) や (M))が付与されているか確認してください。また、UAC 昇格後にカレントディレクトリが変わっていないかも確認しましょう。
Q. del コマンドでファイルを削除しようとするとアクセス拒否されます。
A. ①ファイルに読み取り専用属性(attrib で確認)、②他のプロセスがロック中(tasklist で確認)、③権限不足(icacls で確認)のいずれかが原因です。ファイル削除で「アクセスが拒否されました」が出るときの対策も参照してください。
Q. icacls コマンドの権限フラグの意味がわかりません。
A. 主要なものは (F)=フルコントロール、(M)=変更(書き込み・削除可)、(RX)=読み取り・実行、(R)=読み取りのみ、(W)=書き込みのみ です。/t でサブフォルダへの再帰適用、/grant で権限追加、/remove で権限削除ができます。
Q. タスクスケジューラから実行したときだけ「アクセスが拒否されました」が出ます。
A. タスクスケジューラの実行ユーザーがログイン中のユーザーと異なる可能性があります。タスクのプロパティで「最上位の特権で実行する」にチェックを入れるか、実行ユーザーを SYSTEM に変更してください。また、ネットワークドライブのマウントはセッション依存のため、UNC パス(\\server\share)を直接使うことも有効です。
Q. robocopy でコピーしているとアクセス拒否のファイルがあってもスキップできますか?
A. robocopy はデフォルトでコピーできないファイルをスキップして継続します。/R:3 /W:5(3回リトライ・5秒待機)のオプションでリトライ動作を制御できます。ログ出力(/log:out.txt)でスキップしたファイルを記録することもできます。
Q. 所有者が別のユーザーのファイルを削除したいです。
A. takeown /f "ファイルパス" でファイルの所有権を取得し、icacls "ファイルパス" /grant "%USERNAME%":(F) でフルコントロール権限を付与してから削除します。管理者権限が必要です。