HOW: Modfy ACL based on folder name

I have a directory with thousands of folders.  Domain Users:  READ on this directory.
However, there are hundreds of subfolders in this direcotry named "Working".  Every folder named "Working" is supposed to have Domain Users: Modify.
How can I apply this permission to all subfolders named "WORKING" under the root?
bctekAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Chris DentPowerShell DeveloperCommented:

Hey Bctek,

Do you want to go any deeper into the folder structure than the Working folder?

And just to confirm, you have (something like) this:

Main Folder
       | -- Subfolder 1
       |          |--- Working
       | -- Subfolder 2
       |          |--- Working

Chris
0
bctekAuthor Commented:
hi Chris.  What I have is:

Main Folder
       | -- Subfolder 1
       |          |--- Working
       | -- Subfolder 2
       |          |--- Subfolder 3
       |          |          |--- Working
                             
0
bctekAuthor Commented:
there are numerous working sub folders at several different levels of depth under the Main Folder
0
Introducing the "443 Security Simplified" Podcast

This new podcast puts you inside the minds of leading white-hat hackers and security researchers. Hosts Marc Laliberte and Corey Nachreiner turn complex security concepts into easily understood and actionable insights on the latest cyber security headlines and trends.

Chris DentPowerShell DeveloperCommented:

Okay no problem.

This is VbScript and it looks far worse than it really is (honest). Please test thins on a small number of folders to make sure you're happy with what it does and that it works (you'll probably have to create Test folders, it's what I've done to make sure it works here).

Fill in the fields for <Folder Name> and <Server Name> then it'll run for every folder called "Working" from that point down.

Permission Inheritance is a bit of an odd one, but this has what I hope is the desired effect even if it doesn't quite make a lot of sense yet.

There are other tools that can be used to do this including XCACLS, I haven't used it because it has a great deal of trouble dealing with permission inheritance - if you'd prefer to use something like that then let me know and I'll make the changes.

Chris



Option Explicit

Const STARTING_FOLDER = "<Folder Name>"
Const FILE_SERVER = "<Server Name>"

' Constants

' Inheritance Flags

Const ENABLE = 1
Const COPY_AND_DISABLE = 2
Const REMOVE_AND_DISABLE = 3

Const SE_DACL_PRESENT = 4
Const SE_DACL_AUTO_INHERITED = 1024
Const SE_DACL_PROTECTED = 4096
Const SE_SELF_RELATIVE = 32768

' File System Access Flags

Const FSAF_OBJECT_INHERIT_ACE = 1
Const FSAF_CONTAINER_INHERIT_ACE = 2
Const FSAF_NO_PROPAGATE_INHERIT_ACE = 4
Const FSAF_INHERIT_ONLY_ACE = 8
Const FSAF_INHERITED_ACE = 16

' File System Access Types

Const FSAT_ACCESS_ALLOWED = 0
Const FSAT_ACCESS_DENIED = 1
Const FSAT_AUDIT = 2

' File System Access Masks

Const FSAM_FILE_READ_DATA = 1
Const FSAM_FILE_WRITE_DATA = 2
Const FSAM_FILE_APPEND_DATA = 4
Const FSAM_FILE_READ_EA = 8
Const FSAM_FILE_WRITE_EA = 16
Const FSAM_FILE_EXECUTE = 32
Const FSAM_FILE_DELETE_CHILD = 64
Const FSAM_FILE_READ_ATTRIBUTES = 128
Const FSAM_FILE_WRITE_ATTRIBUTES = 256
Const FSAM_DELETE = 65536
Const FSAM_READ_CONTROL = 131072
Const FSAM_WRITE_DAC = 262144
Const FSAM_WRITE_OWNER = 524288
Const FSAM_SYNCHRONIZE = 1048576

' Global Variables

Dim objFileSystem, objNetwork, objWMIServices, objFolder

'
' Subroutines
'

Sub TraverseFolders(objFolder)

      Dim objSubFolder, objParentDescriptor

      For Each objSubFolder in objFolder.SubFolders
            If InStr(1, objSubFolder.Name, "Working", VbTextCompare) Then
                  SetInheritance objSubFolder.Path, COPY_AND_DISABLE
                  SetSecurity objSubFolder.Path
            End If
            TraverseFolders(objSubFolder)
      Next
End Sub

Sub SetInheritance(strFolder, intInheritanceChange)

      Dim objSecuritySettings, objSecurityDescriptor, objACE
      Dim intControlFlags

      Set objSecuritySettings = objWMIServices.Get("Win32_LogicalFileSecuritySetting.Path='" & strFolder & "'")

      Select Case intInheritanceChange
            Case ENABLE
                  intControlFlags = SE_DACL_PRESENT + SE_DACL_AUTO_INHERITED + SE_SELF_RELATIVE
            Case COPY_AND_DISABLE
                  intControlFlags = SE_DACL_PRESENT + SE_DACL_AUTO_INHERITED + SE_SELF_RELATIVE
            Case REMOVE_AND_DISABLE
                  intControlFlags = SE_DACL_PRESENT + SE_DACL_PROTECTED + SE_SELF_RELATIVE      
      End Select
      
      Set objSecurityDescriptor = objWMIServices.Get("Win32_SecurityDescriptor").SpawnInstance_
      objSecurityDescriptor.ControlFlags = intControlFlags
      objSecuritySettings.SetSecurityDescriptor objSecurityDescriptor
      
      Set objSecuritySettings = Nothing
End Sub

Sub SetSecurity(strFolder)

      Dim objSecuritySettings, objSecurityDescriptor, objTrustee, objACE

      Set objSecuritySettings = objWMIServices.Get("Win32_LogicalFileSecuritySetting.Path='" & strFolder & "'")
      objSecuritySettings.GetSecurityDescriptor objSecurityDescriptor      

      Set objTrustee = GetObject("winmgmts://" & FILE_SERVER & "/root/cimv2:Win32_Trustee").Spawninstance_

      objTrustee.Domain = objNetwork.UserDomain
      objTrustee.Name = "Domain Users"
      
      Set objACE = objWMIServices.Get("Win32_Ace").SpawnInstance_
      objACE.Properties_.Item("trustee") = objTrustee
      
      objACE.Properties_.Item("accessMask") = FSAM_SYNCHRONIZE + FSAM_READ_CONTROL + _
                              FSAM_DELETE + FSAM_FILE_WRITE_ATTRIBUTES + _
                              FSAM_FILE_READ_ATTRIBUTES + FSAM_FILE_EXECUTE + _
                              FSAM_FILE_WRITE_EA + FSAM_FILE_READ_EA + _
                              FSAM_FILE_APPEND_DATA + FSAM_FILE_WRITE_DATA + _
                              FSAM_FILE_READ_DATA
                              
      objACE.Properties_.Item("aCEFlags") = FSAF_OBJECT_INHERIT_ACE + FSAF_CONTAINER_INHERIT_ACE
      objACE.Properties_.Item("aCEType") = FSAT_ACCESS_ALLOWED

      objSecurityDescriptor.Properties_.Item("DACL") = Array(objACE)

      objSecuritySettings.SetSecurityDescriptor objSecurityDescriptor
End Sub

'
' Main Code
'

Set objFileSystem = CreateObject("Scripting.FileSystemObject")
Set objNetwork = CreateObject("WScript.Network")

Set objWMIServices = GetObject("winmgmts://" & FILE_SERVER)

Set objFolder = objFileSystem.GetFolder(STARTING_FOLDER)
TraverseFolders(objFolder)
Set objFolder = Nothing

Set objWMIServices = Nothing

Set objNetwork = Nothing
Set objFileSystem = Nothing
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
bctekAuthor Commented:
Hi.  Thank you for trying to help me.  I went ahead and I tried your code, changing the first two lines:

Const STARTING_FOLDER = "QA"
Const FILE_SERVER = "BC4"

The folder "QA" is a shared folder on the server "BC4"

but it keeps returning with an error:
Line: 133
Char: 1
Error: Path not found
Code: 800A004C

so I went to line 132 and did this:
Set objFolder = objFileSystem.GetFolder("\\bc4\QA")

but it returns a new error:
Line:  76
Char:  6
Error:  Not Found
Code:  80041002





0
Chris DentPowerShell DeveloperCommented:

I haven't tested it working with Share level, only with a full path, i.e. C:\SomeFolder\QA.

Could you possibly try with that way? If it still doesn't work I'll have another look at the code and pick out what's wrong.

Chris
0
Walter PadrónCommented:
seems a little tricky, but it works ;)

Try this before to be sure this is the set of directories

for /F %i in ('dir /s /b /AD \\bc4\QA\*working*') do @echo %i

then

for /F %i in ('dir /s /b /AD \\bc4\QA\*working*') do @cacls %i /E /G "your_domain\Domain Users":C OI

C - Change
OI - Object Inherit. The ACE will be inherited by files.

cheers
0
bctekAuthor Commented:
Fabulous!  It worked....you saved me HOURS!  Thanks!
0
Chris DentPowerShell DeveloperCommented:

Pleasure :)

Chris
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
OS Security

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.