Windows ACL Management with PowerShell
Published: May 2, 2023 | Last Modified: May 13, 2025
Tags: windows powershell security permissions acl system-administration active-directory file-permissions
Categories: Windows PowerShell Security
Get ACL permissions
- The script retrieves the Access Control List (ACL) for a specified UNC path, resolving the Security Identifiers (SIDs) to their corresponding account names.
- It provides a plain-text description of the access rights (e.g., read or write) associated with each account.
- The output, including the SID, account name, and access rights, is saved to a CSV file for further analysis or reporting.
function Get-AccessDescription($AccessMask) {
$AccessRights = @()
if ($AccessMask -band 0x1) { $AccessRights += "ReadData (List Directory)" }
if ($AccessMask -band 0x2) { $AccessRights += "WriteData (Create Files)" }
if ($AccessMask -band 0x4) { $AccessRights += "AppendData (Create Folders)" }
if ($AccessMask -band 0x8) { $AccessRights += "ReadExtendedAttributes" }
if ($AccessMask -band 0x10) { $AccessRights += "WriteExtendedAttributes" }
if ($AccessMask -band 0x20) { $AccessRights += "ExecuteFile (Traverse Folder)" }
if ($AccessMask -band 0x40) { $AccessRights += "DeleteSubdirectoriesAndFiles" }
if ($AccessMask -band 0x80) { $AccessRights += "ReadAttributes" }
if ($AccessMask -band 0x100) { $AccessRights += "WriteAttributes" }
if ($AccessMask -band 0x10000) { $AccessRights += "Delete" }
if ($AccessMask -band 0x20000) { $AccessRights += "ReadControl" }
if ($AccessMask -band 0x40000) { $AccessRights += "WriteDACL" }
if ($AccessMask -band 0x80000) { $AccessRights += "WriteOwner" }
if ($AccessMask -band 0x100000) { $AccessRights += "Synchronize" }
return ($AccessRights -join ', ')
}
$Path = "\\server\share"
$OutputFile = "AccessList.csv"
$ACL = Get-Acl -Path $Path
$AccessList = @()
foreach ($ACE in $ACL.Access) {
try {
$Account = $ACE.IdentityReference.Value
$SID = (New-Object System.Security.Principal.NTAccount($Account)).Translate([System.Security.Principal.SecurityIdentifier]).Value
$AccessDescription = Get-AccessDescription $ACE.FileSystemRights
$AccessEntry = New-Object PSObject -Property @{
SID = $SID
AccountName = $Account
AccessRights = $AccessDescription
}
$AccessList += $AccessEntry
} catch {
$AccessEntry = New-Object PSObject -Property @{
SID = "Not found or not resolvable"
AccountName = "Not found or not resolvable"
AccessRights = "Not found or not resolvable"
}
$AccessList += $AccessEntry
}
}
$AccessList | Export-Csv -Path $OutputFile -NoTypeInformation
Set ACL permissions
Full Control
(Get-Acl -Path "\\server\share").AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("<SID>", "FullControl", "Allow"))) | Set-Acl -Path "\\server\share"
Modify
(Get-Acl -Path "\\server\share").AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("<SID>", "Modify", "Allow"))) | Set-Acl -Path "\\server\share"
Read & Execute
(Get-Acl -Path "\\server\share").AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("<SID>", "ReadAndExecute", "Allow"))) | Set-Acl -Path "\\server\share"
List Folder Contents
(Get-Acl -Path "\\server\share").AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("<SID>", "ListDirectory", "Allow"))) | Set-Acl -Path "\\server\share"
Read
(Get-Acl -Path "\\server\share").AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("<SID>", "Read", "Allow"))) | Set-Acl -Path "\\server\share"
Write
(Get-Acl -Path "\\server\share").AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("<SID>", "Write", "Allow"))) | Set-Acl -Path "\\server\share"