We've all been there - inheriting a massive directory structure with broken NTFS permissions where someone went wild with the security settings. Random deny entries, incorrect ownership, and dangerous "Everyone" permissions scattered throughout the tree. When you need to completely reset permissions to a known good state across thousands of files and folders, manual fixes just won't cut it.
For Unix admins, this would be a simple chown -R
and chmod -R
operation. In Windows, we have two powerful tools:
# Command Line version using ICACLS
icacls "C:\ProblemFolder" /reset /T /C /Q
# PowerShell equivalent
Get-ChildItem "C:\ProblemFolder" -Recurse | ForEach-Object {
icacls $_.FullName /reset /Q
}
The magic happens with ICACLS's /reset
parameter which:
- Removes all explicit permissions
- Sets inherited permissions from parent
- Preserves the SYSTEM account permissions
If you're getting "Access Denied" errors, you'll need to take ownership first:
takeown /F "C:\ProblemFolder" /R /A /D Y
icacls "C:\ProblemFolder" /grant:r Administrators:(OI)(CI)F /T
For more granular control than just resetting to inherited, you can define explicit permissions:
# Grant full control to Admin, modify to Users, read to Everyone
icacls "C:\SecureData" /inheritance:r /grant:r
"Administrators:(OI)(CI)F" /grant:r
"Users:(OI)(CI)M" /grant:r
"Everyone:(OI)(CI)R" /T
For production use, consider this robust function:
function Reset-NTFSPermissions {
param(
[string]$Path,
[string]$User = "$env:USERDOMAIN\$env:USERNAME",
[bool]$ResetInheritance = $true
)
$acl = Get-Acl $Path
if ($ResetInheritance) {
$acl.SetAccessRuleProtection($false, $true)
}
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$User, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
)
$acl.SetAccessRule($rule)
Set-Acl -Path $Path -AclObject $acl
Get-ChildItem $Path -Recurse | ForEach-Object {
try {
$acl = Get-Acl $_.FullName
if ($ResetInheritance) {
$acl.SetAccessRuleProtection($false, $true)
}
$acl.SetAccessRule($rule)
Set-Acl -Path $_.FullName -AclObject $acl
} catch {
Write-Warning "Failed to process $($_.FullName): $_"
}
}
}
For system directories or stubborn objects:
- Use
/B
with takeown for backup privilege - Processes like
TrustedInstaller
may need special handling - Consider using
subinacl
for complex scenarios
Always verify permissions after bulk operations:
icacls "C:\TargetFolder" /save permfile.txt /T
notepad permfile.txt
We've all encountered those messy NTFS permission structures - inherited permissions broken, random ACEs assigned, or Everyone having write access to sensitive directories. When you inherit a system with a deep directory tree (like a migrated file server or legacy application), manually fixing permissions through the GUI becomes impossible.
Coming from Unix where chmod -R
and chown -R
solve permission problems elegantly, Windows administrators often miss equivalent tools. The key Windows utilities we'll use:
icacls - The modern replacement for cacls takeown - For ownership changes robocopy - For permission mirroring
For a complete permission rebuild (use with caution!):
takeown /F "C:\ProblemPath" /R /D Y icacls "C:\ProblemPath" /reset /T /C /Q icacls "C:\ProblemPath" /grant:r "DOMAIN\YourUser:(OI)(CI)F" /T /C /Q
This sequence:
- Takes ownership of everything
- Clears all existing permissions
- Grants full control to your account
For specific permission scenarios:
:: Remove all Everyone entries icacls "C:\Path" /remove:g Everyone /T /C :: Set read-only for Users group icacls "C:\Path" /grant:r "BUILTIN\Users:(OI)(CI)(RX)" /T :: Copy permissions from a known-good location robocopy "C:\GoodTemplate" "C:\ProblemPath" /E /COPYALL /SEC /SECFIX /MIR /XJ
To enable/disable inheritance:
:: Disable inheritance (copy existing permissions) icacls "C:\Path" /inheritance:d :: Re-enable inheritance (from parent) icacls "C:\Path" /inheritance:e
For consistent permission structures, save and apply templates:
:: Export permissions icacls "C:\TemplateFolder" /save "C:\perms.txt" /T /C :: Apply saved permissions icacls "C:\TargetFolder" /restore "C:\perms.txt"
For more granular control:
# Recursive permission reset Get-ChildItem -Path "C:\Path" -Recurse | ForEach-Object { $acl = Get-Acl $_.FullName $acl.SetAccessRuleProtection($true, $false) $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( "DOMAIN\User","FullControl","ContainerInherit,ObjectInherit","None","Allow") $acl.AddAccessRule($rule) Set-Acl -Path $_.FullName -AclObject $acl }
- Always test in non-production first
- System files may require TrustedInstaller permissions
- Watch for long path name issues (>260 chars)
- Consider creating a rollback script before mass changes