ICACLS command in Windows

NTFS permissions control who can read, write, and execute files and folders on Windows. icacls is the command-line tool for viewing and modifying those permissions — without opening File Explorer, without clicking through security dialogs, and without needing a GUI session at all. It works on local paths and UNC shares, supports inheritance rules, and can save and restore complete permission sets across migrations.

Unlike the older cacls command it replaced, icacls handles the full ACL structure: explicit vs inherited permissions, deny entries, special permissions, and integrity levels. This article covers the patterns that come up in real admin work — reading permissions, granting and revoking access, resetting broken inheritance, and backing up ACLs before risky operations.


Quick answer

View current permissions on a folder:

icacls C:\SharedFolder

Grant a user read and execute access:

icacls C:\SharedFolder /grant "DOMAIN\username:(OI)(CI)(RX)"

What it does

icacls (Integrity Control Access Control Lists) reads and modifies the NTFS ACL on any file or folder. It replaces the deprecated cacls command and is available on all Windows versions from Vista and Server 2003 SP2 onward.

Basic syntax:

icacls name [/grant[:r] user:perm] [/deny user:perm] [/remove[:g|:d] user]
           [/inheritance:e|d|r] [/save file] [/restore file]
           [/reset] [/T] [/C] [/Q]

Key flags:

FlagPurpose
/grant user:permAdd permissions for a user (additive — keeps existing)
/grant:r user:permReplace existing permissions for that user
/deny user:permAdd explicit deny entry (overrides grant)
/remove userRemove all ACEs for a user
/remove:g userRemove only granted permissions for a user
/remove:d userRemove only deny entries for a user
/resetReset to inherited permissions only
/inheritance:eEnable inheritance
/inheritance:dDisable inheritance, keep existing ACEs
/inheritance:rDisable inheritance, remove inherited ACEs
/TApply recursively to all files and subfolders
/CContinue on errors (access denied, locked files)
/QSuppress success messages
/save fileSave ACLs to a file for later restore
/restore fileRestore ACLs from a saved file

Permission abbreviations used in icacls syntax:

AbbreviationMeaning
FFull control
MModify (read, write, execute, delete — but not change permissions)
RXRead and execute
RRead only
WWrite only
(OI)Object inherit — applies to files inside the folder
(CI)Container inherit — applies to subfolders
(NP)No propagate — does not inherit further down
(IO)Inherit only — applies to children but not the folder itself
Note: icacls requires administrator privileges to modify permissions on system folders or files owned by other accounts. Always run from an elevated command prompt when changing ACLs.

Practical examples

1. Read current permissions on a folder

The problem: A user reports they cannot access a shared folder. Before making any changes, you need to see exactly what permissions are currently set — who has access, what type, and whether any deny entries exist.

The solution: Run icacls with just the path. No additional flags needed for reading.

rem Display current ACL for a folder
icacls C:\SharedFolder

Example output:

C:\SharedFolder DOMAIN\AdminGroup:(OI)(CI)(F)
                DOMAIN\jsmith:(OI)(CI)(RX)
                BUILTIN\Users:(OI)(CI)(R)
                NT AUTHORITY\SYSTEM:(OI)(CI)(F)

Successfully processed 1 files; Failed processing 0 files

Reading the output: each line shows the principal name followed by inheritance flags in parentheses, then the permission abbreviation. Entries without (I) are explicit. Entries marked (I) are inherited from a parent folder.

2. Grant access to a user or group

The problem: A new team member or service account needs access to a folder. You need to add a permission entry without disturbing existing ACEs for other users.

The solution: Use /grant with inheritance flags. Always include (OI)(CI) when granting on a folder so the permission applies to both files and subfolders inside it, not just the folder object itself.

rem Grant read and execute to a domain user on a folder and all its contents
rem (OI) — object inherit: permission applies to files inside the folder
rem (CI) — container inherit: permission applies to subfolders
rem RX   — read and execute

icacls C:\SharedFolder /grant "DOMAIN\jsmith:(OI)(CI)(RX)"
rem Grant modify access to a domain group (read, write, execute, delete)
icacls C:\AppData /grant "DOMAIN\AppTeam:(OI)(CI)(M)"
Warning: /grant is additive — it adds a new ACE on top of any existing entry for that user. If the user already has an ACE and you want to replace it rather than stack permissions, use /grant:r instead. Running /grant twice creates two separate ACEs for the same user, which can produce confusing effective permission results.

3. Remove access for a user

The problem: An employee has left or changed roles. Their explicit permission entry needs to be removed from a folder — not just revoked via group membership, but the ACE itself cleared.

The solution: Use /remove to delete all ACEs for a specific user. Use /remove:g or /remove:d to target only grant or deny entries specifically.

rem Remove all permission entries for a user from a folder
icacls C:\SharedFolder /remove "DOMAIN\jsmith"
rem Remove only the deny entry for a user, keep any grant entries
icacls C:\SharedFolder /remove:d "DOMAIN\jsmith"
Note: /remove only removes explicit ACEs. If the user inherits access from a parent folder or group membership, /remove will not block that access. To fully block access for a user regardless of inheritance, combine removal with an explicit deny entry — but use deny entries carefully, as they override group-based grants.

4. Reset permissions recursively after a broken ACL

The problem: A folder tree has accumulated a mess of explicit permissions from manual changes over time — some inherited, some not, some for users who no longer exist. You need to wipe all explicit entries and restore clean inheritance from the parent.

The solution: /reset removes all explicit ACEs and re-enables inheritance. Combined with /T it applies recursively to every file and subfolder in the tree.

rem Reset all explicit permissions on a folder tree and restore inheritance
rem /reset — remove all explicit ACEs, enable inheritance from parent
rem /T     — apply recursively to all files and subfolders
rem /C     — continue on errors (locked files, access denied on individual items)

icacls C:\SharedFolder /reset /T /C
Common mistake: Running /reset /T on a folder where inheritance is intentionally broken at a lower level. Reset restores inheritance everywhere in the tree — including subfolders that had deliberate permission overrides. Always document what custom permissions exist before running a recursive reset.

5. Save and restore ACLs before a risky operation

The problem: You need to change permissions on a folder as part of a migration or restructuring, but you want a safety net — the ability to restore the exact original ACL if something goes wrong.

The solution: /save writes the current ACL to a file in a format that /restore can read back exactly. The save file is not human-readable but is a reliable backup.

rem Save current ACL of a folder tree to a backup file
rem /T — include ACLs for all files and subfolders in the save file

icacls C:\SharedFolder /save C:\bat\SharedFolder-acl-backup.txt /T
rem Restore ACLs from the backup file
rem Note: /restore targets the parent of the saved folder, not the folder itself

icacls C:\ /restore C:\bat\SharedFolder-acl-backup.txt
Warning: The /restore path is the parent of the folder whose ACLs were saved. If you saved ACLs from C:\SharedFolder, restore from C:\, not from C:\SharedFolder. This is a common source of confusion — the save file contains the relative path internally and needs the correct parent to reconstruct it.

Hidden gems

Deny entries always win — even over Full Control

An explicit deny entry in an ACL overrides any grant entry for the same user, including Full Control. This means a user can be a member of a group with Full Control on a folder and still be completely blocked if a deny entry exists for their account specifically. When troubleshooting unexpected access denials, always check for deny entries — they are easy to miss in the output because they appear alongside grants without obvious visual distinction.

Note: In icacls output, deny entries appear as (DENY) after the inheritance flags: DOMAIN\jsmith:(DENY)(RX). They do not have a separate section — they appear mixed with grant entries in the same list.

Use wildcards with /T for bulk file operations

You can pass a wildcard pattern to icacls to target multiple files at once. Combined with /T, this lets you grant or revoke permissions on all files matching a pattern across an entire folder tree without scripting a loop:

rem Grant read access to all .log files in a folder tree
icacls "C:\Logs\*.log" /grant "DOMAIN\LogReaders:(RX)" /T

takeown before icacls when access is denied

If icacls returns access denied even when running elevated — which happens when a file or folder is owned by an account that no longer exists, or has been locked down so completely that even administrators cannot modify it — use takeown first to take ownership, then apply permissions with icacls:

rem Take ownership of a folder, then restore admin access
rem Step 1: claim ownership as the current administrator
takeown /F C:\LockedFolder /R /D Y

rem Step 2: grant Full Control to the Administrators group
icacls C:\LockedFolder /grant "BUILTIN\Administrators:(OI)(CI)(F)" /T
Warning: Taking ownership and granting yourself Full Control on a folder that another account owns is an auditable action on domain-joined machines. On servers with security auditing enabled, this generates Event ID 4670 (permissions changed) and 4656 (object accessed with ownership taken). Use this only when operationally necessary.

PowerShell equivalent

PowerShell handles ACLs through Get-Acl and Set-Acl. The syntax is more verbose but returns proper objects and integrates cleanly with pipelines:

# View current ACL — equivalent to: icacls C:\SharedFolder
Get-Acl -Path "C:\SharedFolder" | Format-List
# Grant read and execute to a domain user
# Build the ACE object, then apply it
$acl = Get-Acl -Path "C:\SharedFolder"

$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "DOMAIN\jsmith",
    "ReadAndExecute",
    "ContainerInherit,ObjectInherit",
    "None",
    "Allow"
)

$acl.AddAccessRule($rule)
Set-Acl -Path "C:\SharedFolder" -AclObject $acl
Note: For one-off permission changes on a single machine, icacls is faster to type and easier to read. For scripted permission management across many machines or as part of a larger automation workflow, Get-Acl / Set-Acl integrates better with the rest of the PowerShell pipeline.

Where this matters

File server migrations — saving ACLs with /save before moving data, then restoring them on the destination to preserve all explicit permissions without manual re-entry.

Service account setup — granting a service account exactly the rights it needs on specific paths without adding it to broader groups that would give access beyond those paths.

Access troubleshooting in AD environments — checking for unexpected deny entries or stale SIDs from deleted accounts that are blocking access for current users.

Post-deployment permission hardening — locking down folders after application installation by removing default broad permissions and replacing them with explicit, scoped entries.

Inherited permission cleanup — resetting broken permission trees on shared folders that have accumulated contradictory explicit entries over years of manual changes.


Tips and limitations

  • icacls only manages NTFS permissions — not share permissions. A user blocked at the share level (via net share or Computer Management) cannot be fixed with icacls. Effective access through a UNC path is the more restrictive of NTFS and share permissions combined. When troubleshooting remote access issues, check both.
  • Stale SIDs appear as S-1-5-… entries. If an ACL contains entries like S-1-5-21-... instead of a username, that account no longer exists in the domain. These orphaned SIDs take up space in the ACL and can cause confusion. Remove them with icacls path /remove "S-1-5-21-xxxx-xxxx-xxxx-xxxx".
  • /T on large folder trees is slow. Running a recursive icacls /T on a folder with millions of files can take hours. Use /C to continue past locked files and consider running during off-hours for large migrations.
  • icacls does not handle share-level permissions. For share permissions, use net share or Computer Management. For the combination of both, use PowerShell with Get-SmbShareAccess.
  • Output encoding on non-English systems. On machines with non-ASCII usernames or folder names, icacls output can have encoding issues when redirected to a file. Use icacls ... | Out-File -Encoding UTF8 from PowerShell when you need reliable text output on such systems.

Official documentation

Related guides