Here is a set of simple functions for basic management of directory permissions or Access Control Lists.
when setting up file shares I tend to it in very few unique steps. Break inheritance while keeping ACLs, Add/Remove/Modify users or groups. So I have 4 powershell functions to simply complete these tasks.
function acl-Disableinheritance
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)] [ValidateScript({test-path $_})][string]$PathName
)
# get ACLs
$FolderACL = Get-Acl $PathName
# protect the acls from inheritace (break inheritace) , allow ACLs to inherit down.
$FolderACL.SetAccessRuleProtection($true,$true)
# write new ACL object back to directory
Set-Acl $PathName -AclObject $FolderACL
if ($?)
{
return $true
}else{
return $false
}
}
function acl-RemoveItem
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)] [ValidateScript({test-path $_})][string]$PathName,
[Parameter(Mandatory = $true)] [string]$UserOrGroup
)
# get ACLs
$FolderACL = Get-Acl $PathName
# loop through each User (or Group) called access rules and make $AccessRuleToDelete the the rule to delate.
foreach ($AccessRule in $FolderACL.access)
{
if ($AccessRule.IdentityReference -eq $UserOrGroup)
{
$AccessRuleToDelete = $AccessRule
}
}
# check the rule to delete exists
if ($AccessRuleToDelete)
{
# remove the access rule from the directory ACL object
$FolderACL.RemoveAccessRule($AccessRuleToDelete)
# write new ACL object back to directory
Set-Acl $PathName -AclObject $FolderACL
return $true
}else{
write-host "$UserOrGroup not found" -ForegroundColor Red
return $false
}
}
function acl-AddItem
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)] [ValidateScript({test-path $_})][string]$PathName,
[Parameter(Mandatory = $true)] [string]$UserOrGroup,
[Parameter(Mandatory = $true)] [ValidateSet("FullControl","Modify","ReadAndExecute")][string]$Permission
)
# get ACLs
$FolderACL = Get-Acl $PathName
# create new access rule object
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($UserOrGroup,$Permission,'ContainerInherit,ObjectInherit','None','Allow')
# add new access rule object to the directory ACL object
$FolderACL.SetAccessRule($AccessRule)
if ($?)
{
# write new ACL object back to directory
Set-Acl $PathName -AclObject $FolderACL
if ($?){return $true}
}else{
Write-Host "User or Group $UserOrGroup not found!" -ForegroundColor Red
return $false
}
}
function acl-getItem
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)] [ValidateScript({test-path $_})][string]$PathName,
[switch]$ShowSync
)
# get ACLs
$FolderACL = Get-Acl $PathName
$Result = @()
# loop though each access rule and make a nice simple array
foreach ($AccessRule in $FolderACL.access)
{
$tmpObj = '' | select UserOrGroup , Permission , IsInherited
$tmpObj.UserOrGroup = $AccessRule.IdentityReference
if ($ShowSync)
{
$tmpObj.Permission = $AccessRule.FileSystemRights
}else{
# remove the Synchronize ACL from the list as its normaly hidden.
[string]$RawPerm = $AccessRule.FileSystemRights
$PermArray = $RawPerm.Split(',')
$NewPermArray = $PermArray | where {$_ -notmatch "Synchronize"}
$tmpObj.Permission = $NewPermArray
}
$tmpObj.IsInherited = $AccessRule.IsInherited
$Result += $tmpObj
}
if ($Result)
{
return $Result
}else{
return $null
}
}
Put those functions at the start of your program and you will have the following functions
- acl-Disableinheritance [Path] Will disable inheritance and copy the ACLs.
- acl-RemoveItem -PathName [path] -UserOrGroup [user] will remove the user or group permission from the directory.
- acl-AddItem -PathName [path] -UserOrGroup [user] -Permission Modify|ReadAndExecute|FullControl will create or modify a user or group ACL.
- acl-getItem -PathName [path] will return a simple list of ACLs
To keep these functions simple, there is no ownership function or any way to set granular permissions or set denys.
The functions will return $true if successful (with the exception of acl-getItem that will return an array) and $false if the function fails.
To quickly permission up a simple shared file store with the following directory structure.
\nas01\cifs
\nas01\cifs\sales
\nas01\cifs\marketing
\nas01\cifs\IT
I would call the functions as follows.
acl-RemoveItem -PathName "\\nas01\cifs" -UserOrGroup "Everyone"
acl-Disableinheritance -PathName "\\nas01\cifs\sales"
acl-AddItem -PathName "\\nas01\cifs\sales" -UserOrGroup "domain\ACL-Sales-R" -Permission ReadAndExecute
acl-AddItem -PathName "\\nas01\cifs\sales" -UserOrGroup "domain\ACL-Sales-RW" -Permission Modify
acl-Disableinheritance -PathName "\\nas01\cifs\marketing"
acl-AddItem -PathName "\\nas01\cifs\marketing" -UserOrGroup "domain\ACL-marketing-R" -Permission ReadAndExecute
acl-AddItem -PathName "\\nas01\cifs\marketing" -UserOrGroup "domain\ACL-marketing-RW" -Permission Modify
acl-Disableinheritance -PathName "\\nas01\cifs\IT"
acl-AddItem -PathName "\\nas01\cifs\IT" -UserOrGroup "domain\ACL-IT-R" -Permission ReadAndExecute
acl-AddItem -PathName "\\nas01\cifs\IT" -UserOrGroup "domain\ACL-IT-RW" -Permission Modify
acl-AddItem -PathName "\\nas01\cifs\IT" -UserOrGroup "domain\ACL-IT-Admin" -Permission FullControl
There you go, a quick and easy way to apply ACLs.