PowerShell Setting advanced NTFS permissions - powershell

I'm trying to apply NTFS permissions that are defined in the 'Advanced' tab of the Windows security settings. One ACL $Rule is for This folder only and another one is for the Subfolders and files only.
The permissions are heavily modified as you can see below:
(Get-Acl 'L:\Test\Beez\RAPJOUR\Appels List\Correct').Access
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited : False
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : None
FileSystemRights : CreateFiles, AppendData, DeleteSubdirectoriesAndFiles, ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : Domain\Dirk
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
FileSystemRights : DeleteSubdirectoriesAndFiles, Modify, Synchronize
AccessControlType : Allow
IdentityReference : Domain\Dirk
IsInherited : False
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : InheritOnly
Everything is on except for : Full control, Write attributes, Write extended attributes, Delete, Change permissions and Take ownership.
Everything is on except for : Full control, Change permissions and Take ownership.
This is a piece of the code I use to apply permissions. In this case it has to be defined in the part Change:
$f = 'L:\Test\Beez\RAPJOUR\Appels List\Wrong'
$ADobject = 'Domain\User'
$acl = Get-Acl $f
$Grant = 'Change'
# Remove user/group first
$rule = New-Object system.security.AccessControl.FileSystemAccessRule("$ADobject","Read",,,"Allow")
$acl.RemoveAccessRuleAll($rule)
# Add read permissions
if ($Grant -eq 'ReadAndExecute') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None", "Allow")
}
if ($Grant -eq 'Change') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "Modify", "ContainerInherit, ObjectInherit", "Synchronize", "Allow DeleteSubdirectoriesAndFiles")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "AppendData", "ContainerInherit, ObjectInherit", "ReadAndExecute","Synchronize", "Allow CreateFiles","DeleteSubdirectoriesAndFiles")
}
if ($Grant -eq 'Modify') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow")
}
if ($Grant -eq 'FullControl') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
}
if ($Grant -eq 'ListFolderContents') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "ReadAndExecute", "ContainerInherit", "None", "Allow")
}
$acl.AddAccessRule($rule)
Set-Acl $f $acl
I can't seem to get the syntax right.. Thank you for your help.
Thanks to this post I've already found the part for:
'Subfolders and files only': "ContainerInherit, ObjectInherit", "InheritOnly"
'This folder only': "None", "InheritOnly"

Object access permissions in Windows are controlled via Access Control Lists (ACL), which basically consist of a list of Access Control Entries (ACE). Each ACE is a set of attributes that controls whether access is granted or denied, who the ACE applies to, if the ACE was inherited from a parent object, and whether it should be inherited by child objects.
If you take a look at the documentation of the FileSystemAccessRule class, you'll see that the "full" constructor takes 5 parameters:
IdentityReference/String: An object or string that identifies the trustee (user, group, computer, ...) to whom the ACE applies.
FileSystemRights: The actual permissions to be granted or denied.
InheritanceFlags: Flags to control which object types inherit permissions from this object (containers, leaf objects, or none).
PropagationFlags: Flags to control propagation of permissions. The flag InheritOnly exempts the current object from receiving the ACE. The flag NoPropagateInherit restricts inheritance to immediate child objects.
AccessControlType: The type of the ACE (allow or deny).
Now, if you want to assign multiple access rights to a given trustee, you can either do that with individual ACEs:
$acl = Get-Acl $path
$ace1 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'ListDirectory', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Allow'
$acl.AddAccessRule($ace1)
$ace2 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'ReadAttributes', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Allow'
$acl.AddAccessRule($ace2)
...
Or by providing the permissions as a comma-separated string:
$acl = Get-Acl $path
$ace = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'ListDirectory, ReadAttributes, ...', 'ContainerInherit, ObjectInherit',
'InheritOnly', 'Allow'
$acl.AddAccessRule($ace)
Note, however, that you cannot grant and deny permissions with the same ACE. If you want to deny specific access rights you need to do it with a separate ACE:
$acl = Get-Acl $path
$ace1 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'Modify', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Allow'
$acl.AddAccessRule($ace1)
$ace2 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'CreateDirectories', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Deny'
$acl.AddAccessRule($ace2)
...
Note also, that explicit permissions take precedence over inherited permissions, and Deny takes precedence over Allow.

You know how it goes when you're fighting world problems. The moment you post the question, you find the answer 5 minutes later...
Thanks to the answer of Frode F. on another question, I found the solution to my own problem. I had to copy the output of the line FileSystemRights in $Correct.Access and paste it in an Array as you can see below:
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", #("CreateFiles", "AppendData", "DeleteSubdirectoriesAndFiles"," ReadAndExecute", "Synchronize"), "None", "InheritOnly", "Allow") # This folder only
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", #("DeleteSubdirectoriesAndFiles", "Modify", "Synchronize"), "ContainerInherit, ObjectInherit", "InheritOnly", "Allow") # Subfolders and files only

Related

Single PowerShell Script to Create Folder, AD Groups, and Apply New Groups to Folder

I'm wanting to:
Create New Folder
Set Share Name for folder so that users can see it
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
Set full access permissions to Domain Admins
Here is what I have now after playing around a little bit, but I wanted to make sure I didn't miss anything. I've decided (for the time being to leave out the param settings, but I can come back to that later. Does this look correct or is there a better way to write the script?
I've also ran into a bunch of errors about unexpected
New-ADGroup
-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 the test share"
New-ADGroup
-Name "FS-$NAME-R"
-SamAccountName "FS-"+$NAME+"-R"
-GroupCategory Security
-GroupScope Global
-DisplayName "$NAME Read Access"
-Path "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
-Description "Members of this group have read access to the test share"
# create new folder
New-Item -Path $Path -ItemType Directory
# get permissions
$acl = Get-Acl -Path $Path
#Get Security Groups
get-adobject -searchbase "CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL" -ldapfilter {(objectclass=group)}
# add a new permission
$acl.SetAccessRuleProtection($True, $False)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("Administrators","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("esg.intl\Domain Admins","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("esg.intl\"FS-"+$NAME+"-R"","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("esg.intl\"FS-"+$NAME+"-RW"","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
# set new permissions
$acl | Set-Acl -Path $path
I'm also running into some errors and I'm not sure I understand how to fix them...
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:44 char:96
+ ... " -ldapfilter {(objectclass=group)}
+ ~
Use `{ instead of { in variable names.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:55 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-R"","FullControl", "ContainerInherit, ObjectInherit" ...
+ ~~~~~~~~~~~~~~~~
Unexpected token 'FS-"+$NAME+"-R""' in expression or statement.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:55 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-R"","FullControl", "ContainerInherit, ObjectInherit" ...
+ ~
Missing closing ')' in expression.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:55 char:164
+ ... "None", "Allow")
+ ~
Unexpected token ')' in expression or statement.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:58 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-RW"","FullControl", "ContainerInherit, ObjectInherit ...
+ ~~~~~~~~~~~~~~~~~
Unexpected token 'FS-"+$NAME+"-RW""' in expression or statement.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:58 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-RW"","FullControl", "ContainerInherit, ObjectInherit ...
+ ~
Missing closing ')' in expression.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:58 char:165
+ ... "None", "Allow")
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : OpenBraceNeedsToBeBackTickedInVariableName
Ok, so a couple things I see. First, string interpolation... Where you have:
"FS-"+$NAME+"-RW"
You can shorten that to simply:
"FS-$NAME-RW"
When a variable is found within double quotations like that it will try to expand the variable into a string automatically. I am not going to get into stipulations or rules, since I think that would only over-complicate this. Suffice it to say that this change alone, when applied to all instances where it can be in your script, will probably remove most of your errors. ...and possibly create new ones since several commands would then be correctly interpreted.
Next, command syntax. Your first two commands, unless you have escaped the new lines and that is simply not reflected in your question, are likely not going to execute as you would expect them. If you want to space out your parameters like you have I would suggest setting them up as hashtables, and then expanding the hashtable when executing the command. You can do that like this:
$GroupParams= #{
'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 the test share"
}
New-ADGroup #GroupParams
Your LDAPFilter line error, well, that line looks superfluous so I'd say comment it out and move on.
Please note that you are giving FullAccess rights to the Read group, you probably want to change that to ReadAndExecute.
Lastly, if you have trouble with your ACLs then I'll give you the same advise I give anybody when dealing with ACLs on file shares. Define your settings explicitly, then apply them as an access rule. I use the following as a template:
$Rights = [System.Security.AccessControl.FileSystemRights]"FullControl"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("IIS_IUSRS")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $Rights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL "C:\Temp"
$objACL.AddAccessRule($objACE)
Set-ACL "C:\Temp" $objACL
On a side note, you never really deal with the whole network share thing of declaring a share name and what not. You may want to run get-help New-SMBShare -Full to get more info on setting up the network share.

Set folder permissions for HomeGroup

I found the following which seems to work for what it is, but I need 2 things changed, and can't figure it out.
$acl = Get-Acl D:\New
$permission = "Everyone","Read","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl D:\New
I need to be able to give "HomeGroup" permission, not "Everyone".
I need this to recurse all folders.
When in doubt, read the documentation. You need to change the identity from "Everyone" to "$env:COMPUTERNAME\HomeGroup" and set the appropriate inheritance and propagation flags.
$identity = "$env:COMPUTERNAME\HomeGroup"
$accessRight = 'Read'
$inheritance = 'ContainerInherit, ObjectInherit'
$propagation = 'None'
$type = 'Allow'
$accessRule = New-Object Security.AccessControl.FileSystemAccessRule (
$identity, $accessRight, $inheritance, $propagation, $type
)

Add security rights to an extended rights guid

Thanks to #Mathias R. Jessen I was able to get this far. The only problem is that the rights are not propagating to the extended attribute, even in the advanced tab :(.
If I go in to adsi and check the security tab of the extended right it shows nothing regarding the new group having rights... but ... If I check the variable $rootObjACL.access, it shows the rights as they should be.
ActiveDirectoryRights : ExtendedRight
InheritanceType : None
ObjectType : 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : NEW\Replication
IsInherited : False
InheritanceFlags : None
PropagationFlags : None**
Trying to figure out what I am doing wrong. There are no errors what so ever while running the script. Here is the script below.
Import-Module ActiveDirectory
$rootObjPath = "AD:\CN=Configuration,DC=new,DC=domain,DC=com"
$rootObjACL = Get-Acl $rootObjPath
$group = Get-ADgroup 'Replication'
$SID = New-Object System.Security.Principal.SecurityIdentifierArgumentList $group.SID
# The following object specific ACE is to grant Group the permission DS-Replication-Get-Changes
$objectGuid = New-Object Guid 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
$ADRight = [System.DirectoryServices.ActiveDirectoryRights]"ExtendedRight"
$ACEType = [System.Security.AccessControl.AccessControlType]"Allow"
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $SID,$ADRight,$ACEType,$objectGuid
$rootObjACL.AddAccessRule($ACE)
Set-Acl $rootObjPath -AclObject $rootObjACL

Append security rights to a folder via Powershell

Trying my hand at Powershell and I'm trying to figure out how to add specific permissions to our user account. The code below will add the service account to the folders Security tab, however it will not adjust the permissions. Any idea why?
#variables
$okeeffename = "WCFService"
$domain = "InsideServices.dev.com"
$okeeffedirectory = "d:\webcontent\$domain\$okeeffename"
#create webcontent and application folders
Write-Host "Creating directories" -ForegroundColor Yellow
New-Item -Path $okeeffedirectory -type directory -ErrorAction Stop
#adjust security for folders
$okeefferights = Get-Acl $okeeffedirectory
$read = New-Object system.security.accesscontrol.filesystemaccessrule($useraccount, "Read", "Allow")
$list = New-Object system.security.accesscontrol.filesystemaccessrule($useraccount, "ListDirectory", "Allow")
$readexecute = New-Object system.security.accesscontrol.filesystemaccessrule($useraccount, "ReadAndExecute", "Allow")
$okeefferights.SetAccessRule($read)
$okeefferights.SetAccessRule($list)
$okeefferights.SetAccessRule($readexecute)
Set-Acl -Path $okeeffedirectory -AclObject $okeefferights
Second question: I'm trying to add the following permissions for the service account to the folder. Can someone point out the keyword Powershell uses for the List Folder Contents permission?
EDIT
By toggling the Allow/Deny value for the FileSystemRights I found that each of the specs are only changing the Special Permissions Permission on the folder. Quick screen shot:
This is fairly easy to find out when you know what exactly you are looking for. What you need is a [System.Security.AccessControl.FileSystemRights]. We can find the available rights list by using [enum] as such:
PS C:\windows\system32> [enum]::GetNames([System.Security.AccessControl.FileSystemRights])
ListDirectory
ReadData
WriteData
CreateFiles
CreateDirectories
AppendData
ReadExtendedAttributes
WriteExtendedAttributes
Traverse
ExecuteFile
DeleteSubdirectoriesAndFiles
ReadAttributes
WriteAttributes
Write
Delete
ReadPermissions
Read
ReadAndExecute
Modify
ChangePermissions
TakeOwnership
Synchronize
FullControl
You can create several rights in one object like (this should allow a user read/execute only access to a folder and its' contents):
$Rights = [System.Security.AccessControl.FileSystemRights]"ListDirectory,ReadData,Traverse,ExecuteFile,ReadAttributes,ReadPermissions,Read,ReadAndExecute"
My usual template for setting ACLs is this:
$Rights = [System.Security.AccessControl.FileSystemRights]"FullControl"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("Domain\User")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $Rights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL "C:\Temp"
$objACL.AddAccessRule($objACE)
Set-ACL "C:\Temp" $objACL
From that you should be able to manipulate the code to accomplish what you want.
To build an ACE that shows up as "list folder contents" in the "Security" tab you need to combine 5 file system rights:
ListDirectory
ReadAttributes
ReadExtendedAttributes
ReadPermissions
Traverse
and set inheritance to ContainerInherit.
$list = New-Object Security.AccessControl.FileSystemAccessRule($useraccount, 'Traverse,ListDirectory,ReadAttributes,ReadExtendedAttributes,ReadPermissions', 'ContainerInherit', 'None', 'Allow')
the most straightforward way to find out the specific combination of file system rights and inheritance flags for a particular ACE is to create it manually and inspect the result in the Advanced Security Settings:

Added permission not inherited to sub folders/files

Im trying to add modify right to bob user from domain, but it is giving only permission and no rights at all and even not inheriting to subfolder to path D:\test, from the script as below:
$Right = [System.Security.AccessControl.FileSystemRights]"Modify"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::InheritOnly
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("domain\bob")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $Right, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL "D:\Test"
$objACL.AddAccessRule($objACE)
Set-ACL "D:\Test" -aclobject $objACL
Where is my mistake ?
Not sure what you mean by "only permission and no rights at all", but the following line is what prevents your ACL from being inherited:
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
Change that line to
$InheritanceFlag = ([System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit)
and the ACL should be inherited by the child objects.