ACL

The need for this information came when I had a file server crash and for some reason lost all ACLs on all user’s home directory folders. The thought of having to manually reassign user rights to over 4000 parent folders was a daunting task. I quickly jumped into PowerShell and began scripting, trying to find a good way to set ACLs. Using a combination of PowerShell cmdlets and .NET I discovered a great way to apply ACLs to a folder, files, and sub-folders.

First thing first! What’s the difference between an ACE and an ACL? Well an ACL (Access Control List) is a list of ACEs (Access Control Entries). The picture below shows this. The item outlined in red is an ACE. There are 6 ACEs on this folder which make up the ACL of the folder, outlined in orange.

Let’s have a look at the particular section of the script that applies ACLs and then we’ll break each line down.

Control Rights

This is where we set the Control Rights we want the user to have on the folders, files, and sub-folders we are working with. For our purposes we want the user to have full control of all items so we’ll be using the FullControl member name. A list of other member names and their description can be found at the MSDN post.

Inheritance and Propagation Flags

This is where things get tricky. The next two lines specify inheritance and propagation of the control rights we specified in the first line. Specifying different Inheritance and Propagation flag combinations will provide completely different results.

Access Control Type

Next we must specify the Access Control Type. This is how we specify if we want to Allow or Deny the control rights we specified in the first line. In our case we want to Allow the user access to all folders, sub-folders, and files:

Creating ACE and User

So we’ve specified lots of information so far: Control Rights, Inheritance, Propagation, and Access Control. Now we need to specify who we want all these items to apply to. We’ll do this by creating a new object which specifies the users domain account name in the format DomainUserName. For our purposes we will use TestDomainJakeAlbarelli.

You can see we combine the User, Control Rights, Inheritance, Propagation, and Access Control into a single object.

Apply the ACE

To apply ACLs in PowerShell we’ll be using the Set-ACL cmdlet. It’s important to note that by default the Set-ACL cmdlet will REPLACE all ACEs on a folder or file, it does not append them. This means that we should get the current ACLs of the folder and add our new ACE to that list. This is what the last three lines actually do.

First we get the ACL of the target folder:

PowerShell

1

$CurrentACL=Get-ACL"\ExampleTestFolder"

Now we’ll use the AddAccessRule method to add the ACE we previously created:

1

$CurrentACL.AddAccessRule($ObjectACE)

Finally we will use the Set-ACL cmdlet to reapply the original ACLs plus our new entry:

PowerShell

1

Set-ACL"\ExampleTestFolder"$CurrentACL

And there you have it! That’s all you need to apply ACEs and ACLs to folders.

The Real World

Obviously this is a lot of code to do a simple task one time. As I stated at the beginning of the post, I created this code to reapply rights to thousands of folders and use a similar snippet for other automation purposes.

Imagine your AD gets wiped out and you must rebuild it or perhaps the ACLs somehow get wiped from your user’s home directories, trust me I’ve seen it happen. Maybe you just want to apply different rights other than full access.

Here is an example where we find all users in Active Directory that have a path in their HomeDirectory field and then we apply that user rights to its own HomeDirectory.

Say your organization isn’t using the HomeDirectory path in Active Directory but uses a different method to connect users to their files. Image your users’ username and foldername match and that all your home directories are stored in a common folder. This script will run through each of the user folders, create an ACE for the corresponding AD account, and then apply that ACE to the folder. I’ve included a regex to only get folders that have a name matching a certain format.

PowerShell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

<#

THIS SCRIPT WORKS ON THE ASSUMPTION THAT ALL

USER'S FOLDERS ARE IN A SINGLE DIRECTORY AND

THAT THE USER'S FOLDERNAME AND SamAccountName

MATCH. THE FIRST IF STATEMENT VERIFIES THE

FOLDER IS PROPERLY NAMED TO MATCH A USER ACCOUNT.

#>

#CLEAR ERRORS

$ERROR.Clear()

#IMPORT ACTIVE DIRECTORY MODULE

Import-ModuleActiveDirectory

#GET USER FOLDERS

$Folders=Get-ChildItem"\ServerNameFolderName"-Directory

#START FOREACH LOOP

foreach($Folderin$Folders)

{

#IF STATEMENT TO CHECK THAT THE FOLDER MATCHES THE EMPLOYEE ID STRUCTURE

#THIS PREVENTS THE WRONG FOLDERS FROM BEING PROCESSED

if($Folder.Name-match"^[br]{1}[0-5]{2,5}$")

{

$UserName=$Folder.Name#SET USERNAME TO FOLDERNAME

$FolderPath=$Folder.FullName#SET FOLDERPATH TO THE FOLDERPATH

#CHECK IF A MATCHING ACTIVE DIRECTORY USER ACCOUNT EXISTS, IF NOT THEN SKIP