Working with NTFS permissions in PowerShell (Part 1)

In this first of two parts we will first briefly explain how NTFS permissions work. Then we will have a look at the ACL cmdlets which are available in PowerShell and finally we will examine the security descriptors a bit more in detail.

How do NTFS permissions work

On an NTFS file system all objects (files and directories) have security descriptors that control the access to them. The security descriptors contain information about the owner of the object, access to the object and auditing of this access.

In these security descriptors there is an Access Control List (ACL) in which the security permissions are defined. There are two types of ACLs:

  • Discretionary Access Control List (DACL): contains all the users and groups that are either allowed or denied access to the object.
  • System Access Control List (SACL): defines auditing of the object.

An entry in the ACL is called an Access Control Entry (ACE).

When a user is authenticated to a system, an Access Token (AT) is created. This AT contains a list of Security Identifiers (SID) linked to this user. Besides the SID of the user this also includes all the SIDs of the groups of which the user is a member.

When the user tries to access an object, the SIDs in the DACL of the object are compared against the SIDs in the AT of the user.

Basic functionality of the ACL cmdlets

Working with security descriptors in PowerShell is not that straightforward. There are two cmdlets available:

  • Get-Acl, which lets you retrieve the security descriptor of an object (obviously files and directories, but also registry entries, Active Directory objects, etc.).
  • Set-Acl, which enables you to modify the security descriptor of those objects.

When examining these two cmdlets with Get-Help, you will notice there is not a lot of options available. One would expect parameters to set permissions, users, etc. But they are nowhere to be found.

Let’s show a basic example of what we can do. Following command takes the ACL of the directory C:\Foo and applies it on the directory C:\Bar.

Get-Acl –Path "C:\Foo" | Set-Acl –Path "C:\Bar"

While useful, it’s not really very flexible. One would need to manually configure the permissions (with the GUI) on the first directory to be able to apply these permissions on the second directory in the command line.

Examining the security descriptors

In order to use the full power of the ACL cmdlets, we will need to dig a little deeper. Let’s see if we can get more details with the Get-Acl cmdlet.

# Create a new directory.
New-Item -ItemType Directory -Path C:\ -Name SuperSysAdmin

# Get the ACL of the directory and put it in a variable.
$ACL = Get-Acl -Path C:\SuperSysAdmin

# View the properties of the ACL object.
$ACL | Get-Member

This would give a result as in below screenshot.


On top we can confirm that our object is of the type System.Security.AccessControl.DirectorySecurity. Further down we see some interesting properties such as Access and Owner.

If we consult the Access property on our variable we can see all the users and groups and their respective permissions that are configured on our example directory. This is the same information you would see when consulting the Security tab in the GUI.

# View the Access properties of the ACL object.

This would give a result as in below screenshot.


Now let’s further break down what we are seeing. For each ACE in the ACL there are 6 properties displayed:

  • IdentityReference: This is the user or group to which the permissions are applied.
  • FileSystemRights: This property defines the actual permissions which are applied to the user. The most common we will find here are FullControl, Modify and ReadAndExecute. There is a whole variety of permissions we can apply, this is the same list we would see when going in the Advanced Security tab in the GUI. Full reference can be found at MSDN.
  • AccessControlType: This property controls to either allow or deny access. The two only options here are Allow or Deny. As you might know, be careful with the Deny flag as it always takes precedence on Allow. This can give you a lot of headaches if a user is nested in multiple groups. Full reference can be found at MSDN.
  • InheritanceFlags: This property defines to which kind of child objects will inherit the ACE. ContainerInherit means that child container objects (e.g. directories) will inherit the ACE. ObjectInherit means that child leaf objects (e.g. files) will inherit the ACE. Full reference can be found at MSDN.
  • PropagationFlags: This property defines how the ACE is propagated to child objects. Full reference can be found at MSDN.
  • IsInherited: This property indicates whether the ACE is inherited from the parent directory or not.

This concludes our introduction to working with NTFS permissions in PowerShell. In the second part we will apply this in some real life examples.

Leave a Reply

Your email address will not be published. Required fields are marked *