Filed under Windows
Tagged as PowerShell Windows Security NTFS
Changing NTFS permissions with PowerShell saves a lot of time when you need to make changes to a large group of files or when it is required as part of a larger automation project. This article should help you understand everything you need to know to manipulate security permissions with PowerShell.
When changing ownership of files or folders you must run PowerShell as an Administrator. Everything here will work in Windows PowerShell 5, but not PowerShell 6 as of this writing – specifically, the SetAccessControl() method does not exist in PowerShell 6.
We are going to use the
Get-Acl cmdlet to view the current ACL. Running it in PowerShell will give the following output.
Our primary focus in this article will be on the Owner and Access objects. We can see from this example that
WIN-UBFNHEQ8GII\Administrator is the owner and we have three Access rules granting FullControl.
Ownership is pretty simple. Ownership is assigned to one user or group and there are no additional details.
Access Right Details
We can see a more detailed description of the access rules by selecting them specifically using this command
(Get-Acl .\Directory\).Access. Now we can see which permissions were inherited and the InheritanceFlags and PropagationFlags. These latter two will be important when we start modifying rules.
Before we can set an object’s ACL we need to build one. The easiest way to do that is to save the current ACL in a variable and then modify it. To do that we’ll just assing the output of
Another option would be to create a completely new, and empty, ACL object like this:
Now that we have our ACl object we can make modifications. Once we’ve made the desired changes we have to apply it back to the directory or our changes will be lost.
Setting the owner in the ACL is almost as simple as viewing it. We will use the
SetOwner() method on the ACL. This method takes one argument of type
System.Security.Principal.NTAccount so first we need to create an object of that type and then we can set the owner.
However, there are two limitations when setting ownership via PowerShell.
- We need to be running powershell as Administrator.
- We can only set the owner to the user currently running PowerShell or
Remember, we haven’t changed anything on the filesystem yet. We’ve only modified our
When creating access rules we will want to specify inheritance flags also. When doing so we have four options. You will most likely want to set both the
ContainerInheritance and the
ObjectInheritance flags. This indicates that we want our permission to be propagated to all child directories and files.
|ContainerInherit||Propagate to child containers (directories).|
|None||Do not propagate this permission to any child containers or objects.|
|ObjectInherit||Propagate to child objects (files).|
In addtion to Inheritance Flags we can also set Propagation Flags. The default Windows behavior is
None. See the table below for more detail on the three Propagation Flag options. Setting this flag to
InheritOnly will cause the access rule to only apply to child objects of the container.
|InheritOnly||Specifies that the ACE is propagated only to child objects. This includes both container and leaf child objects.|
|None||Specifies that no inheritance flags are set.|
|NoPropagateInherit||Specifies that the ACE is not propagated to child objects.|
Flag Combinations and Effect
The table below details how a rule will be apply to the current object and child objects based on the flags set in the access rule.
|Access Rule Applies To||Inheritance Flags||Propagation Flags|
|Subfolders and Files only||ContainerInherit,ObjectInherit||InheritOnly|
|This Folder, Subfolders and Files||ContainerInherit,ObjectInherit||None|
|This Folder, Subfolders and Files||ContainerInherit,ObjectInherit||NoPropagateInherit|
|This folder and Subfolders||ContainerInherit||None|
|This Folder and Files||ObjectInherit||None|
|This Folder and Files||ObjectInherit||NoPropagateInherit|
|This Folder only||None||None|
Access Control Types
There are only two access control types.
Deny. Allow means we are allowing the permission, e.g., we are allowing a user to write to this directly. Deny will specifically deny a right, and takes precedence over Allow permissions. So, if a user has a Modify/Allow entry and also a Read/Deny that user will have all Modify rights except read.
Be sure to verify a principal’s effective access when using
When we talk about basic permissions we are talking about the primary checkboxes available when looking at the security tab in a file system object’s Properties dialog.
Here is a table of basic permissions that can be set via PowerShell, and the rights each will grant.
|FullControl||Specifies the right to exert full control over a folder or file, and to modify access control and audit rules. This value represents the right to do anything with a file and is the combination of all rights in this enumeration.|
|Modify||Specifies the right to read, write, list folder contents, delete folders and files, and run application files. This right includes the ReadAndExecute right, the Write right, and the Delete right.|
|ReadAndExecute||Specifies the right to open and copy folders or files as read-only, and to run application files. This right includes the Read right and the ExecuteFile right.|
|Read||Specifies the right to open and copy folders or files as read-only. This right includes the ReadData right, ReadExtendedAttributes right, ReadAttributesright, and ReadPermissions right.|
|Write||Specifies the right to create folders and files, and to add or remove data from files. This right includes the WriteData right, AppendData right, WriteExtendedAttributes right, and WriteAttributes right.|
List folder contents is not in the table above. While this can be set via PowerShell it will show up under Special permissions as
List folder / read data.
Adding Basic Permissions
To add new rights to a folder we will need to first create a file system rule, and then we can add it to our current set of
$acl. There are two methods we can use to either add or set a rule.
SetAccessRule() vs AddAccessRule()
The first method is
SetAccessRule(). When using
SetAccessRule() our new rule will overwrite any existing rule of the same type (Allow or Deny) for that security principal (user or group) regardless of the existing permissions. If a user has Modify permission and a new rule is created using
SetAccessRule() specifying Read permission that user will now only have Read permission. This method essentially removes any existing access an replaces that access with the specified rule.
The second method is
AddAccessRule(). This method will add this access rule to the ACL. Here if a user has Modify permission and we use
AddAccessRule() to create a new rule with Read permission the user will still have Modify permissions. This can be dangerous from a security perspective if we think we intend to limit a user’s access, but mistakenly use the
My suggestion is always use
SetAccessRule() and specify all intended permissions when making ACL changes.
Creating A New FileSystem Access Rule
Now that we understand inheritance flags, basic permissions, and the methods used to add a rule to our
$acl we are ready to create a new filesystem rule. This is a two step process. First we create our rule, and then we will apply it to our
Here’s what we need to create the rule.
The code block above creates a new object of type
System.Security.AccessControl.FileSystemAccessRule with the following parameters:
After creating the rule we can apply it to our
$acl object using the
Again, we haven’t modified the filesystem yet. We’ve only modified our
$acl object. Next let’s look at how to apply our
$acl object to a filesystem object.
Removing A FileSystem Access Rule
To remove an existing access rule you should use the
RemoveAccessRule() method. This is very straightfoward once you understand how to create an access rule. To remove a rule it must already be part of the
$acl object. Generally you would loop through these to find the rule you wanted and assign it to a variable. Then you can call
$acl.RemoveAccessRule($rule) to remove the rule from the
Here is a simple example to illustrate. This example demonstrates create an ACL object, create a rule, listing the access rules in our ACL object, and then removing the access rule from the ACL object.
Saving the ACL Changes
To avoid a bug in
Set-Acl we will be using the
SetAccessControl() method to save our permissions. If we need to be compatible with PowerShell 6 we must use
Set-Acl, but you may experience odd behavior after using it and from personal experience I don’t recommend using
What we are going to do instead is use the
SetAccessControl() method of the
DirectoryInfo class to apply our ACL.
To do this we can use Get-Item and then call
SetAccessControl() on the returned object.
Putting all the steps together we can get or create an ACL object, add a rule, and apply that rule to a file system object. The code block below shows all three steps together.
A basic right such as Modify can be thought of as a group of special permissions. Special permissions are more detailed rights that can be assigned rather than using the pre-defined basic rights groups. For instance, if you want to allow a principal to create files, but not directories that can be accomplished using special rights. These type permissions are only viewable in the GUI via the Advanced button on the Security tab.
At first, it may take some experimentation to get the desired rights when dealing with advanced permissions. Be sure to test these settings thoroughly to be sure everything behaves as intended.
Now, using the example above let’s grant a user
CreateFiles permission only. This will allow a user to read the directory tree and files, but only allow them to paste new files into the folders. As you can see in the table below the
CreateFiles permission does not grant
AppendData which is needed to change data in an existing file. Also, once the user creates/moves a file into this directory they will be unable to delete it.
Table of Special Permissions
|AppendData||Specifies the right to append data to the end of a file.|
|ChangePermissions||Specifies the right to change the security and audit rules associated with a file or folder.|
|CreateDirectories||Specifies the right to create a folder.|
|CreateFiles||Specifies the right to create a file.|
|Delete||Specifies the right to delete a folder or file.|
|DeleteSubdirectoriesAndFiles||Specifies the right to delete a folder and any files contained within that folder.|
|ExecuteFile||Specifies the right to run an application file.|
|ListDirectory||Specifies the right to read the contents of a directory.|
|ReadAttributes||Specifies the right to open and copy file system attributes from a folder or file. For example, this value specifies the right to view the file creation or modified date. This does not include the right to read data, extended file system attributes, or access and audit rules.|
|ReadData||Specifies the right to open and copy a file or folder. This does not include the right to read file system attributes, extended file system attributes, or access and audit rules.|
|ReadExtendedAttributes||Specifies the right to open and copy extended file system attributes from a folder or file. For example, this value specifies the right to view author and content information. This does not include the right to read data, file system attributes, or access and audit rules.|
|ReadPermissions||Specifies the right to open and copy access and audit rules from a folder or file. This does not include the right to read data, file system attributes, and extended file system attributes.|
|Synchronize||Specifies whether the application can wait for a file handle to synchronize with the completion of an I/O operation.|
|TakeOwnership||Specifies the right to change the owner of a folder or file. Note that owners of a resource have full access to that resource.|
|Traverse||Specifies the right to list the contents of a folder and to run applications contained within that folder.|
|WriteAttributes||Specifies the right to open and write file system attributes to a folder or file. This does not include the ability to write data, extended attributes, or access and audit rules.|
|WriteData||Specifies the right to open and write to a file or folder. This does not include the right to open and write file system attributes, extended file system attributes, or access and audit rules.|
|WriteExtendedAttributes||Specifies the right to open and write extended file system attributes to a folder or file. This does not include the ability to write data, attributes, or access and audit rules.|
That covers the building blocks of modifying NTFS permissions with powershell. I would love feed back so please feel free to send questions, corrections, or general comments about the article to firstname.lastname@example.org.