patternshellMinor
Cleanly setting ACLs
Viewed 0 times
settingcleanlyacls
Problem
So this is my full script that I've been working on. My plan is to Create New, Folder, Create AD Group FS-TESTSHARE-R, Create AD Group FS-TESTSHARE-RW, Apply Both groups to the new share folder, Set Full Read permissions to FS-TESTSHARE-R, Set Full Read/Rights permissions to FS-TESTSHARE-RW, and Set full access permissions to Domain Admins and local Administrators.
I'm Pretty sure I have all of the syntax correct now (thanks to some awesome assistance I've received here), but I was hoping for some clarification on setting ACLs.
At the bottom I've redone how I was attempting to get, create, and set the ACLs Thanks to @themadtechnician), but I was curious as to if I've got all syntax correct or if I should create the set for each of the $objUser instead of putting them all in parentheses (is this the cleanest way to do this)...
```
$Parent = read-host -prompt "Enter full parent path that will contain the new folder (ie. \\eccofs01\Groups\ECCO IT\)"
$Name = read-host -prompt "Enter New Folder Name."
$Path = "$($parent)$($Name)"
$Location = read-host -prompt "Enter the AD Security Group Location (i.e. Global, Americas, Europe, Asia Pacific)"
Import-Module ActiveDirectory
#Create Security Groups
$GroupParams1= @{
'Name' = "FS-$NAME-RW"
'SamAccountName' = "FS-$NAME-RW"
'GroupCategory' = "Security"
'GroupScope' = "Global"
'DisplayName' = "$NAME Read-Write Access"
'Path' = "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
'Description' = "Members of this group have read-write access to $Path."
}
New-ADGroup @GroupParams1
$GroupParams2= @{
'Name' = "FS-$NAME-R"
'SamAccountName' = "FS-$NAME-R"
'GroupCategory' = "Security"
'GroupScope' = "Global"
'DisplayName' = "$NAME Read-Write Access"
'Path' = "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
'Description' = "Members of this group have read access to $Path"
}
New-ADGroup @GroupParams2
# Create New Folder
New-Item
I'm Pretty sure I have all of the syntax correct now (thanks to some awesome assistance I've received here), but I was hoping for some clarification on setting ACLs.
At the bottom I've redone how I was attempting to get, create, and set the ACLs Thanks to @themadtechnician), but I was curious as to if I've got all syntax correct or if I should create the set for each of the $objUser instead of putting them all in parentheses (is this the cleanest way to do this)...
```
$Parent = read-host -prompt "Enter full parent path that will contain the new folder (ie. \\eccofs01\Groups\ECCO IT\)"
$Name = read-host -prompt "Enter New Folder Name."
$Path = "$($parent)$($Name)"
$Location = read-host -prompt "Enter the AD Security Group Location (i.e. Global, Americas, Europe, Asia Pacific)"
Import-Module ActiveDirectory
#Create Security Groups
$GroupParams1= @{
'Name' = "FS-$NAME-RW"
'SamAccountName' = "FS-$NAME-RW"
'GroupCategory' = "Security"
'GroupScope' = "Global"
'DisplayName' = "$NAME Read-Write Access"
'Path' = "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
'Description' = "Members of this group have read-write access to $Path."
}
New-ADGroup @GroupParams1
$GroupParams2= @{
'Name' = "FS-$NAME-R"
'SamAccountName' = "FS-$NAME-R"
'GroupCategory' = "Security"
'GroupScope' = "Global"
'DisplayName' = "$NAME Read-Write Access"
'Path' = "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
'Description' = "Members of this group have read access to $Path"
}
New-ADGroup @GroupParams2
# Create New Folder
New-Item
Solution
To streamline the permission handling you may want to wrap ACE creation in a function and set the ACL just once at after all ACEs were added:
Other improvements might include determining the administrators and domain admins group names independent of the system's locale by their well-known SIDs, e.g.:
Another thing you could do is map names to permissions like this:
and use the hashtable as input for the ACE creation:
Of course this implies that all ACEs have the same type and flags, otherwise you'd have to use a more elaborate data structure.
function New-Ace {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true, Position=0)]
[Security.Principal.NTAccount]$Account,
[Parameter(Mandatory=$false, Position=1)]
[Security.AccessControl.FileSystemRights]$Permissions = 'ReadAndExecute',
[Parameter(Mandatory=$false, Position=2)]
[Security.AccessControl.InheritanceFlags]$InheritanceFlags = 'ContainerInherit,ObjectInherit',
[Parameter(Mandatory=$false, Position=3)]
[Security.AccessControl.PropagationFlags]$PropagationFlags = 'None',
[Parameter(Mandatory=$false, Position=4)]
[Security.AccessControl.AccessControlType]$Type = 'Allow'
)
New-Object Security.AccessControl.FileSystemAccessRule(
$Account, $Permissions, $InheritanceFlags, $PropagationFlags, $Type
)
}
$domain = 'DOMAIN'
$acl = Get-Acl $path
'Administrators', "$domain\Domain Admins" | ForEach-Object {
$acl.AddAccessRule((New-Ace $_ 'FullControl'))
}
$acl.AddAccessRule((New-Ace "$domain\FS-$NAME-RW" 'Modify'))
$acl.AddAccessRule((New-Ace "$domain\FS-$NAME-R" 'ReadAndExecute'))
Set-Acl $path $aclOther improvements might include determining the administrators and domain admins group names independent of the system's locale by their well-known SIDs, e.g.:
$administrators = ([wmi]"Win32_Sid.Sid='S-1-5-32-544'").AccountName
$domain_admins = Get-WmiObject -Class Win32_Account |
Where-Object { $_.SID -like '*-512' } |
Select-Object -Expand CaptionAnother thing you could do is map names to permissions like this:
$permissions = @{
'Administrators' = 'FullControl'
"$domain\Domain Admins" = 'FullControl'
"$domain\FS-$NAME-RW" = 'Modify'
"$domain\FS-$NAME-R" = 'ReadAndExecute'
}and use the hashtable as input for the ACE creation:
$permissions.Keys | ForEach-Object {
$acl.AddAccessRule((New-Ace $_ $permissions[$_]))
}Of course this implies that all ACEs have the same type and flags, otherwise you'd have to use a more elaborate data structure.
Code Snippets
function New-Ace {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true, Position=0)]
[Security.Principal.NTAccount]$Account,
[Parameter(Mandatory=$false, Position=1)]
[Security.AccessControl.FileSystemRights]$Permissions = 'ReadAndExecute',
[Parameter(Mandatory=$false, Position=2)]
[Security.AccessControl.InheritanceFlags]$InheritanceFlags = 'ContainerInherit,ObjectInherit',
[Parameter(Mandatory=$false, Position=3)]
[Security.AccessControl.PropagationFlags]$PropagationFlags = 'None',
[Parameter(Mandatory=$false, Position=4)]
[Security.AccessControl.AccessControlType]$Type = 'Allow'
)
New-Object Security.AccessControl.FileSystemAccessRule(
$Account, $Permissions, $InheritanceFlags, $PropagationFlags, $Type
)
}
$domain = 'DOMAIN'
$acl = Get-Acl $path
'Administrators', "$domain\Domain Admins" | ForEach-Object {
$acl.AddAccessRule((New-Ace $_ 'FullControl'))
}
$acl.AddAccessRule((New-Ace "$domain\FS-$NAME-RW" 'Modify'))
$acl.AddAccessRule((New-Ace "$domain\FS-$NAME-R" 'ReadAndExecute'))
Set-Acl $path $acl$administrators = ([wmi]"Win32_Sid.Sid='S-1-5-32-544'").AccountName
$domain_admins = Get-WmiObject -Class Win32_Account |
Where-Object { $_.SID -like '*-512' } |
Select-Object -Expand Caption$permissions = @{
'Administrators' = 'FullControl'
"$domain\Domain Admins" = 'FullControl'
"$domain\FS-$NAME-RW" = 'Modify'
"$domain\FS-$NAME-R" = 'ReadAndExecute'
}$permissions.Keys | ForEach-Object {
$acl.AddAccessRule((New-Ace $_ $permissions[$_]))
}Context
StackExchange Code Review Q#125408, answer score: 5
Revisions (0)
No revisions yet.