Your basic ITPro blog... What's going on at work, what I'm interested in.

Sunday, March 16, 2008

Reset Security on Folder Structure with PowerShell

I have been thinking through our new shared folder storage and came across the following dilemma.

As you probably know, when you copy an item form one location to another (same volume or different volume) the item inherits its destination's security settings. However, you have to be more careful when you move an item.

If you move and item to a destination on a different volume, there are actually two steps that take place: a copy and then a delete. The item is copied to the new location (thereby inheriting the security settings of its destination) and then it is deleted from its original location.

But, if you move an item to another location on the same volume, only the pointer to the item is changed. So, the item retains its security settings. This is a HUGE problem for me, one that I was starting to get worried about.

Our User and Group shares are stored on the same volume on our server. It looks something like this:

image In this structure, the 'Share-Admin' security group has Full Control rights to the 'Shares' folder. The 'Groups' folder is shared out and every user gets a drive mapping to that folder. Each folder under 'Groups' get its own security groups assigned it, one for MODify access and one for ReadOnly access (see my entry here).

The 'Users' folder is shared out and every user gets a drive mapping to: \\server\Users\<username>. Each user is given Modify rights to their folder.

These resources all use Access Based Enumeration so each user only sees the folders that they have access to.

It all seemed to be working out quite well, until I realized that moves were possible. If a user has access to multiple folders within 'Groups', they could move items from one folder to another. And, since the source and destination would be on the same volume, the item(s) being moved would take their security settings with them. Not good!

So, what is my solution to this?! I am formulating a solution that I hope will be workable. Of course, I am using PowerShell. I am developing a script that will iterate through all of the child objects within by base folders and reset the security settings so that there are no misplaced or explicit items.

My first go-around was pretty simple.

$ErrorActionPreference = "SilentlyContinue"

$path = 'c:\shares\users\derekm'

$dirs = Get-ChildItem -Path $path -Recurse

foreach ($item in $dirs) {
    $acl = Get-Acl $item.FullName
    $aces = $acl.Access
    foreach ($ace in $aces) {
        if ($ace.IsInherited -eq $FALSE) {
            $removeACE = $acl.RemoveAccessRule($ace)
    $ACLset = Set-Acl $item.FullName $acl

$path = $dirs = $acl = $aces = $removeACE = $ACLset = $null

All this does is:

  • Load all child items for a particular folder into an array.
  • For each item
    • Get the ACL
    • Load the ACEs into an array
    • Remove all explicit ACEs
    • Write the modified ACL back to the item

This was fine, except for one thing... If you move an item from one folder to another within the 'Groups' folder structure, the ACEs all show up as inherited. So, if you move FILE.TXT from FOLDERA to FOLDERB, FILE.TXT will have inherited FOLDERA security, even though it now resides in FOLDERB. My script, as listed above, can not fix this. I need another way. With some minor tweaks, I have come up with:

$ErrorActionPreference = "SilentlyContinue"

$path = 'c:\shares\Groups\Folder0013'

$baseACL = Get-Acl $path

$items = Get-ChildItem -Path $path -Recurse

foreach ($item in $items) {
    Set-Acl $item.FullName $baseACL
    $itemACL = Get-Acl $item.FullName
    $itemACEs = $itemACL.Access
    foreach ($itemACE in $itemACEs) {
        if ($itemACE.IsInherited -eq $FALSE) {
            $null = $itemACL.RemoveAccessRule($itemACE)
    Set-Acl $item.FullName $itemACL

$path = $baseACL = $items = $item = $itemACL = $itemACEs = $itemACE = $ACLset = $null

The main change here is that I first overwrite the current ACL on each item with that of it's proper parent folder. I then go through and remove all explicit entries, leaving only inherited security settings. Great!

So, this seems to be the raw mechanics that will work for me. Now, I just need to augment this script, allowing it to accept input, work with possible deadly errors, etc.

No comments:

Additional Info

My photo
email: support (AT) mangrumtech (DOT) com
mobile: 480-270-4332