Link to home
Start Free TrialLog in
Avatar of SAM IT
SAM IT

asked on

Need to Change ACL (Permissions )and disable in heritance for subfolders

Below script create sub folders and I Need to  disable inheritance for Foldera and folderb and Change the permissions from particular security Group from Modify to Read For other folders no changes needed

For Foldera and Folderb ACL should be Read Permission
and for rest of the folders Modify Permission

$root = "C:\Users\a.narasimha.s\Desktop\foldertest1"

ForEach ($dir in (Get-ChildItem -Path "$root\*\" | ?{$_.PSIsContainer} | Select -Expand Name)){



  New-Item -Path "$dir\folder1" -ItemType Directory | Out-Null
  New-Item -Path "$dir\folder2" -ItemType Directory | Out-Null
  New-Item -Path "$dir\1" -ItemType Directory | Out-Null
  New-Item -Path "$dir\2" -ItemType Directory | Out-Null

 }

Open in new window

Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Good morning,

This might need a bit of tweaking, I haven't tested it.
$root = "C:\Users\a.narasimha.s\Desktop\foldertest1"

Get-ChildItem -Path "$root\*\" | Where-Object { $_.PSIsContainer } | ForEach-Object {
  $dir = $_.FullName

  $folder = New-Item -Path "$dir\folder1" -ItemType Directory
  
  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' -and $_.FileSystemRights -eq 'Modify,Synchronize' } | ForEach-Object {
    $acl.RemoveAccessRule($_)
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('domain\somegroup', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl

  $folder = New-Item -Path "$dir\folder2" -ItemType Directory

  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' -and $_.FileSystemRights -eq 'Modify,Synchronize' } | ForEach-Object {
    $acl.RemoveAccessRule($_)
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('domain\somegroup', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl

  $folder = New-Item -Path "$dir\1" -ItemType Directory
  $folder = New-Item -Path "$dir\2" -ItemType Directory
}

Open in new window

Avatar of SAM IT
SAM IT

ASKER

Partially script works.

Now script  disabled the  Inheritance  option on the subfolders.

But security group Modify level Permissions which are reflected from the Parent Folders its still remain same on sub folders

I want to Change the Inherited Modify Security Group (Group1) permission level  to Read only on 02 subfolders . Rest not changes needed

I have attached the Permission level screen shot
permission.jpg
Second attempt.
$root = "C:\Users\a.narasimha.s\Desktop\foldertest1"

Get-ChildItem -Path "$root\*\" | Where-Object { $_.PSIsContainer } | ForEach-Object {
  $dir = $_.FullName

  $folder = New-Item -Path "$dir\folder1" -ItemType Directory
  
  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' } | ForEach-Object {
    $acl.RemoveAccessRule($_)
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('domain\somegroup', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl

  $folder = New-Item -Path "$dir\folder2" -ItemType Directory

  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' } | ForEach-Object {
    $acl.RemoveAccessRule($_)
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('domain\somegroup', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl

  $folder = New-Item -Path "$dir\1" -ItemType Directory
  $folder = New-Item -Path "$dir\2" -ItemType Directory
}

Open in new window

Avatar of SAM IT

ASKER

In the attached document I have highlighted in red lines

1. Folders
2. Domain\Group
3.Domain\Group

Have bit confusion here . why twice we have to mentioned the Domain\group for one folder
 and what exactly have to mention here?
No attachment...

We have domain\group twice because we must first explicitly remove the rule you don't want, then add a new rule with the values you do want.
Avatar of SAM IT

ASKER

yes I got it. But still new rule is applying the Full access only to the subfolder




I have mentioned different security  group name in New rule . I noticed that Sub folder having the In inherited group with full access not considering what mentioned in the new rule
Avatar of SAM IT

ASKER

I have used Second attempt script which was given my you.

I have noticed that $acl.RemoveAccessRule($_) not removing the  inherited the Modify security group

 I have added the different Different security group with read access in $ace = New-Object System.Security.AccessControl.FileSystemAccessRule it is reflecting

Now the pending thing is  Security groups is not getting removed  $acl.RemoveAccessRule($_)
Inherited ACE's cannot be removed, only explicit. This is why the  access control list is protected prior to making that change. I would add code to determine if it's finding the ACE to remove in the first place.

e.g.
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' } | ForEach-Object {
    Write-Host "Removining ACE for $($_.IdentityReference)"
    $acl.RemoveAccessRule($_)
  }

Open in new window

Avatar of SAM IT

ASKER

tried above Example . no luck

Still IN inherited permissions are reflecting
Hmm perhaps we need two steps.
  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  Set-Acl $folder.FullName -AclObject $acl
  
  $acl = Get-Acl $folder.FullName
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' } | ForEach-Object {
    $acl.RemoveAccessRule($_)
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('domain\somegroup', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl

Open in new window

Avatar of SAM IT

ASKER

If i executed the above script Now new object wont be added and Inheritance permissions remain same
Is inheritance being disabled or not?

When it's being disabled we're copying the existing access control entries from the old ACL to the new. The copied entries will become explicit.

You could delete them immediately, but you'd have to re-populate the ACL with something useful before committing it.
Avatar of SAM IT

ASKER

1. In inheritance is getting disabled on subfolders
2. But Inherited Permission wont get removed
3. If I add different group in New object it is getting added to sub folders
2.  This is correct. If the permissions are completely removed the ACL will be completely blank. You'll have to rebuild it completely.

3. What do you mean by getting added to sub-folders? As in $dir\folder1\sub has permissions inheriting from folder1?

If an ACL is not protected, inheritance of rights by children is controlled by the inheritance and propagation flags on individual access control entries. You haven't specified any.
Avatar of SAM IT

ASKER

Answer to your 3 point.

If I add any Security group in the below mentioned New-object I will get added to folder security .

 If I add the same security group which I mentioned to acl.RemoveAccessRule there will be no changes. the output is  security groups are still getting inheritance from parent


$ace = New-Object System.Security.AccessControl.FileSystemAccessRule('domain\somegroup', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')

Open in new window


__________________________

I did not understand this point :
If an ACL is not protected, inheritance of rights by children is controlled by the inheritance and propagation flags on individual access control entries. You haven't specified any.
Your file system looks like this:

C:\Users\a.narasimha.s\Desktop\foldertest1\something\folder1
C:\Users\a.narasimha.s\Desktop\foldertest1\something\folder2
C:\Users\a.narasimha.s\Desktop\foldertest1\something\1
C:\Users\a.narasimha.s\Desktop\foldertest1\something\2

folder1 and folder2 have AccessRuleProtection enabled, inheritance from "something" is disabled.

1 and 2 are inheriting as is the default.

When inheritance was disabled for folder1 and folder2, the existing (inherited) rights were copied and made explicit within the context of that ACL.

Explicit entries can be removed from folder1 and folder2, provided the syntax to do so is correct.

Explicit entries can be added to all folders, provided that the new access control entry really is new (does not provide the same or less access than an existing entry).

To remove an entry, the syntax used here needs testing and correcting:
  $acl = Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\something\folder1"
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' } | ForEach-Object {
    Write-Host "Removing ACL for $($_.IdentityReference)"
    $acl.RemoveAccessRule($_)
  }

Open in new window

It is very, very important you get the terminology right here. If you tell me there are inherited access control entries on a folder which just had protection enabled I'll have to ask more questions about whether or not protection is enabled.

There *will* be entries which resemble the previously inherited entries, but they are *not* inherited unless something else went wrong.

A fair understanding of NTFS security is a pre-requisite to coding all of this.
Avatar of SAM IT

ASKER

Below is the folder the folder structure:

Shared folder Path:
C:\Users\a.narasimha.s\Desktop\foldertest1

Under folder                                 > foldertest1   Root Shared Path
Under Parent folder                     > Parentfolder - No changes happening on Parent folder  
Subfolder folder                           > Sub folder    - In inheritance is getting turned off on the sub folder But In In inherited security Group is not getting removed
Avatar of SAM IT

ASKER

I have reduced the script length as well for easy understand:

Below is the folder the folder structure:

Shared folder Path:
C:\Users\a.narasimha.s\Desktop\foldertest1

Under folder                                 > foldertest1   Root Shared Path
Under Parent folder                     > Parentfolder - No changes happening on Parent folder  
Subfolder folder                           > Sub folder    - In inheritance is getting turned off on the sub folder But In In inherited security Group is not getting removed


$root = "C:\Users\a.narasimha.s\Desktop\foldertest1"

Get-ChildItem -Path "$root\*\" | Where-Object { $_.PSIsContainer } | ForEach-Object {
  $dir = $_.FullName

  $folder = New-Item -Path "$dir\folder1" -ItemType Directory
  
  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  $acl.Access | Where-Object { $_.IdentityReference -eq 'Domain\Group1' } | ForEach-Object {
    $acl.RemoveAccessRule($_)
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('Domain\Group', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl

Open in new window

The code works in principal, but the ACL must be applied and re-acquired after enabling access rule protection.
$root = "C:\Users\a.narasimha.s\Desktop\foldertest1"

Get-ChildItem -Path "$root\*\" | Where-Object { $_.PSIsContainer } | ForEach-Object {
  $dir = $_.FullName

  $folder = New-Item -Path "$dir\folder1" -ItemType Directory
  
  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  Set-Acl $folder.FullName -AclObject $acl  

  $acl = Get-Acl $folder.FullName
  $acl.Access | Where-Object { $_.IdentityReference -eq 'Domain\Group1' } | ForEach-Object {
    $acl.RemoveAccessRule($_)
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('Domain\Group', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl

Open in new window

Avatar of SAM IT

ASKER

After executing above script getting an error. attached for reference

Set-acl error: Security group is not getting apply to sub folder

And  inherited permission to Subfolder not getting removed
error5.jpg
You don't have sufficient rights to make the change... SeSecurityPrivilege is Run As Administrator.

Did that appear after setting access rule protection, or after adding the ACE?
Avatar of SAM IT

ASKER

It appeared after setting access rule protection.
Okay, nothing you can do other than ensure you have sufficient rights to make the change. Run as administrator.
Avatar of SAM IT

ASKER

I initiated above script it works with out errors

1. Script turned off  inheritance
2. Not removed the Inherited security group
3. Added the new-object "different security group"
Please can you tell me if you see the text in Write-Host when you run this command:
  $acl = Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\something\folder1"
  $acl.Access | Where-Object { $_.IdentityReference -eq 'domain\somegroup' } | ForEach-Object {
    Write-Host "Removing ACL for $($_.IdentityReference)"
    $acl.RemoveAccessRule($_)
  }

Open in new window

We categorically need to know if the snippet is selecting the correct rule to remove.
Avatar of SAM IT

ASKER

Its not removing the Inherited group.

I have attached the output file .
abc.jpg
It's not finding a rule to remove. Something is wrong with the comparison.

Try.
  $acl = Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\something\folder1"
  $acl.Access | Where-Object { $_.IdentityReference.Value.ToString() -like '*\somegroup' } | ForEach-Object {
    Write-Host "Removing ACL for $($_.IdentityReference)"
    $acl.RemoveAccessRule($_)
  }

Open in new window

Avatar of SAM IT

ASKER

I executed the script no errors in output.  reference attached
xyz.jpg
It removed the ACE this time. That should have fixed it.
Avatar of SAM IT

ASKER

In the Above attached screen shot ouput says Removed acl for Security Group.

But   inherited security  group wont get removed . I have attached the screen shot for the same
12.jpg
It's removing something. Look at $acl.Access before and after to see what its stripping out. Or inspect the ACL it found with this:
  $acl = Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\something\folder1"
  $acl.Access | Where-Object { $_.IdentityReference.Value.ToString() -like '*\somegroup' } | ForEach-Object {
    $_

    $acl.RemoveAccessRule($_)
  }

Open in new window

Avatar of SAM IT

ASKER

Not removed the Inherited permissions.

Please find the attached output
13.jpg
ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SAM IT

ASKER

Finally  below script removing the Inherited  security permission If I mention specific sub folder name "doc" In the line 1st line  
$acl = Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\123\doc"

Open in new window



Mentioned security  group in $acl.access is getting removed after running this script. Can we run this script on Parent folder "123" because If multiples sub folders will be there inside Parent folder we can remove the Inherited permission on specific sub folder


    $acl = Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\123\doc"
  $acl.Access | Where-Object { $_.IdentityReference.Value.ToString() -like '*\DL-WGK-US-Houston-Projects-XXXXXX-RW-TESTnew12' } | ForEach-Object {
    $_

    $acl.RemoveAccessRule($_)
  }
Set-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\123\" -AclObject $acl

Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\123\" |
    Select-Object -ExpandProperty Access

Open in new window

Avatar of SAM IT

ASKER

I hope above out put is fine .
Avatar of SAM IT

ASKER

Output I am getting that 1st If i run the below script it will create the sub folder on parent folder

$root = "C:\Users\a.narasimha.s\Desktop\foldertest1"

Get-ChildItem -Path "$root\*\" | Where-Object { $_.PSIsContainer } | ForEach-Object {
  $dir = $_.FullName

  $folder = New-Item -Path "$dir\doc" -ItemType Directory
  
  $acl = Get-Acl $folder.FullName
  $acl.SetAccessRuleProtection($true, $true)
  $acl.Access | Where-Object { $_.IdentityReference.Value.ToString() -like '*\DL-WGK-US-Houston-Projects-XXXXXX-RW-TESTnew12' } | ForEach-Object {
    Write-Host "Removing ACL for $($_.IdentityReference)"
    $acl.RemoveAccessRule($_)
  
  }
  $ace = New-Object System.Security.AccessControl.FileSystemAccessRule('domain\DL-WGK-US-Houston-Projects-XXXXXX-RW-TESTnew', 'ReadAndExecute,Synchronize', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
  $acl.AddAccessRule($ace)
  Set-Acl $folder.FullName -AclObject $acl
  }

Open in new window


Then second action is I need to run the below script . for output what I expected . Can we merge the script in to one

    $acl = Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\123\doc"
  $acl.Access | Where-Object { $_.IdentityReference.Value.ToString() -like '*\DL-WGK-US-Houston-Projects-XXXXXX-RW-TESTnew12' } | ForEach-Object {
    $_

    $acl.RemoveAccessRule($_)
  }
Set-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\123\" -AclObject $acl

Get-Acl "C:\Users\a.narasimha.s\Desktop\foldertest1\123\" |
    Select-Object -ExpandProperty Access

Open in new window

Avatar of SAM IT

ASKER

Hello Chris,

For above script we need to mention the specfic sub-folder folder-name which are under Parentfolder .

For Each and every Parent folder we need to alter the script. I have saw your update for one the question for similar requirement below mentioned one

https://www.experts-exchange.com/questions/28347944/Need-help-creating-a-Powershell-folder-script.html

I have script to create Parent folders which will take input from csv.  I there any way that In one handy we run the script it should create tge parent folders incuding 07 subfolders on each parent folders and for 03 subfolder in inheritance should be disabled and permission should be removed and added

I am using below script for Parent folder creation I tried to add the subfolder script in the parent folder script I have not got any results , Thanks in advance


Set-Location "C:\Users\a.narasimha.s\Desktop\98"
$csvFile = "C:\Users\a.narasimha.s\Desktop\importfolders.csv"

$create = Import-CSV $csvFile

function DoPermissions
{
    param( $permissionGroup, $folder, $level)
    $toAdd = $permissionGroup -split ";"
    Write-Host $folder
    foreach ($item in $toAdd)
    {
        $acl = (Get-Item $folder).GetAccessControl('Access')
        $ar = New-Object System.Security.AccessControl.FileSystemAccessRule($item, $level, 'ContainerInherit,ObjectInherit','None','Allow')
        $acl.SetAccessRule($ar)
        Set-ACL -path $folder -AclObject $acl
    }
}

foreach ($folder in $create)
{
    $fullPath = $folder.folder #$path + $folder.folder
    if (!(Test-Path $fullPath)) {New-Item -ItemType Directory -Path $fullPath}

    if ($folder.full_control) {DoPermissions $folder.full_control $fullPath "FullControl"}
    if ($folder.modify) {DoPermissions $folder.modify $fullPath "Modify"}
    if ($folder.read_execute) {DoPermissions $folder.read_execute $fullPath "ExecuteFile"}
    if ($folder.list_folder_content) {DoPermissions $folder.list_folder_content $fullPath "ListDirectory"}
    if ($folder.read) {DoPermissions $folder.read $fullPath "ReadData"}
    if ($folder.write) {DoPermissions $folder.write $fullPath "Write"}

}

Open in new window

Avatar of SAM IT

ASKER

To join the subfolder creation along with Parent folder below script might help out . Thanks in advance

$folder = "C:\Users\IBM_ADMIN\Desktop\foldertest"
$subfolders = "Volvo","Skoda","Tesla"
$file = Import-Csv 'C:\Users\IBM_ADMIN\Desktop\foldertest\import.csv' -Delimiter ';' 
$file | 
 % { 
        $path = Join-Path $folder $_.Letter; 
        New-Item -Path $path -Name $_.Name -Type Directory 
}
foreach ($subfolder in $subfolders)
{ 
$file | %{
 $path2 = Join-Path $folder $_.Letter;
 $path3 = Join-Path $path2 $_.Name;
 New-Item -Path $path3\$subfolder -Type Directory 
   }
}

Open in new window

No comment has been added to this question in more than 21 days, so it is now classified as abandoned.

I have recommended this question be closed as follows:

Accept: Chris Dent (https:#a42091777)

If you feel this question should be closed differently, post an objection and the moderators will review all objections and close it as they feel fit. If no one objects, this question will be closed automatically the way described above.

exchangepro
Experts-Exchange Cleanup Volunteer