This comprehensive guide covers all aspects of NTFS permissions management using PowerShell.
Prerequisites
If you’re not familiar with NTFS permissions management, check out the NTFS Permissions Management Best Practice guide.
Setting File and Folder Permissions
To implement a least-privilege model (best practice for system security), IT specialists configure NTFS access control lists (ACLs) by adding access control entries (ACEs).
Listing Available Permissions
Find all available user permissions:
[system.enum]::getnames([System.Security.AccessControl.FileSystemRights])
Setting Permissions
The PowerShell Set-Acl cmdlet is used to change the security descriptor of a specified item.
Grant Full Control
$acl = Get-Acl \\fs1\shared\sales
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("ENTERPRISE\T.Simpson","FullControl","Allow")
$acl.SetAccessRule($AccessRule)
$acl | Set-Acl \\fs1\shared\sales
Note: SetAccessRule completely overwrites the permissions for a user or group.
Add Permissions (Without Overwriting)
$acl = Get-Acl \\fs1\shared\Accounting
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("ENTERPRISE\J.Carter","FullControl","Allow")
$acl.AddAccessRule($AccessRule)
$acl | Set-Acl \\fs1\shared\Accounting
Use AddAccessRule to add permissions without overwriting existing ones.
Permission Types Reference
Individual Permissions
| Access Right | PowerShell Name |
|---|---|
| Full Control | FullControl |
| Traverse Folder / Execute File | ExecuteFile |
| List Folder / Read Data | ReadData |
| Read Attributes | ReadAttributes |
| Read Extended Attributes | ReadExtendedAttributes |
| Create Files / Write Data | CreateFiles |
| Create Folders / Append Data | AppendData |
| Write Attributes | WriteAttributes |
| Write Extended Attributes | WriteExtendedAttributes |
| Delete Subfolders and Files | DeleteSubdirectoriesAndFiles |
| Delete | Delete |
| Read Permissions | ReadPermissions |
| Change Permissions | ChangePermissions |
| Take Ownership | TakeOwnership |
Permission Sets
| Access Rights Set | Rights Included | PowerShell Name |
|---|---|---|
| Read | List Folder/Read Data, Read Attributes, Read Extended Attributes, Read Permissions | Read |
| Write | Create Files/Write Data, Create Folders/Append Data, Write Attributes, Write Extended Attributes | Write |
| Read and Execute | Traverse folder/Execute File, List Folder/Read Data, Read Attributes, Read Extended Attributes, Read Permissions | ReadAndExecute |
| Modify | All of above + Delete | Modify |
Copying Permissions
To copy permissions, a user must own both the source and target folders:
get-acl \\fs1\shared\accounting | Set-Acl \\fs1\shared\sales
Exporting Permissions to CSV
For a detailed guide on exporting NTFS permissions to CSV, see this how-to.
Removing User Permissions
To remove permissions, use the RemoveAccessRule parameter.
Remove Specific Permission
Delete the “Allow FullControl” permission for T.Simpson:
$acl = Get-Acl \\fs1\shared\sales
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("ENTERPRISE\T.Simpson","FullControl","Allow")
$acl.RemoveAccessRule($AccessRule)
$acl | Set-Acl \\fs1\shared\sales
Note: RemoveAccessRule deletes only specific permissions.
Remove All Permissions for a User
To completely wipe T.Simpson’s permissions, use PurgeAccessRules:
$acl = Get-Acl \\fs1\shared\sales
$usersid = New-Object System.Security.Principal.Ntaccount ("ENTERPRISE\T.Simpson")
$acl.PurgeAccessRules($usersid)
$acl | Set-Acl \\fs1\shared\sales
Important Notes:
PurgeAccessRulesdoesn’t work with a string username; it works only with SIDs- We used the “Ntaccount” class to convert the user account name into a SID
PurgeAccessRulesworks only with explicit permissions; it does not purge inherited ones
Enabling and Disabling Permissions Inheritance
NTFS permissions can be either explicit or inherited. Inherited permissions are inherited from the parent folder.
Permission Hierarchy
- Explicit Deny
- Explicit Allow
- Inherited Deny
- Inherited Allow
Managing Inheritance
Use the SetAccessRuleProtection method, which has two parameters:
- First parameter: Blocks inheritance from parent folder (
$trueor$false) - Second parameter: Retains or removes current inherited permissions (
$trueor$false)
Disable Inheritance and Remove Inherited Permissions
$acl = Get-Acl \\fs1\shared\sales
$acl.SetAccessRuleProtection($true,$false)
$acl | Set-Acl \\fs1\shared\sales
All inherited permissions are removed; only explicit permissions remain.
Re-enable Inheritance
$acl = Get-Acl \\fs1\shared\sales
$acl.SetAccessRuleProtection($false,$true)
$acl | Set-Acl \\fs1\shared\sales
Changing File and Folder Ownership
To set an owner for a folder, use the SetOwner method.
Change Ownership
Make “ENTERPRISE\J.Carter” the owner of the “Sales” folder:
$acl = Get-Acl \\fs1\shared\sales
$object = New-Object System.Security.Principal.Ntaccount("ENTERPRISE\J.Carter")
$acl.SetOwner($object)
$acl | Set-Acl \\fs1\shared\sales
We used the Ntaccount class to convert the user account name from a string into a SID.
Requirements
The SetOwner method does not enable you to change the owner to any account you want; the account must have:
- “Take Ownership” right
- “Read” right
- “Change Permissions” right
Complete Examples
Example 1: Grant Modify Permission to a Group
$path = "\\fs1\shared\ProjectFiles"
$acl = Get-Acl $path
$permission = "DOMAIN\ProjectTeam","Modify","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.AddAccessRule($accessRule)
$acl | Set-Acl $path
Example 2: Remove All Permissions for a User and Set New Ones
$path = "\\fs1\shared\sales"
$user = "ENTERPRISE\J.Smith"
# Get current ACL
$acl = Get-Acl $path
# Remove all existing permissions for user
$usersid = New-Object System.Security.Principal.Ntaccount($user)
$acl.PurgeAccessRules($usersid)
# Add new ReadAndExecute permission
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($user,"ReadAndExecute","Allow")
$acl.AddAccessRule($AccessRule)
# Apply changes
$acl | Set-Acl $path
Example 3: Disable Inheritance and Set Explicit Permissions
$path = "\\fs1\shared\Confidential"
# Get ACL
$acl = Get-Acl $path
# Disable inheritance, keep existing permissions
$acl.SetAccessRuleProtection($true,$true)
# Remove all non-admin access
Get-ADUser -Filter * | ForEach-Object {
$usersid = New-Object System.Security.Principal.Ntaccount("DOMAIN\$($_.SamAccountName)")
$acl.PurgeAccessRules($usersid)
}
# Add admin full control
$adminRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators","FullControl","Allow")
$acl.AddAccessRule($adminRule)
# Apply
$acl | Set-Acl $path
Example 4: Bulk Permission Assignment from CSV
path,user,permission,type
\\fs1\shared\HR,DOMAIN\HRTeam,Modify,Allow
\\fs1\shared\Finance,DOMAIN\FinanceTeam,FullControl,Allow
\\fs1\shared\IT,DOMAIN\ITTeam,Modify,Allow
$permissions = Import-Csv "C:\permissions.csv"
foreach ($perm in $permissions) {
$acl = Get-Acl $perm.path
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$perm.user,
$perm.permission,
$perm.type
)
$acl.AddAccessRule($accessRule)
$acl | Set-Acl $perm.path
Write-Host "Applied $($perm.permission) for $($perm.user) on $($perm.path)"
}
Best Practices
- Test First: Use a test folder before applying to production
- Backup: Export current permissions before making changes
Get-Acl \\fs1\shared\sales | Export-Clixml C:\backups\sales-acl.xml - Use Groups: Assign permissions to groups, not individual users
- Least Privilege: Grant only the minimum permissions needed
- Document: Keep records of permission changes
- Audit: Regularly review permissions
- Inheritance: Use inheritance when possible for easier management
Troubleshooting
Common Issues
“Access Denied”
- Solution: Run PowerShell as Administrator
- Ensure you have “Change Permissions” right on the folder
“Cannot find path”
- Solution: Verify path exists with
Test-Path - Use UNC paths for remote shares
Changes Don’t Apply
- Solution: Check if Group Policy is overriding settings
- Verify inheritance settings
Viewing Current Permissions
# View permissions in readable format
$acl = Get-Acl "\\fs1\shared\sales"
$acl.Access | Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited -AutoSize