locked
Recursively list all non-inherited permissions on a file path RRS feed

  • Question

  • Hello,

    I'm trying to write a script to recursively return all non-inherited permissions down the entire subtree of a given local path.

    So far I have the following:

        get-childitem -Directory "F:\" -recurse | get-acl | Where {$_.Access.IdentityReference -like "DOMAIN*"} |  Where {$_.Access.IsInherited -like "False"} | Ft -autosize -wrap

    Where DOMAIN would be replaced with the domain that I am interested in getting permissions information for, and F:\ is the path I'm interested in. These could be replaced with variables of course

    The problem with this is that the "where" items don't appear to be filtering anything out. I still see all local account privs and all the non-inherited items as well.

    Initially I want to use this output to audit the various permissions on fileserver shares, hence filtering out local account privs and inherited privs.

    After the initial audit I also want to redirect the output of this command to a text file that I can bring into a source control system, reporting on daily diffs to show the changes in permissions from day to day.

    At that point the only requirements for output format will be that it includes all the relevant data, and that it be deterministic (things don't jump around)

    Any help would be appreciated.

    Thanks!

       -Brian Marshall

    Tuesday, August 22, 2017 5:20 PM

All replies

  • $false is not a string.  It is a Boolean.

    Look in the Gallery for scripts that do what you are asking: https://gallery.technet.microsoft.com/

    Please read this first: This forum is for scripting questions rather than script requests  
    Also find scripts here: http://gallery.technet.microsoft.com


    \_(ツ)_/

    Tuesday, August 22, 2017 5:27 PM
  • I've used this in the past for doing the same thing; it doesn't filter out local accounts, you can either add that or just filter it manually in Excel after.  it outputs to a CSV file on the desktop of whoever runs it.  Just put the share(s) you want to check in the $shares array.

    $shares = @(<share 1>, <share 2>)
    
    $csvOut = "$($env:USERPROFILE)\desktop\Working_permissions.csv"
    $output = @()
    
    foreach ($share in $shares) {
        $folder = Get-Item $share
        $acl = get-acl $folder.FullName
        foreach ($access in $acl.access) {
            $output += [pscustomobject][ordered]@{
                'Share' = $share
                'Folder' = $folder.name
                'User' = $access.identityreference
                'Permissions' = $access.FileSystemRights
                'ParentPath' = $folder.Parent.FullName
            }
        }
    
        $folders = Get-ChildItem -Path $share -Directory -Recurse
        foreach ($folder in $folders) {
        try {
            $acl = get-acl $folder.fullname
            if ($acl.access.isinherited -eq $false) {
                foreach ($access in $acl.access) {
                    $output += [pscustomobject][ordered]@{
                        'Share' = $share
                        'Folder' = $folder.name
                        'User' = $access.identityreference
                        'Permissions' = $access.FileSystemRights
                        'ParentPath' = $folder.Parent.FullName
                    }
                }
            }
        } catch { $output += [pscustomobject][ordered]@{ 
                    'Share' = $share
                    'Folder' = $folder
                    'User' = '???'
                    'Permissions' = '???' 
                    'ParentPath' = $folder.Parent.FullName
                } 
            }
        }
    } 
    $output | Export-Csv -Path $csvOut -NoTypeInformation
    • Edited by kdcooke Tuesday, August 22, 2017 7:58 PM
    Tuesday, August 22, 2017 7:15 PM
  • Check the below scripts may help you:

    DIR "C:\temp" -directory -recurse | GET-ACL | where {$_.Access.IsInherited -eq $false}


    Get-ChildItem C:\temp -recurse | Select @{Name='Path';Expression={$_.FullName}},@{Name='InheritedCount';Expression={(Get-Acl $_.FullName | Select -ExpandProperty Access | Where { $_.IsInherited }).Count}} | Where { $_.InheritedCount -eq 0 } | Select Path

    Source: https://stackoverflow.com/questions/25126877/getting-names-of-folders-that-do-not-inherit-permissions

    List file permissions that are not inherited: https://community.spiceworks.com/topic/493582-list-file-permissions-that-are-not-inherited

    Also, check this auditing solution to get current effective permissions on your file server and audit changes in the permissions of files and folders: https://www.lepide.com/lepideauditor/file-server-auditing.html

    Hope you find this helpful.

    Wednesday, August 23, 2017 6:33 AM
  • Hello, unfortunately this script doesn't scan recursively and only show the folder specified in the first variable
    Wednesday, March 6, 2019 1:24 PM
  • This script does recursively scan for me.  However, if inheritance is turned ON for a folder, AND that folder has additional explicit ACLs, this script would miss it.  A very small change fixed that.

        foreach ($folder in $folders) {
        try {
            $acl = get-acl $folder.fullname
            foreach ($access in $acl.access) {
                 if ($access.isinherited -eq $false) {
                    $output += [pscustomobject][ordered]@{
                        'Share' = $share
                        'Folder' = $folder.name
                        'User' = $access.identityreference
                        'Permissions' = $access.FileSystemRights
                        'ParentPath' = $folder.Parent.FullName
                    }
                }
            }

    The original code only checked for the isinherited flag for the first ACL returned for the folder object.  And if so, it assumed all the ACLs for that object were inherited.

    Granted, I'm sure this change will slow down the script considerably on large file systems.

    Thursday, January 23, 2020 4:14 PM
  • Another "gotcha", this script will choke on long file paths.

    Found the solution here: https://stackoverflow.com/a/46309524

    Read the link for full details and prerequesites.

    #GPEdit location:  Configuration>Administrative Templates>System>FileSystem 
    Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1

    But you also need to use -LiteralPath instead of -Path

    get-childitem -LiteralPath '\\?\C:\Very long path' -Recurse 
    get-childitem -LiteralPath '\\?\UNC\127.0.0.1\c$\Very long path\' -Recurse
    $shares = @("<share>")
    
    $csvOut = "$($env:USERPROFILE)\desktop\Working_permissions.csv"
    $output = @()
    
    foreach ($share in $shares) {
        $folder = Get-Item -LiteralPath $share
        $acl = get-acl $folder.FullName
        foreach ($access in $acl.access) {
            $output += [pscustomobject][ordered]@{
                'Share' = $share
                'Folder' = $folder.name
                'User' = $access.identityreference
                'Permissions' = $access.FileSystemRights
                'ParentPath' = $folder.Parent.FullName
            }
        }
    
        $folders = Get-ChildItem -LiteralPath $share -Directory -Recurse
        foreach ($folder in $folders) {
        try {
            $acl = get-acl $folder.fullname
            foreach ($access in $acl.access) {
                 if ($access.isinherited -eq $false) {
                    $output += [pscustomobject][ordered]@{
                        'Share' = $share
                        'Folder' = $folder.name
                        'User' = $access.identityreference
                        'Permissions' = $access.FileSystemRights
                        'ParentPath' = $folder.Parent.FullName
                    }
                }
            }
        } catch { $output += [pscustomobject][ordered]@{ 
                    'Share' = $share
                    'Folder' = $folder
                    'User' = '???'
                    'Permissions' = '???' 
                    'ParentPath' = $folder.Parent.FullName
                } 
            }
        }
    } 
    $output | Export-Csv -Path $csvOut -NoTypeInformation

    Thursday, January 23, 2020 4:50 PM