Changing ACL with script

This topic contains 0 replies, has 1 voice, and was last updated by  Forums Archives 5 years, 9 months ago.

  • Author
    Posts
  • #5148

    by Chris78 at 2012-09-27 05:25:20

    Hello,

    I have a number of folders, each with a folder-specific security group with the permission 'list contents, this folder only'. I need to change the permission for each group to read and execute, and due to the large number of folders and security groups I would like to do this using PowerShell. Each of the security group names usefully ends with '-T'.

    I've tried writing the following script, however I can't seem to get it right:

    [code2=powershell]$path = "C:\PSTEST"
    $folders = gci $path -recurse | ?{._psiscontainer}
    get-acl $folders | select -expand access | where { $_.IdentityReference -like "*-T" }
    foreach ($Access in $Acl.Access) { $acl.RemoveAccessRule($Access)
    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($Access.IdentityReference,"ReadandExecute,Synchronize","None","None","Allow")
    $acl.AddAccessRule($rule)
    Set-Acl -Path $Folder.FullName -AclObject $acl[/code2]

    Any help would be appreciated!

    Thanks,

    Chris

    by poshoholic at 2012-09-27 05:41:18

    Without running your script, I can see that you're close, but you're missing a few things. First, you get a folders collection, but then you reference $folder when that variable has never been assigned. Also, you retrieve the ACL for each folder, but then you don't assign the ACL to the $ACL variable that you are then using in your script. Lastly, you are missing a closing brace for your loop. Here is a slightly modified version of your script (WARNING: UNTESTED) that should get you a little further:
    $path = "C:\PSTEST"
    foreach ($folder in gci $path -recurse | ?{._psiscontainer}) {
    $acl = get-acl $folder
    foreach ($ace in $acl.Access | where { $_.IdentityReference -like "*-T" }) {
    $newAce = New-Object System.Security.AccessControl.FileSystemAccessRule($ace.IdentityReference,"ReadandExecute,Synchronize","None","None","Allow")
    $acl.RemoveAccessRule($ace)
    $acl.AddAccessRule($newAce)
    }
    Set-Acl $folder -AclObject $acl
    }

    I stress again, this is untested. I just shuffled around some parts in your script to make sure that loops are closed properly and to make sure that variables are being properly assigned before use.

    A few tips:
    1. Use indentation for loops. That lets you see where they start and finish more easily.
    2. When you reference a variable, make sure that variable is assigned first. Variables don't get magically assigned.

    by JeffH at 2012-09-27 05:42:01

    First off, it always help to say what the problem is. Do you get errors? Does nothing happen? Do you not get the result you expect. That said it looks like some things are missing from your code. You have a ForEach line but where is $ACL coming from? Later on you use $Folder.Fullname with Set-ACL. Where did $Folder come from? Is this something you copied from somewhere else? I'm working on restructuring but this is incomplete and will never work as is.

    by Chris78 at 2012-09-27 08:16:29

    Hi,

    Thank you both for your comments. Apologies for the missing elements of the script, what I posted was from two different scripts that I'd put together without testing (neither of them worked, but I thought it gave an idea of what I was trying to do).

    I amended the script as suggested, however I am still getting errors. Specifically, for each sub-folder in C:\PSTEST I get the following:

    Get-Acl : Cannot find path '1234' because it does not exist.
    At C:\pstest\test10.ps1:3 char:19
    + $acl = get-acl < <<< $folder
    + CategoryInfo : ObjectNotFound: (:) [Get-Acl], ItemNotFoundException
    + FullyQualifiedErrorId : GetAcl_PathNotFound_Exception,Microsoft.PowerShell.Commands.GetAclCommand

    Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
    At C:\pstest\test10.ps1:9 char:31
    + Set-Acl $folder -AclObject < <<< $acl
    + CategoryInfo : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclCommand

    Just to clarify, the script is now as follows:

    [code2=powershell]$path = "C:\PSTEST"
    foreach ($folder in gci $path -recurse | ?{$_.psiscontainer}) {
    $acl = get-acl $folder
    foreach ($ace in $acl.Access | where { $_.IdentityReference -like "*-T" }) {
    $newAce = New-Object System.Security.AccessControl.FileSystemAccessRule($ace.IdentityReference,"ReadandExecute,Synchronize","None","None","Allow")
    $acl.RemoveAccessRule($ace)
    $acl.AddAccessRule($newAce)
    }
    Set-Acl $folder -AclObject $acl
    }[/code2]

    Any ideas?

    Thanks,

    Chris

    by poshoholic at 2012-09-27 08:23:59

    Inside the outermost foreach loop, in the calls to Get-Acl and Set-Acl, replace $folder with $folder.FullPath.

    by Chris78 at 2012-09-27 08:38:13

    Thanks for the quick reply. I've changed the script as follows:

    $path = "C:\PSTEST"
    foreach ($folder in gci $path -recurse | ?{$_.psiscontainer}) {
    $acl = get-acl $folder.FullPath
    foreach ($ace in $acl.Access | where { $_.IdentityReference -like "*-T" }) {
    $newAce = New-Object System.Security.AccessControl.FileSystemAccessRule($ace.IdentityReference,"ReadandExecute,Synchronize","None","None","Allow")
    $acl.RemoveAccessRule($ace)
    $acl.AddAccessRule($newAce)
    }
    Set-Acl $folder.FullPath -AclObject $acl
    }

    However, I now get the following errors:

    Get-Acl : Cannot validate argument on parameter 'Path'. The argument is null or empty. Supply an argument that is not
    ull or empty and then try the command again.
    At C:\pstest\test10.ps1:3 char:19
    + $acl = get-acl < <<< $folder.FullPath
    + CategoryInfo : InvalidData: (:) [Get-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetAclCommand

    Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
    At C:\pstest\test10.ps1:9 char:40
    + Set-Acl $folder.FullPath -AclObject < <<< $acl
    + CategoryInfo : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclCommand

    Thanks for the help,

    Chris

    by poshoholic at 2012-09-27 08:56:53

    Whoops! It's not what I say this morning, it's what I mean to say that's important. 🙂

    Sorry for the confusion, it's FullName, not FullPath. You need to pass the FullName property to the Path parameter (i.e. replace FullPath with FullName). My apologies for giving you the wrong property name last time.

    by Chris78 at 2012-09-27 09:10:22

    🙂 no worries, there's no need to apologise since you're the one helping me out!

    I changed the script, and it works absolutely perfectly – thank you so much for your time and patience, you've really helped me out!

    Thanks again,

    Chris

    by poshoholic at 2012-09-27 09:55:22

    Excellent, thanks for letting me know it's working for you!

You must be logged in to reply to this topic.