How to assign NTFS permissions to group on several repeated folders hierarchy?

Hi all,

I know this will sound complicated to some of  you but i'll try my best to deliver my request in an easy method. Now, there is file server running windows server 2008 and this server is running different shares for different departments. In brief, i am working on one of the shares called "BSD" and the folder hierarchy looks like the following:

BSD (Share)
       -------  Contracts
                  -------  01 Agreements
                               --------  101-200
                               --------  201-300
                                            .............
                               --------  901-1000

Under every agreement, there are folders like the following;

101-200
    -------  POST-Contract
    -------  PRE-Contract

201-300
      ------- POST-Contract
      ------- PRE-Contract.

....... etc.

Now, i need to apply certain AD groups for every Post Contract and Pre Contract on every agreement. By doing this thing manually, it will really be a boring job and i think i will get myself killed someday cuz of this manual job :). However, i need a script or tool to help me to complete this job automatically by just double clicking the script.

I thought about using the Subinacl tool but actually if you look at it , you will find that you need to build a subinacl line for each group in each folder which means the task is still manual because if you calculate the time of building the subinacl batch file and the time of doing the task manually , they will be the same time. :(

VBScript will be fine in this job if you tell the script to look at a repeated folders name (such as Post Cont and Pre Cont) under each agreement and assign those groups to each of them, it will be great.

Note: 101-200
          201-300
         ...etc
these are called agreements folders to not to confuse you.

Appreciate your fast response relally on this one.

Thanks

LVL 1
amyasseinAsked:
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.

amyasseinAuthor Commented:
Sorry i forgot to mention the other complicated side of this task regarding the assigning permissions.

Actually, when the script assigns permissions to groups, i need it to replace any existing objects in the folder's ACL by the groups that i mention in the script. Also, i need it to clear the inheritance of the folder after replacing the existing ACL and to propagate the permissions to subfolders as well.

For example,

When i right click the Post-Contract folder and hit security, there will be users and groups exists, i need to clear them and replace them with the groups that i mention in the script and also to clear inheritance of that folder as well as propagate those new groups to subfolders.

If i really can give this request 800 points to you, i would do that but actually this is the experts exchange limitation :)

Thanks a lot
0
slemmesmiCommented:
Dear amyassein,

did you check out icacls http://technet.microsoft.com/en-us/library/cc753525(WS.10).aspx ?

You're runing Windows Server 2008 - icacls may be the solution for you.

Kind regards,
Soren
0
slemmesmiCommented:
Dear amyassein,

Forgot - if you have PowerShell feature added on your Windows Server 2008, you can also do the above using the set-acl CmdLet:
http://technet.microsoft.com/en-us/library/dd315261.aspx

Kind regards,
Soren
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

amyasseinAuthor Commented:
slemmesmi, thanks for your nice response but let me clarify thing.

Subinacl, ICACLS,XCACLS and Set Acl PS command are still manual methods. In other words, you have to write a command line for each repeated folder under each agreement and compine them in a single batch file or execute them seprarately. As i mentioned, the time of doing this is the same time for doing the task manually using Windows GUI.

VBScript , however, is a code with many facilities (such as If Else, Looping, ...etc) so it can look under each agreement folder and search for repeated folders such as Post and Pre Contract folders in a dynamic way. By the way, i am not a scripting geek but i have only the basics that's why i can't create complicated scripts and ask for help here.

Thanks

0
amyasseinAuthor Commented:
I request a BIG attention to this question please.
0
Chris DentPowerShell DeveloperCommented:

> it will really be a boring job and i think i will get myself killed someday cuz of this manual job :)

heh I know exactly what you mean :)

Would you go with PowerShell for this? You're right that it can be done in VbScript but it's a hell of a lot easier in PowerShell.

Chris
0
amyasseinAuthor Commented:
Chris,

Can you shed some light and help me how to do this using PS ? .... As you know, i am not a PS/VBS scripting geek like you :)

I'd appreciate if you can write some PS code to do this job.

Thanks
A.Y.
0
amyasseinAuthor Commented:
I found a solution using PS but still need manual attention :-(

What i did is, i piped a security ACL of an existing Post-Contract folder to every post contract under every agreement. See below:

PS C:\>get-acl -path "\\server01\bsd\contracts\01 Agremments\201-300\201 folder\post-contract" | set-acl -path "\\server01\bsd\contracts\01 Agremments\201-300\202 folder\post-contract"

Then, i use the UP arrow again to recall the previous command and modify the new folder to "203 folder" till "300 folder"

I am dying here :) lol

0
amyasseinAuthor Commented:
Chris, Any update ?
0
Chris DentPowerShell DeveloperCommented:

Oh, sorry, I didn't mean to leave you hanging.

> What i did is, i piped a security ACL of an existing Post-Contract folder to every post contract under every agreement.

Is this what you need to maintain? Apply a template ACL to every instance of Post-something?

Chris
0
amyasseinAuthor Commented:
Hi Chris,

No i meant that i set a permission in one Post-contract folder under one of the agreements and instead of doing this manually on every Post-Contract, i am simply copying the permissions from that folder to the other Post-Contract folders by using Pipe. However, the procedure still manual which means i need everytime to hit the UP arrow to recall the previous command and change the path to the other Post-Contract folders.

If possible, i need a help to write a code (PS or VBS whatever) to look for these Post-Something folders and to see permission on them.

Thanks
0
Chris DentPowerShell DeveloperCommented:

That should be quite easy :)

This will find Post- folders:


Get-ChildItem -Filter "Post-*" -Recurse | ?{ $_.PsIsContainer }


So what we need to do is:


# Load the template ACL
$Acl = Get-Acl "\\server01\bsd\contracts\01 Agremments\201-300\201 folder\post-contract"
# Find Post folders
Get-ChildItem -Filter "Post-*" -Recurse | ?{ $_.PsIsContainer } | %{
  # Apply the ACL
  Set-Acl $_.FullName -AclObject $Acl
}


Of course I'm sure you'll want to test that quite carefully :)

Chris
0
amyasseinAuthor Commented:
I meant to set permissions on them not see permissions on them :)
Sorry
0
Chris DentPowerShell DeveloperCommented:

heh I had to go back and look, some kind of auto-correct running in my head I'd read it as Set :)

Chris
0
amyasseinAuthor Commented:
Chris,

I saved the above code in a .ps1 file the i run the below command:

c:\my scripts>.\bsd
c:\my scripts>

However, nothing happened when it finished and no errors shown.

Thanks
0
amyasseinAuthor Commented:
And also to mention, i replaced the server01 by the actual server name in the UNC path and i am sure the path is correct.
0
amyasseinAuthor Commented:
Ok ... what i understood from this code is, it will get the current ACL in the "201 folder\post-contract" folder. However, i couldn't understand it will paste this ACL where ? ...
0
Chris DentPowerShell DeveloperCommented:

> However, nothing happened when it finished and no errors shown.

I didn't have it write any output, nothing above generates it so the script, if you use it as one, will run silently.

But I guess it didn't make any changes?

Here's a more advanced version for you :)

Get-Help ./WhateverYouCalledTheScript.ps1
Get-Help ./WhateverYouCalledTheScript.ps1 -Full

Then to run:

./WhateverYouCalledTheScript.ps1 "\\Server\Share" -Filter "Post-*" -Template "\\server01\bsd\contracts\01 Agremments\201-300\201 folder\post-contract" -Verbose -WhatIf

And if it looks good, drop -WhatIf.

Chris
<#
  .Synopsis
    A short script to update permissions.
  .Description
    This script takes a template ACL and applies that to any folders it finds
    in a directory structure.

    This script also supports Verbose and WhatIf parameters.
  .Parameter Path
    The folder structure to search.
  .Parameter Filter
    A filter string used when searching for folders.
  .Parameter TemplatePath
    The path used to read a template access control list.
#>

[CmdLetBinding(SupportsShouldProcess = $True)]
Param(
  [Parameter(Mandatory = $True, Position = 0)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$Path,
  [String]$Filter,
  [Parameter(Mandatory = $True)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$TemplatePath
)

# Load the template ACL
$Acl = Get-Acl $TemplatePath

Write-Verbose "Beginning folder search from $Path"

Get-ChildItem $Path -Filter $Filter -Recurse | ?{ $_.PsIsContainer } | %{

  Write-Verbose "Modifying access control list on $($_.FullName)"

  If ($PsCmdLet.ShouldProcess($($_.FullName))) {
    # Apply the ACL
    Set-Acl $_.FullName -AclObject $Acl
  }
}

Open in new window

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
amyasseinAuthor Commented:
Oh my God Chris !! How did you do that ? .... You a real GEEEk !! hehe

It works extremely fine now but i have couple of questions:

1- Is this will going apply the permissions recursively to all subfolders and files to the destination Post-Contract folders in each agreement ?

2- If i want to work also on Pre-Contract folders, do i just need to replace the "Post-*" by "Pre-*" in the command?

Note: i said destination because now the command got a source and destination, source that get the ACL from and destination to apply that ACL to. :)))))

Cheers
0
Chris DentPowerShell DeveloperCommented:

> You a real GEEEk !! hehe

Yes, yes I am :) Scripting is just little logic puzzles, keeps me from being bored :)

1. No, it sets the template and relies on you having Inheritance set.

2. Yes :)

Chris
0
amyasseinAuthor Commented:
Ok i need now one small thing ...

Can we make the code to just replace any existing ACEs with the ACEs that is being copied? ... In other words, i want all the subfolders/files under Post-Contract to be replaced by the ACEs from source.

Thanks Man , appreciate it.
0
Chris DentPowerShell DeveloperCommented:

Hmm you can, but that means you lose inheritance, and that in turn makes permissions very high maintenance. Are you really sure you want that?

It would be better, in my opinion, to disable inheritance on Pre / Post (in the template), then rely on inheritance for everything beneath those folders.

Chris
0
amyasseinAuthor Commented:
Good Point ! but no worries because this actually an access restriction project requested by some department which means that the same groups will access all the Post and Pre contracts folders and their subfolders which also means nobody else will be granted access to those folders.

The problem now is when you view the security of one of the subfolder under Post-contract or Pre-contract , you will notice that there are still other groups which inherited from the top parent (shared folder) and i don't want them there. I want only those groups that are copied from source.

0
amyasseinAuthor Commented:
Also, if i need in the future to turn on inheritance to one of the subfolders, Xcacls is the right tool for this job. :))))
0
Chris DentPowerShell DeveloperCommented:

Ah in that case you need to disable inheritance on your template. If you're doing that in code it means setting AccessRuleProtection.

e.g.

$TemplateAcl = Get-Acl $TemplateFolder
$TemplateAcl.SetAccessRuleProtection($True, $False)

The second argument tells it to remove existing entries when turning off rule protection.

You should only need to do that once in your template acl, not on everything else.

Chris
0
amyasseinAuthor Commented:
Chris, as you know, i am not a Geek like you :)) so can you re-write the code and include those 2 new lines in it?

Thx
0
Chris DentPowerShell DeveloperCommented:

Well you don't really need to because you only have to disable inheritance there once you see :)

Chris
0
amyasseinAuthor Commented:
Chris, Sorry maybe i mis-described my request.

Instead of turning off Inheritance, can we simply turn on the "Replace all existing inheritable permissions on all descendants with inhetitable permissions in this object" on every Post-contract and Pre-Contract folder? .... By this way, the code will not only apply permissions copied from source but will also take these permissions and override all the subfolders permissions.

You know what i mean ? :)
0
Chris DentPowerShell DeveloperCommented:

I do :)

Lets see how this gets on for that then.

Chris
<#
  .Synopsis
    A short script to update permissions.
  .Description
    This script takes a template ACL and applies that to any folders it finds
    in a directory structure.

    This script also supports Verbose and WhatIf parameters.
  .Parameter Path
    The folder structure to search.
  .Parameter Filter
    A filter string used when searching for folders.
  .Parameter TemplatePath
    The path used to read a template access control list.
#>

[CmdLetBinding(SupportsShouldProcess = $True)]
Param(
  [Parameter(Mandatory = $True, Position = 0)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$Path,
  [String]$Filter,
  [Parameter(Mandatory = $True)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$TemplatePath
)

# Load the template ACL
$Acl = Get-Acl $TemplatePath

Write-Verbose "Beginning folder search from $Path"

Get-ChildItem $Path -Filter $Filter -Recurse | ?{ $_.PsIsContainer } | %{

  Write-Verbose "Modifying access control list on $($_.FullName)"

  If ($PsCmdLet.ShouldProcess($($_.FullName))) {
    # Apply the ACL
    Set-Acl $_.FullName -AclObject $Acl

    # Deal with inheritance down the tree
    Get-ChildItem $_.FullName -Recurse | %{
      $ChildAcl = $_.FullName
      # Re-enable inheritance
      $ChildAcl.SetAccessProtection($False, $False)
      # Remove any entries which have been defined here (leaving inherited entries)
      $ChildAcl.Access | 
        ?{ $_.IsInherited -eq $False } | 
        %{ $ChildAcl.RemoveAccessRuleSpecific($_) }
      # Re-apply the ACL
      Set-Acl $_.FullName -AclObject $ChildAcl
    }
  }
}

Open in new window

0
amyasseinAuthor Commented:
Ok i got the below error:

Set-Acl : Cannot bind parameter 'AclObject'. Cannot convert the "C:\test\800-9
0\POST-Contract\New Text Document.txt" value of type "System.String" to type "
ystem.Security.AccessControl.ObjectSecurity".
At C:\my scripts & tools\test_bsd.ps1:51 char:37
+       Set-Acl $_.FullName -AclObject <<<<  $ChildAcl
    + CategoryInfo          : InvalidArgument: (:) [Set-Acl], ParameterBinding
   Exception
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerSh
   ell.Commands.SetAclCommand
0
Chris DentPowerShell DeveloperCommented:

Ooops :)

Chris
<#
  .Synopsis
    A short script to update permissions.
  .Description
    This script takes a template ACL and applies that to any folders it finds
    in a directory structure.

    This script also supports Verbose and WhatIf parameters.
  .Parameter Path
    The folder structure to search.
  .Parameter Filter
    A filter string used when searching for folders.
  .Parameter TemplatePath
    The path used to read a template access control list.
#>

[CmdLetBinding(SupportsShouldProcess = $True)]
Param(
  [Parameter(Mandatory = $True, Position = 0)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$Path,
  [String]$Filter,
  [Parameter(Mandatory = $True)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$TemplatePath
)

# Load the template ACL
$Acl = Get-Acl $TemplatePath

Write-Verbose "Beginning folder search from $Path"

Get-ChildItem $Path -Filter $Filter -Recurse | ?{ $_.PsIsContainer } | %{

  Write-Verbose "Modifying access control list on $($_.FullName)"

  If ($PsCmdLet.ShouldProcess($($_.FullName))) {
    # Apply the ACL
    Set-Acl $_.FullName -AclObject $Acl

    # Deal with inheritance down the tree
    Get-ChildItem $_.FullName -Recurse | %{
      $ChildAcl = Get-Acl $_.FullName
      # Re-enable inheritance
      $ChildAcl.SetAccessProtection($False, $False)
      # Remove any entries which have been defined here (leaving inherited entries)
      $ChildAcl.Access | 
        ?{ $_.IsInherited -eq $False } | 
        %{ $ChildAcl.RemoveAccessRuleSpecific($_) }
      # Re-apply the ACL
      Set-Acl $_.FullName -AclObject $ChildAcl
    }
  }
}

Open in new window

0
amyasseinAuthor Commented:
I got this new one too : )

Method invocation failed because [System.Security.AccessControl.FileSecurity]
oesn't contain a method named 'SetAccessProtection'.
At C:\my scripts & tools\test_bsd.ps1:45 char:36
+       $ChildAcl.SetAccessProtection <<<< ($False, $False)
    + CategoryInfo          : InvalidOperation: (SetAccessProtection:String) [
   ], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
0
Chris DentPowerShell DeveloperCommented:

The trouble with doing things from memory without testing ;)

Chris
<#
  .Synopsis
    A short script to update permissions.
  .Description
    This script takes a template ACL and applies that to any folders it finds
    in a directory structure.

    This script also supports Verbose and WhatIf parameters.
  .Parameter Path
    The folder structure to search.
  .Parameter Filter
    A filter string used when searching for folders.
  .Parameter TemplatePath
    The path used to read a template access control list.
#>

[CmdLetBinding(SupportsShouldProcess = $True)]
Param(
  [Parameter(Mandatory = $True, Position = 0)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$Path,
  [String]$Filter,
  [Parameter(Mandatory = $True)]
  [ValidateScript( { Test-Path $_ } )]
  [String]$TemplatePath
)

# Load the template ACL
$Acl = Get-Acl $TemplatePath

Write-Verbose "Beginning folder search from $Path"

Get-ChildItem $Path -Filter $Filter -Recurse | ?{ $_.PsIsContainer } | %{

  Write-Verbose "Modifying access control list on $($_.FullName)"

  If ($PsCmdLet.ShouldProcess($($_.FullName))) {
    # Apply the ACL
    Set-Acl $_.FullName -AclObject $Acl

    # Deal with inheritance down the tree
    Get-ChildItem $_.FullName -Recurse | %{
      $ChildAcl = Get-Acl $_.FullName
      # Re-enable inheritance
      $ChildAcl.SetAccessRuleProtection($False, $False)
      # Remove any entries which have been defined here (leaving inherited entries)
      $ChildAcl.Access | 
        ?{ $_.IsInherited -eq $False } | 
        %{ $ChildAcl.RemoveAccessRuleSpecific($_) }
      # Re-apply the ACL
      Set-Acl $_.FullName -AclObject $ChildAcl
    }
  }
}

Open in new window

0
amyasseinAuthor Commented:
Chris,

I think that's enough talking and bothering you anymore as the above script is the real final one that exactly suits my needs. I really want to thank you for your valuable efforts and if i have more than 1000 points to give you , i would do that but this is the EE points limitation. (Max 500)

Thanks Man , keep up the excellent work !

 
0
Chris DentPowerShell DeveloperCommented:

You're welcome :)

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
Windows Server 2008

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.