How to Completely Replace NTFS Permissions Using ICACLS on Windows Server (Full Reset with Examples)


2 views

When managing file permissions on Windows Server, administrators often need to completely reset access control lists (ACLs) rather than just adding new entries. The scenario described is common: You want to wipe all existing permissions and establish new ones from scratch, keeping only SYSTEM while adding specific user access.

The /grant:r switch in ICACLS replaces existing grants of the same type, but doesn't remove fundamentally different permission entries. Here's what's happening:

icacls C:\temp\test /grant:r DOMAIN\USER:(OI)(CI)F /t

This only replaces explicit grant entries, while built-in system permissions and inherited entries remain intact.

To achieve a true permission reset, we need to combine multiple ICACLS operations:

1. Clear All Existing Permissions

icacls C:\temp\test /reset /t

This removes all ACLs and resets to default inherited permissions.

2. Remove Inheritance (Optional but Recommended)

icacls C:\temp\test /inheritance:r

This breaks permission inheritance from parent folders.

3. Apply New Permissions

icacls C:\temp\test /grant:r "NT AUTHORITY\SYSTEM:(OI)(CI)F" "DOMAIN\USER:(OI)(CI)F" /t

Now we explicitly grant only the desired permissions.

For more complex scenarios, consider these patterns:

Preserving Creator Owner Rights

icacls C:\temp\test /grant:r "NT AUTHORITY\SYSTEM:(OI)(CI)F" 
"DOMAIN\USER:(OI)(CI)F" "CREATOR OWNER:(OI)(CI)(IO)F" /t

Batch Processing Multiple Folders

for /d %i in (C:\temp\*) do (
    icacls "%i" /reset /t
    icacls "%i" /inheritance:r
    icacls "%i" /grant:r "NT AUTHORITY\SYSTEM:(OI)(CI)F" "DOMAIN\USER:(OI)(CI)F"
)

Access Denied errors typically occur when:

  • Running without elevated privileges (Run as Administrator)
  • System files are involved (use takeown first)
  • Inheritance isn't properly disabled

Verification command:

icacls C:\temp\test /verify /t

When managing file system permissions on Windows Server, administrators often need to completely reset ACLs rather than just adding new entries. The scenario described is common:

  • Existing permissions include SYSTEM, Administrators, Users, and CREATOR OWNER
  • We want to keep only SYSTEM access
  • Add a specific domain user with full control
  • Apply these changes recursively to all subfolders and files

The /grant:r switch in ICACLS replaces only the explicit grants, but preserves:

1. Inherited permissions from parent folders
2. System-generated entries like CREATOR OWNER
3. Any deny entries in the ACL

To achieve a true permission reset, we need a two-step approach:

REM First, remove all permissions while preserving inheritance structure
icacls "C:\temp\test" /inheritance:r /t

REM Then apply the new desired permissions
icacls "C:\temp\test" /grant:r "NT AUTHORITY\SYSTEM:(OI)(CI)F" "DOMAIN\USER:(OI)(CI)F" /t
Parameter Purpose
/inheritance:r Disables inheritance and copies existing inherited permissions
/grant:r Replaces all explicit permissions with the specified ones
(OI)(CI) Object Inherit, Container Inherit flags for propagation
F Full control permission
/t Recursive operation through all subfolders

After running the commands, verify with:

icacls "C:\temp\test"

Common issues to check:

  • Ensure you're running Command Prompt as Administrator
  • Check for any explicit "Deny" entries that might persist
  • Verify the domain\username format is correct for your environment

If you need to keep certain permissions while removing others, use:

icacls "C:\temp\test" /remove:g "BUILTIN\Users" "CREATOR OWNER" /t

This granular approach allows selective permission removal before applying new grants.

For more control, consider this PowerShell equivalent:

$acl = Get-Acl "C:\temp\test"
$acl.SetAccessRuleProtection($true, $false) # Break inheritance, copy existing
$acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) } | Out-Null
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "DOMAIN\USER","FullControl","ContainerInherit,ObjectInherit","None","Allow")
$acl.AddAccessRule($rule)
Set-Acl "C:\temp\test" $acl -Recurse