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:
| Flag | Purpose |
|---|---|
/grant user:perm | Add permissions for a user (additive — keeps existing) |
/grant:r user:perm | Replace existing permissions for that user |
/deny user:perm | Add explicit deny entry (overrides grant) |
/remove user | Remove all ACEs for a user |
/remove:g user | Remove only granted permissions for a user |
/remove:d user | Remove only deny entries for a user |
/reset | Reset to inherited permissions only |
/inheritance:e | Enable inheritance |
/inheritance:d | Disable inheritance, keep existing ACEs |
/inheritance:r | Disable inheritance, remove inherited ACEs |
/T | Apply recursively to all files and subfolders |
/C | Continue on errors (access denied, locked files) |
/Q | Suppress success messages |
/save file | Save ACLs to a file for later restore |
/restore file | Restore ACLs from a saved file |
Permission abbreviations used in icacls syntax:
| Abbreviation | Meaning |
|---|---|
F | Full control |
M | Modify (read, write, execute, delete — but not change permissions) |
RX | Read and execute |
R | Read only |
W | Write 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 |
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)"
/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"
/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
/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
/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.
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
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
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 shareor Computer Management) cannot be fixed withicacls. 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 withicacls path /remove "S-1-5-21-xxxx-xxxx-xxxx-xxxx". - /T on large folder trees is slow. Running a recursive
icacls /Ton a folder with millions of files can take hours. Use/Cto 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 shareor Computer Management. For the combination of both, use PowerShell withGet-SmbShareAccess. - Output encoding on non-English systems. On machines with non-ASCII usernames or folder names,
icaclsoutput can have encoding issues when redirected to a file. Useicacls ... | Out-File -Encoding UTF8from PowerShell when you need reliable text output on such systems.
Official documentation
- icacls — Microsoft Learn — full parameter reference including special permission masks and integrity level syntax
Related guides
- ATTRIB command — manage file attributes (hidden, read-only, system) — a different layer of file control that works alongside NTFS permissions
- Fix trust relationship between workstation and domain — domain issues that can cause permission failures even when ACLs are correctly set
- DCDIAG — Active Directory troubleshooting — AD health checks relevant when stale SIDs or domain trust issues affect file access
- ROBOCOPY command — copy files with full ACL preservation using
/COPYALL, the natural partner to icacls for file migrations - Windows Command Line (CMD) Cheat Sheet — quick reference for CMD commands used alongside icacls in admin workflows