Weekend Scripter: Use PowerShell to Get, Add, and Remove NTFS Permissions


Summary: Microsoft PFE, Raimund Andree, talks about using Windows PowerShell to get, add, and remove permissions.

Microsoft Scripting Guy, Ed Wilson, is here. Today we have Microsoft Premier Field Engineer, Raimund Andree, back to talk about using Windows PowerShell to work with permissions…

Managing file and folder permissions in Windows PowerShell is not that easy, and there are numerous articles and blog posts describing how it works by using the .NET classes. This is far from being comfortable, and there is one major and one minor restriction:

  • Path length
  • Generic rights

This post introduces the NTFSSecurity module, which provides a bunch of cmdlets for managing permissions on NTFS drives. It does not use the Windows PowerShell way to access the file system, and it works around the MAX_PATH, which is 260 characters. (For more information, see Naming Files, Paths, and Namespaces). This is achieved thanks to AlphaFS.

This post examines displaying permissions and granting users permission.

Installation

You can download the module from the Script Center Repository: File System Security PowerShell Module 3.2.1. Please unblock the file before extracting it.

For more information about installing Windows PowerShell modules, see Hey, Scripting Guy! How Can I Install Windows PowerShell Modules on Multiple Users' Computers?

Some background

Windows stores the permissions in the discretionary access control list (DACL), which is part of the Security Descriptor. The Security Descriptor also includes the system access control list (SACL), where the auditing is configured, and member information. This post is about permissions and it does not discuss the SACL or member information.

The DACL contains access control entries (ACEs) that define the permissions someone has on the object. Each ACE contains the following values:

  • Account: Who is granted or denied access. Windows does not store the user’s SamAccountName, but rather, the SID.
  • Rights: The permissions granted or denied.
  • Type: Grant or deny access.
  • IsInherited: True if the ACE is inherited from a parent object.
  • InheritanceFlags and PropagationFlags: These bits control the inheritance. The NTFSSecurity module converts the bits into something more readable that is discussed later in this post.

By default, a security descriptor on the file system inherits permissions from the parent object. Users who have full access on drive C also have full access to all subfolders if the inheritance is not disabled.

Managing permissions

Reading the permissions of a single item

The first and easiest task is to retrieve the DACL from a specific file. The cmdlet that the NTFSSecurity module provides for retrieving existing permissions is Get-NTFSAccess. You can pipe a file or folder to that cmdlet or work with the Path parameter:

Get-Item D:\Data | Get-NTFSAccess

Get-NTFSAccess -Path D:\Data

The output might look like this:

Image of command output

The output is grouped by the file or folder, which is important when getting the permissions of more than one object. Next to the path is information about if the file or folder inherits the permissions from the parent object. My example shows that four of the displayed ACEs have been inherited from drive D.

Some more details about the columns:

  • Account: The account that has been granted or denied access to the item. As mentioned, Windows does not store the user’s name, but rather, the SID. If the SID can be translated into the name, NTFSSecurity shows it; otherwise, the SID is displayed.
  • AccessRights: These are the actual permissions that the account has been granted or denied. The list behind this field also supports generic rights.
  • Applies to: The .NET Framework stores the inheritance information in two-bit fields: InheritanceFlags and PropagationFlags. These fields are quite difficult to interpret, so NTFSSecurity converts them into something that is known from the Windows Explorer:
    • ThisFolderOnly
    • ThisFolderSubfoldersAndFiles
    • ThisFolderAndSubfolders
    • ThisFolderAndFiles
    • SubfoldersAndFilesOnly
    • SubfoldersOnly
    • FilesOnly
  • Type: Either Allow or Deny
  • Inherited: If the ACE is inherited from the parent, this is True. The first two ACEs have been defined explicitly in the folder.
  • InhertedFrom: This column only contains information if IsInherited is True, and it indicates where the ACE is inherited from.

Reading the permissions of multiple items

All NTFSSecurity cmdlets support pipelining. If you need to get the permissions from multiple items, you do not need to run a ForEach loop. You can simply pipe the files and folders to Get-NTFSAccess.

dir C:\Data | Get-NTFSAccess

Get-NTFSAccess provides ways to filter the ACEs. A common scenario is to get the ACEs of a specific account or only those that have not been inherited.

If you want to display only permissions that have been added explicitly and hide all the inherited permissions, use the ExcludeInherited switch:

dir | Get-NTFSAccess –ExcludeInherited

If you want to display only the permissions assigned to a certain user, use the Account parameter:

dir | Get-NTFSAccess -Account raandree9\randr_000

Note  This displays the permissions as defined in the ACL. This is not the effective permissions. Effective permissions will be discussed in an upcoming post.

Granting access

Granting access to a file or folder is also quite easy to do by using the Add-NTFSAccess cmdlet. Add-NTFSAccess provides the following parameters:

  • Account: This can be a user account name (SamAccountName) or a SID. The user account name has to contain the domain (domain\username). Built-in SIDs are also supported, such as Everyone, NT AUTHORITY\SYSTEM, or BUILTIN\Administrators. For more information, see Well-known security identifiers in Windows operating systems.
  • AccessRights: This parameter takes one or more of file system rights, for example, FullControl, Modify, or Read. If you want to assign multiple rights, provide them in a comma-separated list.

Note  Use Tab expansion or the ISE to get a list of all available values.

  • AccessType: Allow or deny
  • AppliesTo: This parameter sets the scope of the ACE. The options are the same as Windows Explorer provides. By default (when not defined), the scope is ThisFolderSubfoldersAndFiles.

Note  Use Tab expansion or the ISE to get a list of all available values.

  • PassThru: By default, the cmdlet does not return any data. If the PassThru switch is used, the cmdlet displays the ACL after adding the ACE.

The next commands give the well-known group, Authenticated Users, read access to the folder C:\Data. The built-in administrators and the local group, Editors, are getting full control:

Add-NTFSAccess -Path C:\Data `

    -Account 'NT AUTHORITY\Authenticated Users' `

    -AccessRights Read

 

Add-NTFSAccess -Path C:\Data `

    -Account 'BUILTIN\Administrators', 'raandree9\Editors' `

    -AccessRights FullControl

Removing access

Removing access is similar to adding permissions. The command Remove-NTFSAccess takes the same parameters as Add-NTFSAccess.

To remove a user from the ACL, provide the path, the account name, and the permissions you want to remove, for example:

Remove-NTFSAccess D:\Data -Account RAANDREE0\randr_000 -AccessRights Read -PassThru

If the user has different permissions than those you want to remove, nothing happens. There needs to be an exact match.

Note  You cannot remove inherited permissions. Get-NTFSAccess informs about the source of the inherited permissions where the respective ACE can be changed or removed.

Remove-NTFSAccess accepts pipeline input. If you want to remove all permissions for a certain user account, you can read the permissions first and then pipe the results to Remove-NTFSAccess. This operation can also run reclusively:

Get-ChildItem -Path d:\ -Recurse |

    Get-NTFSAccess -Account raandree0\randr_000 -ExcludeInherited |

    Remove-NTFSAccess

Note  The cmdlets in the NTFSSecurity module do not provide a way to process files and folders reclusively. You have to use Get-ChildItem or Get-ChildItem2 with the Recurse switch. (The Get-ChildItem2 cmdlet is part of the NTFSSecurity module, and it will be discussed in a future post.)

NTFS inheritance

After you set permissions on a parent folder, new files and subfolders that are created in the folder inherit these permissions. If you do not want them to inherit permissions, set ApplyTo to “ThisFolderOnly” when you set special permissions for the parent folder. In cases where you want to prevent certain files or subfolders from inheriting permissions, disable (or block) the inheritance.

There are two types of permissions:

  • Explicit permissions: Set by default when the object is created by user action.
  • Inherited permissions: Propagated to an object from a parent object. Inherited permissions ease the task of managing permissions and ensure consistency of permissions among all objects within a given container.

To add an ACE that does not affect any child elements, use the following command:

Add-NTFSAccess .\Data -Account raandree1\install -AccessRights Modify -AppliesTo ThisFolderOnly

If the AppliesTo parameter is not used, the ACE applies to “ThisFolderSubfoldersAndFiles,” like when using the Windows Explorer to add permissions. All child elements will inherit the ACE created by the following command:

Add-Access -Path .\Data -Account BUILTIN\Administrators -AccessRights FullControl

To verify which child items have inherited the ACE, you can get and pipe all child elements recursively to Get-NTFSAccess. With the following command, Windows PowerShell reads only the inherited ACEs that are assigned to the built-in administrators group that are inherited from D:\Data:

dir -Recurse | Get-NTFSAccess -Account BUILTIN\Administrators -ExcludeExplicit | Where-Object InheritedFrom -eq 'D:\Data' 

Image of command output

The next post will explore how to report, enable, and disable inheritance in folders (the NTFSSecurity module provides the same feature as the Windows Explorer). I will also discuss taking ownership of files without losing the ACL.

~Raimund

Thank you, Raimund, for an awesome blog post.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (22)

  1. Mayday IT says:

    This looks like an awesome tool, but when using gci -recurse, I still get the pathtoolongexception. The documentation mentions something about the AlphaFS library adding extra dir2, etc. commands, but after importing ntfssecurity, the additional commands
    don’t exist, and if I try importing the AlphaFS module directly, it shows up as binary with no attached commands. If I didn’t have so many folders to go through it would have turned into most of my scripting experience – waste a day trying to figure it out
    only to wind up doing it manually anyway!

  2. Anonymous says:

    Great! Can you give some more info on the 260 chars path problem?

  3. Phil says:

    Ed, This looks like something I could use to solve a problem we have, but I am not sure how to script it. Somehow a tech added the Domain Users group to the security permissions of the entire Home folders share. So now we need to remove the Domain Users
    from all users home folders without removing or replacing the exist permissions (where each user home folder has the specific user allowed but nothing else). Do you know of a way to fix this?

  4. Paolo says:

    there is a newer version 3.2.2 that allow more than 30000 chars in path

  5. Dyensky Dorsainville says:

    I work at an environment where we have multiple users accessing their own network folder on our network. All users folder belong to this parent folder call userfolder. Now if permission was altered and everyone seems to lost access to their own folder,
    how can you write a script to grant each users their own access to their own folders so they can access their files?

  6. Edwin says:

    Works like a charm. Perfect!!

  7. Brent says:

    Is there any way to pass the "foreach" loop to add permission? I want to create a bunch of directories using a CSV file, then add permissions using that same CSV, and finally sharing out the directory, again, using that same CSV – adding the permissions
    is critical to his script, but it doesn’t work using the "foreach "loop.

  8. Frank Mbanusi says:

    Hi,

    I commented out the New-Item line for creating the new directory since my users already have a home path set. That works fine for updating permissions on my migrated domain users (Interforest Migration). It fails, however when there is no path present for the
    home folder. Is there a way to skip users if the path to a home folder does not exist for a user, and go ahead updating the rest of the users in the OU?

    Thanks,

    Frank

  9. ali says:

    This was one of the best i have ever seen
    Thank you so much.
    Is there any way to replace a user with another user?

  10. Frank says:

    The term ‘get-ntfsaccessinheritance’ is not recognized as the name of a cmdlet
    Which version of powershell does this requiered? I’m running powershell from Win 8.1 pro

  11. Neil says:

    Having a problem importing the module:

    PS C:Usersadminuser> Import-Module NTFSSecurity
    Import-Module : The following error occurred while loading the extended type data file:
    Microsoft.PowerShell, C:UsersadminuserDocumentsWindowsPowerShellModulesNTFSSecurityNTFSSecurity.types.ps1xml : Fi
    le skipped because it was already present from "Microsoft.PowerShell".
    Microsoft.PowerShell, C:UsersadminuserDocumentsWindowsPowerShellModulesNTFSSecurityNTFSSecurity.types.ps1xml : Fi
    le skipped because it was already present from "Microsoft.PowerShell".
    At line:1 char:14
    + Import-Module <<<< NTFSSecurity
    + CategoryInfo : InvalidOperation: (:) [Import-Module], RuntimeException
    + FullyQualifiedErrorId : FormatXmlUpateException,Microsoft.PowerShell.Commands.ImportModuleCommand

  12. Jeff25 says:

    This script works well though I am having an issue setting permissions to a UNIX share that is configured to use NTFS permissions. The rights are assigned and look perfect yet I can’t access the share with the specified account. If I add the account using
    the exact same effective permissions it works perfectly. Is there a way to fully detail all permissions enabled rather than the small field under the "Access Rights" field in the console output.

  13. Martin says:

    I made and started script, it adds some permissions but they don’t work UNTIL I click on some of them, change it, apply, change it back and apply again. After this process it works. But I can’t find why?! Is there any "/FORCE" magic spell? Restart PC didn’t
    help, restart server didn’t help, waiting 24hours didn’t help. I have to change anything then undo on every single folder I share with different permissions (160 folders and increasing).
    Any help please?

  14. ryan says:

    Same issues here as Martin, used a csv file to apply permissions on 500+ folders at various levels, you can see the permissions in the GUI, effective access shows correct access, get-ntfspermissions and get-ACL show the correct permissions. Yet when a
    user clicks on the folder it says ACCESS DENIED. addiing a dummy permmission in the GUI then removing it and hitting apply fixes the issue for that particular folder only. Without manually doing this for over 500 folders I dont know what else to do. Seems
    like a massive bug as the same wthing occurs when using SET-ACL. THis is on Server 2012 R2. Please help.

  15. jeremy says:

    In order to assign Read and Execute or Modify rights you need to use -AccessRights Modify, Synchronize. Make sure that Synchronize is added as a right or it will not work.

  16. ryan says:

    Thanks Jeremey, that fixed the issue

  17. sanjeev says:

    I have tried the Get-NTFSAccess command on windows 2012, its not working getting below error

    Get-NTFSAccess : The term ‘Get-NTFSAccess’ is not recognized as the name of a cmdlet, function, script file, or operable program

  18. Titan says:

    Using Add-NTFSAccess to grant Modify permissions to an ACE which already has Read Only access is straight forward and appears to work fine.

    PS C:> Get-NTFSAccess c:xxxmjt | Format-List

    Name : xxxmjt
    FullName : c:xxxmjt
    InheritanceEnabled : False
    InheritedFrom :
    AccessControlType : Allow
    AccessRights : ReadAndExecute, Synchronize
    Account : NT AUTHORITYAuthenticated Users
    InheritanceFlags : ContainerInherit, ObjectInherit
    IsInherited : False
    PropagationFlags : None
    AccountType :

    PS C:> Add-NTFSAccess C:xxxmjt -Account "NT AUTHORITYAuthenticated Users" -AccessRights CreateDirectories,CreateFiles,Write,WriteAttributes,Delete -PassThru

    Path: C:xxxmjt (Inheritance disabled)

    Account Access Rights Applies to Type IsInherited InheritedFrom
    ——- ————- ———- —- ———– ————-
    NT AUTHORITYAuthenticated Users Modify, Synchronize ThisFolderSubfoldersAn… Allow False
    BUILTINAdministrators FullControl ThisFolderSubfoldersAn… Allow False

    However, removing permissions does not appear to do anything.

    PS C:> Remove-NTFSAccess -Path C:xxxmjt -Account "NT AUTHORITYAuthenticated Users" -AccessRights CreateDirectories,CreateFiles,Write,WriteAttributes,Delete -PassThru

    Path: C:xxxmjt (Inheritance disabled)

    Account Access Rights Applies to Type IsInherited InheritedFrom
    ——- ————- ———- —- ———– ————-
    NT AUTHORITYAuthenticated Users Modify, Synchronize ThisFolderSubfoldersAn… Allow False
    BUILTINAdministrators FullControl ThisFolderSubfoldersAn… Allow False

    Am I missing something ?

  19. Titan says:

    I understand that there needs to be an exact match when using Remove-NTFSAccess, the question is why. My previous comment "Am I missing something" was the wrong thing to say. Is there anything in the PowerShell toolkit that can remove permissions from
    an existing ACE in the same way that Add-NTFSAccess can grant permissions to an existing ACE ?.

  20. mikhail says:

    Hi!
    You module really helped me with folder management on fileserver but I still can’t remove BUIL IN Users from NTFS permissions. I disable Inheritance and got 2 BUILT In "SERVER/USERS" group with, when I try delete them from server with command :

    Get-ChildItem -Path "\file01.domain.named$$NTFSGroup" -Recurse |
    Get-NTFSAccess -Account "FILE01.TEOREMA.INFOUsers" |
    Remove-NTFSAccess

    I get the message that "Get-NTFSAccess" Can’t translate "Account" Can’t tanslate "FILE01.domain.nameUsers" value ti "Security2.IdentityReference2" type.

    Where I am wrong? Thank you

  21. adam says:

    How can I pipe out the "Applies To" table displayed by running Get-NTFSAccess, as the values are not displayed with the format set by NTFSSecurity. Display SubfolderandFilesOnly vs the InheritanceFlags and PropagationFlags.

  22. kuraara says:

    Hey Scripting Guy, If powershell is so great, why on Earth aren’t modules like this built in to the framework by default?

Skip to main content