PowerShell to set ACLs that prevent renaming of top-level directories in a share

We have a shared folder that is replicated to all our sites using the fantastic GlobalScape WAFS (@GlobalScape). This folder is huge.

People go into the folder, and “type ahead” to get the subfolder they want,  but what keeps happening (and I am sure you have seen this) is that when users click and try to type ahead, they don’t realize that they have clicked a folder and their “type ahead” is actually renaming the folder. We end up with a lot of folders named “p” or “j” or “m”. Everyone has full access to the folder and all files/folders below. The impact is that when a large folder gets renamed, this has to be replicated across the country via WAFS, which is slowing down the other offices.

To solve this I had to sit down and figure out ACLs and using PowerShell to change them. The security on the top-level folders are inherited from above, and they are simple: Administrator = FULL, System = Full, Creator Owner = Modify, and BUILTIN\USERS = Modify.

The script below, loops through the top-level folders (in this case just the A’s) and  copies the inherited permissions to the folder. Next it sets the folder so it does not inherit permission from the folder above (Lines 1 – 6). Then, the script  creates an ACL rule that removes the BUILTIN\USERS = Modify ACL (Line  8 ). Finally it creates 2 ACL rules that add, for BUILTIN\USERS,  “ReadAndExecute” for “This folder only” and a “Modify” for “Subfolder and files below” (Lines 9 – 10).

And this is what the result looks like:

PowerShell script:

Get-ChildItem a* | Where {$_.psIsContainer -eq $true} | foreach {
$filename = $_
write-host "Changing $_"
$objACL=Get-ACL $filename
$objACL.SetAccessRuleProtection($true,$true)
set-acl $filename $objACL

$RMAccessRule = New-Object Security.AccessControl.FileSystemAccessRule("BUILTIN\Users",@("Modify", "Synchronize"),"ContainerInherit, ObjectInherit","None","Allow")
$AddAccessRule1 = New-Object Security.AccessControl.FileSystemAccessRule("BUILTIN\Users",@("ReadAndExecute", "Synchronize"),"None","None","Allow")
$AddAccessRule2 = New-Object Security.AccessControl.FileSystemAccessRule("BUILTIN\Users",@("Modify, Synchronize"),"ContainerInherit, ObjectInherit","InheritOnly","Allow")

$objACL=Get-ACL $filename
$objACL.RemoveAccessRule($RMAccessRule)
$objACL.AddAccessRule($AddAccessRule1)
$objACL.AddAccessRule($AddAccessRule2)
set-acl $filename $objACL
}

Comments are closed.