Windowsでファイルやフォルダに「誰が何をできるか」を制御するのがアクセス制御リスト(ACL)です。icaclsコマンドはそのACLを読み書きできるWindowsの標準ツールで、バッチファイルから権限を一括設定したり、設定をバックアップ・復元したりと幅広い場面で活躍します。
本記事ではicaclsの構文から実践的なバッチパターンまで、所有権取得(takeown)・SID指定・細粒度パーミッション・ACL監査まで含めて体系的に解説します。
icaclsとは
icacls(Integrity Control Access Control List)はWindows Vista以降に標準搭載されたACL管理コマンドです。旧来のcaclsコマンドは非推奨となっており、現在はicaclsが正式な後継として推奨されています。
Windowsのファイルシステム(NTFS)では、各ファイル・フォルダにDACL(任意アクセス制御リスト)が付与されており、ユーザーやグループごとに「読み取り」「書き込み」「実行」などの許可・拒否を細かく設定できます。ACLの中でアクセスを制御する各エントリをACE(アクセス制御エントリ)と呼びます。
基本構文
icacls <パス> [オプション] 主なオプション: /grant [ユーザー]:[アクセス権] アクセス権を付与(追加) /grant:r [ユーザー]:[アクセス権] アクセス権を付与(置換) /deny [ユーザー]:[アクセス権] アクセス権を拒否 /remove [ユーザー] ACLエントリを削除 /remove:g[ユーザー] 付与エントリのみ削除 /remove:d[ユーザー] 拒否エントリのみ削除 /reset 継承可能なACLをリセット /setowner[ユーザー] 所有者を変更 /T サブフォルダ・ファイルに再帰適用 /C エラーが出ても処理を続行 /L シンボリックリンク自体に適用 /Q ICACLSバナーを表示しない /save <ファイル> 現在のACLをファイルに保存 /restore <ファイル> 保存済みACLを復元 /inheritance:e/d/r 継承を有効化/無効化/削除 /findsid [SID] 指定SIDを含むACEを持つファイルを検索 /verify ACEのフォーマットを検証
アクセス権の確認
パスだけを指定するとそのファイル・フォルダのACLが表示されます。
@echo off :: 単一ファイルの確認 icacls "C:\data\report.txt" :: フォルダとサブフォルダをすべて確認 icacls "C:\data" /T :: バナーなしで確認(スクリプト向け) icacls "C:\data\report.txt" /Q :: 結果をファイルに保存 icacls "C:\data" /T /Q > C:\logs\acl_check.txt
出力例を見てみましょう。
C:\data\report.txt NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Administrators:(I)(F) BUILTIN\Users:(I)(RX) DOMAIN\yamada:(I)(M) Successfully processed 1 files; Failed processing 0 files
| 記号 | 意味 |
|---|---|
| (I) | 継承されたACE(親フォルダから受け継いだ設定) |
| (OI) | オブジェクト継承:フォルダ内のファイルに伝播 |
| (CI) | コンテナ継承:サブフォルダに伝播 |
| (IO) | 継承のみ:このオブジェクト自身には適用しない |
| (NP) | 継承を伝播しない |
アクセス権の付与
/grant と /grant:r の違い
/grantは既存のACEに追加するのに対し、/grant:rは同一ユーザーの付与エントリを置き換えます。スクリプトで冪等に設定したい場合は/grant:rを使うのが安全です。
@echo off :: ユーザーに読み取り・実行権限を付与(追加) icacls "C:\data" /grant "BUILTIN\Users":(RX) :: 同一ユーザーの付与エントリを置き換え(冪等) icacls "C:\data" /grant:r "DOMAIN\yamada":(M) :: サブフォルダ・ファイルにも再帰適用 icacls "C:\deploy" /grant:r "BUILTIN\Users":(RX) /T /C /Q :: NT AUTHORITY\SYSTEMにフルコントロールを付与 icacls "C:\logs" /grant:r "NT AUTHORITY\SYSTEM":(F) /T /C /Q
基本アクセス権マスク一覧
| 記号 | アクセス権 | 内容 |
|---|---|---|
| F | フルコントロール | すべての操作を許可 |
| M | 変更 | 読み取り・書き込み・削除(所有権変更・権限変更を除く) |
| RX | 読み取りと実行 | ファイルの読み取りとプログラムの実行 |
| R | 読み取り | ファイル・フォルダの内容を読み取る |
| W | 書き込み | ファイルの作成・上書き(削除は含まない) |
| D | 削除 | ファイル・フォルダの削除 |
特殊アクセス権(細粒度)の指定
括弧内にカンマ区切りで指定すると、より細かい権限を設定できます。
| 記号 | 意味 |
|---|---|
| RC | 読み取り権限(Read Control) |
| WDAC | DACLの変更(Write DAC) |
| WO | 所有者の変更(Write Owner) |
| S | 同期(Synchronize) |
| AS | アクセスシステムセキュリティ |
| MA | 最大許容(Maximum Allowed) |
| GR | 汎用読み取り(Generic Read) |
| GW | 汎用書き込み(Generic Write) |
| GE | 汎用実行(Generic Execute) |
| GA | 汎用すべて(Generic All) |
| RD | データ読み取り / ディレクトリのリスト |
| WD | データ書き込み / ファイル追加 |
| AD | データ追加 / サブディレクトリ追加 |
| REA | 拡張属性の読み取り |
| WEA | 拡張属性の書き込み |
| X | 実行 / トラバース |
| DC | 子の削除 |
| RA | 属性の読み取り |
| WA | 属性の書き込み |
@echo off :: 読み取り+実行のみ(書き込み不可・削除不可) icacls "C:\app" /grant:r "DOMAIN\AppUser":(RD,REA,RA,X,RC,S) /T /C /Q :: 書き込みのみ(読み取り不可のログ専用フォルダ) icacls "C:\log_drop" /grant:r "DOMAIN\LogWriter":(WD,AD,WEA,WA) /T /C /Q
アクセス権の拒否
/denyで明示的な拒否エントリを追加できます。拒否は付与より優先されるため、Administratorsグループのメンバーでも拒否エントリがあればアクセスできなくなります。使用は慎重に。
@echo off :: 特定ユーザーの書き込みを拒否 icacls "C:\readonly_data" /deny "DOMAIN\tanaka":(W) :: Guestsグループの全アクセスを拒否 icacls "C:\sensitive" /deny "BUILTIN\Guests":(F) /T /C /Q
/denyで自分自身(Administrators含む)を拒否すると、権限を取り戻すために所有権の取得が必要になる場合があります。テスト環境で動作確認してから本番に適用してください。アクセス権の削除
@echo off :: 特定ユーザーのACEを全削除(付与・拒否どちらも) icacls "C:\data" /remove "DOMAIN\tanaka" :: 付与エントリのみ削除(拒否エントリは残す) icacls "C:\data" /remove:g "DOMAIN\tanaka" :: 拒否エントリのみ削除(付与エントリは残す) icacls "C:\data" /remove:d "DOMAIN\tanaka" :: 複数ユーザーを一括削除(サブフォルダも再帰) icacls "C:\data" /remove "DOMAIN\OldUser1" /T /C /Q icacls "C:\data" /remove "DOMAIN\OldUser2" /T /C /Q
継承の制御
フォルダ上で/inheritanceオプションを使って継承設定を変更できます。
@echo off :: 継承を有効化(デフォルト) icacls "C:\data" /inheritance:e :: 継承を無効化(既存の継承ACEはコピーして保持) icacls "C:\data" /inheritance:d :: 継承を無効化し、かつ継承ACEを削除(明示的ACEのみ残す) icacls "C:\data" /inheritance:r :: サブフォルダ含めて継承を無効化 icacls "C:\data" /inheritance:d /T /C /Q
| オプション | 動作 |
|---|---|
| /inheritance:e | 継承を有効化(親フォルダのACEを適用) |
| /inheritance:d | 継承を無効化(既存の継承ACEはコピーして明示的ACEに変換) |
| /inheritance:r | 継承を無効化(継承ACEを削除。明示的ACEのみ残る) |
所有権の取得(takeown)と所有者変更
アクセス拒否エラーが解消できない場合、ファイルの所有権を取得してからACLを設定し直すのが効果的です。takeownコマンドとicacls /setownerを組み合わせて使います。
@echo off :: ステップ1: 所有権をAdministratorsに取得 takeown /f "C:\problem_folder" /r /d y :: ステップ2: Administratorsにフルコントロールを付与 icacls "C:\problem_folder" /grant:r "BUILTIN\Administrators":(F) /T /C /Q :: ---- または ---- :: icaclsで所有者を直接変更(Administratorsに) icacls "C:\problem_folder" /setowner "BUILTIN\Administrators" /T /C /Q echo 所有権取得・権限設定完了
/f パス:対象のファイル/フォルダ(ワイルドカード可)/r:サブフォルダを再帰処理/d y:確認プロンプトを自動でYesにする(バッチ向け)/a:Administratorsグループに所有権を付与(デフォルトは実行者)SIDを使ったユーザー指定
ドメイン移行後やアカウント名が変わった場合など、ユーザー名ではなくSID(セキュリティ識別子)でACEを指定・検索する方法があります。
@echo off :: ユーザーのSIDを確認する wmic useraccount where name="yamada" get sid :: --- 出力例 --- :: SID :: S-1-5-21-123456789-987654321-111111111-1001 :: SIDでACEを指定して権限付与 icacls "C:\data" /grant:r *S-1-5-21-123456789-987654321-111111111-1001:(M) :: 特定SIDを含むACEを持つファイルを検索 icacls "C:\data" /findsid S-1-5-21-123456789-987654321-111111111-1001 /T :: 旧アカウントSIDのACEを全削除(ドメイン移行後のクリーンアップ) icacls "C:\data" /remove *S-1-5-21-123456789-987654321-111111111-1001 /T /C /Q
- ドメイン移行後に旧SIDのACEを一括削除する
- アカウント名変更後も旧SIDが残っている場合のクリーンアップ
- 名前が解決できない「不明なアカウント」のACEを特定・削除する
ACLのリセット
/resetは明示的に設定されたACEを削除し、継承可能なACEのみ残す状態に戻します。誤った権限設定を元に戻すときに便利です。
@echo off :: フォルダのACLを継承のみの状態にリセット icacls "C:\data" /reset :: サブフォルダ・ファイルも再帰的にリセット icacls "C:\data" /reset /T /C /Q echo ACLリセット完了
ACLのバックアップと復元
運用変更前にACLをファイルに保存しておくと、問題が発生した際に素早く元の状態に戻せます。
@echo off
:: フォルダとサブフォルダのACLをファイルに保存
icacls "C:\data" /save "C:\backup\data_acl.txt" /T /C /Q
if %errorlevel% equ 0 (
echo ACLバックアップ完了: C:\backup\data_acl.txt
) else (
echo バックアップ失敗 (ERRORLEVEL=%errorlevel%)
)
@echo off :: 保存済みACLを復元 :: ※ /restore は /save で保存したフォルダの「親フォルダ」を指定する icacls "C:\" /restore "C:\backup\data_acl.txt" /C /Q echo ACL復元完了
/saveは対象フォルダの相対パスを保存します。/restoreには保存したフォルダの親フォルダを指定してください。例:
C:\dataを保存→復元時はicacls "C:\" /restore ...実践パターン
パターン1: 新規共有フォルダのアクセス権設定
部署ごとに読み書き権限を分けた共有フォルダを設定するバッチです。
@echo off setlocal set FOLDER=C:\shared\sales_data set DEPT_RW=DOMAIN\SalesTeam set DEPT_RO=DOMAIN\Managers set OWNER=BUILTIN\Administrators :: フォルダ作成(なければ) if not exist "%FOLDER%" mkdir "%FOLDER%" :: 現在のACLをバックアップ icacls "%FOLDER%" /save "%TEMP%\acl_backup.txt" /T /C /Q :: 継承を無効化し既存ACEをクリア(明示的ACEのみ削除) icacls "%FOLDER%" /inheritance:r /T /C /Q :: Administratorsにフルコントロール icacls "%FOLDER%" /grant:r "%OWNER%":(F) /T /C /Q :: 営業チームに読み書き(変更) icacls "%FOLDER%" /grant:r "%DEPT_RW%":(M) /T /C /Q :: 管理職に読み取りのみ icacls "%FOLDER%" /grant:r "%DEPT_RO%":(RX) /T /C /Q :: SYSTEMにフルコントロール(必須) icacls "%FOLDER%" /grant:r "NT AUTHORITY\SYSTEM":(F) /T /C /Q echo アクセス権設定完了 icacls "%FOLDER%"
パターン2: ユーザー追加・削除のテンプレート
@echo off
:: 使い方: manage_user_permission.bat [add|remove] [ユーザー名] [フォルダパス] [権限]
:: 例: manage_user_permission.bat add DOMAIN\yamada C:\data M
setlocal
set ACTION=%1
set USERNAME=%2
set FOLDER=%3
set PERM=%4
if "%ACTION%"=="" goto usage
if "%USERNAME%"=="" goto usage
if "%FOLDER%"=="" goto usage
if /i "%ACTION%"=="add" (
if "%PERM%"=="" set PERM=RX
icacls "%FOLDER%" /grant:r "%USERNAME%":(%PERM%) /T /C /Q
echo [追加] %USERNAME% -> %FOLDER% (%PERM%)
goto end
)
if /i "%ACTION%"=="remove" (
icacls "%FOLDER%" /remove "%USERNAME%" /T /C /Q
echo [削除] %USERNAME% -> %FOLDER%
goto end
)
:usage
echo 使い方: %0 [add^|remove] [ユーザー] [フォルダ] [権限(省略可)]
exit /b 1
:end
パターン3: 退職者・異動者の権限一括削除
@echo off
setlocal enabledelayedexpansion
:: 退職者リスト(users_to_remove.txt に1行1ユーザー)
set LIST=C:\admin\users_to_remove.txt
set TARGET=C:\shared
if not exist "%LIST%" (
echo リストファイルが見つかりません: %LIST%
exit /b 1
)
:: バックアップ
icacls "%TARGET%" /save "%TEMP%\acl_before_cleanup.txt" /T /C /Q
echo ACLバックアップ: %TEMP%\acl_before_cleanup.txt
:: ユーザーごとに削除
for /f "tokens=* delims=" %%u in ('type "%LIST%"') do (
echo 削除中: %%u
icacls "%TARGET%" /remove "%%u" /T /C /Q
if !errorlevel! equ 0 (
echo [OK] %%u の権限を削除しました
) else (
echo [警告] %%u の削除でエラー発生
)
)
echo 処理完了
パターン4: ACL監査ログ+前日差分アラート
重要フォルダのACLを定期的にファイルへ記録し、前日と差分があった場合にアラートを出すバッチです。schtasksコマンド完全ガイドと組み合わせて日次実行するのがおすすめです。
@echo off
setlocal enabledelayedexpansion
set LOG_DIR=C:\logs\acl_audit
set DATE_STR=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
:: 前日の日付を計算(PowerShell使用)
for /f %%d in ('powershell -NoProfile -Command "(Get-Date).AddDays(-1).ToString('yyyyMMdd')"') do set YESTERDAY=%%d
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
:: 監査対象フォルダ
set TARGETS[0]=C:\data
set TARGETS[1]=C:\shared
set TARGETS[2]=C:\deploy
for /L %%i in (0,1,2) do (
set FOLDER=!TARGETS[%%i]!
set SAFE=!FOLDER:\=_!
set TODAY_LOG=%LOG_DIR%\!SAFE!_%DATE_STR%.txt
set YESTERDAY_LOG=%LOG_DIR%\!SAFE!_%YESTERDAY%.txt
:: 今日のACLを保存
icacls "!FOLDER!" /T /Q > "!TODAY_LOG!" 2>&1
:: 前日ログがあれば差分チェック
if exist "!YESTERDAY_LOG!" (
fc /b "!YESTERDAY_LOG!" "!TODAY_LOG!" > nul 2>&1
if !errorlevel! neq 0 (
echo [警告] ACL変更検知: !FOLDER!
echo 差分: fc "!YESTERDAY_LOG!" "!TODAY_LOG!"
)
)
)
echo ACL監査完了
パターン5: ROBOCOPYコピー後のACL再設定
ROBOCOPYはデフォルトでACLをコピーしますが、コピー先のACLをあえてリセットして新規設定したいケースもあります。
@echo off setlocal set SRC=C:\source set DST=C:\destination :: /COPYALL でACLも含めてコピー(通常) robocopy "%SRC%" "%DST%" /E /COPYALL /R:3 /W:5 /LOG:"%TEMP%\robocopy.log" :: --- または --- :: /COPY:DAT でACLはコピーせず、コピー後にicaclsで設定 robocopy "%SRC%" "%DST%" /E /COPY:DAT /R:3 /W:5 :: コピー先のACLをリセットして親フォルダから継承させる icacls "%DST%" /reset /T /C /Q echo コピーおよびACLリセット完了
パターン6: 環境構築スクリプトのACL設定テンプレート
アプリケーション環境構築時に使える権限設定のテンプレートです。フォルダの役割に応じて最小権限を付与します。
@echo off
setlocal
set APP_DIR=C:\app\myapp
set LOG_DIR=%APP_DIR%\logs
set CONF_DIR=%APP_DIR%\config
set DATA_DIR=%APP_DIR%\data
set APP_USER=DOMAIN\AppServiceUser
:: フォルダ作成
for %%d in ("%APP_DIR%" "%LOG_DIR%" "%CONF_DIR%" "%DATA_DIR%") do (
if not exist %%d mkdir %%d
)
:: Administratorsにフルコントロール
icacls "%APP_DIR%" /grant:r "BUILTIN\Administrators":(F) /T /C /Q
icacls "%APP_DIR%" /grant:r "NT AUTHORITY\SYSTEM":(F) /T /C /Q
:: アプリユーザーの最小権限設定
:: - ルートは読み取りのみ
icacls "%APP_DIR%" /grant:r "%APP_USER%":(RX) /C /Q
:: - logsは書き込み可(読み取り不可)
icacls "%LOG_DIR%" /grant:r "%APP_USER%":(WD,AD,WEA,WA) /T /C /Q
:: - configは読み取りのみ
icacls "%CONF_DIR%" /grant:r "%APP_USER%":(RX) /T /C /Q
:: - dataは読み書き可(削除のみ不可)
icacls "%DATA_DIR%" /grant:r "%APP_USER%":(M) /T /C /Q
echo アプリACL設定完了
icacls "%APP_DIR%"
パターン7: ACLのエクスポートとインポート(サーバー移行)
サーバー移行時にACLも含めて移行したい場合のパターンです。
@echo off setlocal :: === 旧サーバー側: ACLをエクスポート === set EXPORT_DIR=C:\migration\acl_export if not exist "%EXPORT_DIR%" mkdir "%EXPORT_DIR%" icacls "C:\data" /save "%EXPORT_DIR%\data_acl.txt" /T /C /Q icacls "C:\shared" /save "%EXPORT_DIR%\shared_acl.txt" /T /C /Q echo エクスポート完了。%EXPORT_DIR% を新サーバーにコピーしてください。 :: === 新サーバー側: ACLをインポート === :: ※ 保存したファイルをCドライブ直下に転送し、以下を実行 rem icacls "C:\" /restore "%EXPORT_DIR%\data_acl.txt" /C /Q rem icacls "C:\" /restore "%EXPORT_DIR%\shared_acl.txt" /C /Q rem echo インポート完了
よくあるエラーと対処
| エラー内容 | 原因 | 対処 |
|---|---|---|
| アクセスが拒否されました | 管理者権限なし、または拒否ACEが存在 | 管理者権限でバッチを実行。管理者権限の自動取得も参照 |
| 指定されたファイルが見つかりません | パスが存在しない、スペースが含まれる | パスをダブルクォートで囲む。if existで事前確認 |
| 無効なパラメーターです | ユーザー名やアクセス権の書き方が誤っている | (RX)のように括弧で囲む。ユーザー名はドメイン\ユーザー形式で指定 |
| 所有者でないため変更できない | ファイルの所有者でなく、管理者権限もない | takeown /f パス /r /d yで所有権を取得してから再実行 |
| /restore が適用されない | /restore のパス指定が誤っている | /restore には「保存対象の親フォルダ」を指定する(保存対象そのものではない) |
| 一部ファイルのACL設定が失敗する | ファイルが別プロセスにロックされている | /Cで続行。エラーファイルを特定してプロセス終了後に再実行 |
ファイル・フォルダのアクセス権周りのエラーは原因が複数あります。アクセスが拒否されました エラーの完全解決ガイドやファイル削除でアクセスが拒否されたときの対処法も参考にしてください。
icacls・cacls・attribの違い
| コマンド | 目的 | ステータス |
|---|---|---|
| icacls | NTFSのDACL/SACLを管理(読み書き・バックアップ・復元) | 現行推奨 |
| cacls | icaclsの旧版。互換性のために残存 | 非推奨(使用禁止推奨) |
| attrib | ファイルの属性(読み取り専用・隠しファイル・システム)を管理 | 現行。ACLとは別物 |
attribはACLとは別の仕組みです。attrib +rで「読み取り専用」属性を付けても、Administrators権限があれば上書きできます。パスワード管理や権限制御にはicaclsを使ってください。
よくある質問
/Tはサブフォルダ・ファイルへの再帰適用、/Cはエラーが発生しても処理を続行するオプションです。大量のファイルに一括適用する場合、一部のファイルが別プロセスにロックされていてもエラーで止まらずに済むため、両方セットで指定するのが基本パターンです。コンピュータ名\ユーザー名と明示するのが確実です。BUILTIN\UsersやNT AUTHORITY\SYSTEMは特殊グループの指定方法です。コンピュータ名を省略してユーザー名だけでも認識されますが、同名ユーザーが複数存在する環境では明示的に指定してください。icacls パス /remove *SID文字列 /T /C /Qで削除できます。icacls パス /findsid SID文字列 /TでそのSIDを含むファイルを先に確認するのがおすすめです。/restoreが失敗します。編集後はicacls パス /verifyで検証してから適用することをおすすめします。まとめ
icaclsの主なポイントをおさらいします。
- ACLの確認は
icacls パス、再帰確認は/Tを追加 - 権限付与は
/grant(追加)または/grant:r(置換・冪等) - 権限削除は
/remove、リセットは/reset - 継承の無効化は
/inheritance:d、継承ACEごと削除は/inheritance:r - バックアップは
/save、復元は/restore(親フォルダを指定) - スクリプトで安全に使うなら
/T /C /Qの組み合わせが基本セット - アクセス拒否が解消できない場合は
takeownで所有権を取得してから設定 - ドメイン移行後の旧SID削除には
/findsid→/remove *SIDの流れで対処
権限設定はシステムの安定運用に直結します。変更前の/saveバックアップを習慣にして、問題が起きたときにすぐ/restoreできる体制を整えておきましょう。

