Command Line¶
The Security tab shows one object at a time. icacls and Get-Acl show many, and they're the only way to be sure a change took.
icacls¶
icacls "C:\Finance"
C:\Finance BUILTIN\Administrators:(OI)(CI)(F)
NT AUTHORITY\SYSTEM:(OI)(CI)(F)
CORP\Finance:(OI)(CI)(M)
BUILTIN\Users:(OI)(CI)(RX)
| Code | Meaning |
|---|---|
F |
Full control |
M |
Modify |
RX |
Read and execute |
R |
Read |
W |
Write |
(OI) |
Object inherit: files inside get this entry |
(CI) |
Container inherit: subfolders get this entry |
(I) |
This entry was itself inherited from the parent |
Check several folders at once:
icacls "C:\Windows\System32\drivers\etc"
icacls "C:\Program Files"
icacls "C:\Users\Public"
Change with icacls¶
icacls "C:\Finance" /remove:g "Everyone"
icacls "C:\Finance" /remove:g "Users"
icacls "C:\Finance" /grant:r "CORP\Finance:(OI)(CI)M"
icacls "C:\Finance" /inheritance:e
/remove:gremoves a group's Allow entry (/remove:dfor a Deny entry)./grant:rreplaces the group's existing entry rather than adding to it./inheritance:eenables inheritance;:ddisables it and converts;:rremoves inherited entries.- Add
/tto apply recursively.
Get-Acl¶
For one identity across a folder:
(Get-Acl "C:\Finance").Access | Where IdentityReference -like "*Users*" | Select IdentityReference, FileSystemRights, IsInherited
Find every folder under a path where Everyone has write:
Get-ChildItem C:\Finance -Recurse -Directory | ForEach-Object {
$acl = Get-Acl $_.FullName
$acl.Access | Where { $_.IdentityReference -eq "Everyone" -and $_.FileSystemRights -match "Write|Modify|FullControl" } | ForEach-Object { $_.FullName = $_.FullName; [PSCustomObject]@{Path=$_.FullName; Rights=$_.FileSystemRights} }
}
Verify¶
Run icacls on the folder after changing it. The output should match what you intended, entry for entry.
Example¶
icacls "C:\Windows\System32\drivers\etc" shows BUILTIN\Users:(OI)(CI)(M). Users can edit the hosts file and redirect any website. Fix: icacls "C:\Windows\System32\drivers\etc" /grant:r "BUILTIN\Users:(OI)(CI)RX" /t.