3

Executive summary: I want to find all the directories and files a particular user or group has access to.

In more detail: I'm looking for a command-line tool to recursively search an NTFS directory for all files and directories where an ACE in the DACL contains a given user or group. If I wanted to modify permissions, I would use subinacl or SetACL. I thought I would be able to use one of these tools to search and display, too, but I'm having trouble finding a straight-forward solution.

I could use SetACL like so:

   setacl -on C:\SOME_DIR -ot file -actn list -lst "f:tab;w:d;i:y;" -rec cont

and then grep for the user of interest, but I'd like a more elegant solution. I'm probably missing something here. Any ideas?

  • 1
    You're probably not going to find an elegant solution since it's such an inelegant problem. I would've recommended SetACL, so you're already where I'd recommend you being. (I once had somebody ask me to write a tool to audit and "report" on file permissions on a 6TB 10,000,000+ file shared folder hierarchy. I pointed them at SetACL and said "Good luck-- I wouldn't touch that w/ a 10 foot pole.") – Evan Anderson Sep 3 '09 at 23:25
5

Thanks, "unknown". Your PowerShell script doesn't work for me, but I hacked together something that does. I'm new to it, too, but after some trial and error:

Get-ChildItem "C:\SOME\DIR" -recurse | 
    ForEach-Object { 
        $fname = $_.FullName
        $acl = Get-Acl $fname
        foreach ($e in $acl.Access) {
            If ( -not $e.IsInherited -and
                 $e.AccessControlType -eq "Allow" -and 
                 $e.IdentityReference -eq "SOMEDOMAIN\Somegroup") 
            {
                Write-Host $fname
                break
            }
        }
    }

Somebody with PowerShell kungfu could probably clean this up a bit. Note that I have it ignore inherited entries, because I'm only interested in knowing where the access begins.

| improve this answer | |
  • Finally getting back to this. So that's not a bad solution, but the problem I run into is that it fails for filenames containing wildcard characters, e.g.: Get-Acl : The specified wildcard pattern is not valid: foo[bar.txt I've tried escaping $fname before I use it in the call to Get-Acl, but so far (using "-replace '[[]]', '``$0'", for example) without success. – David Aug 13 '10 at 18:54
3

Untested, and a little new to powershell, but something like this would write it to screen. From there you could dump it to a file or whatever.

Get-ChildItem "RootFolderPath" -recurse | 
    ForEach-Object { 
        $acl = Get-Acl $_.FullName
        If $acl.ContainsKey "User/Group" {Write-Host $_.FullName}
    }
| improve this answer | |
  • Will this work if you don't have access to some of the files as administrator? – Zoredache Sep 3 '09 at 21:29
  • Nope. PS is going to use whatever credientials you run it with, and if that account doesnt have the correct permissions on the file/folder then it won't be able to read the permissions/acl from the file/folder. – user10711 Sep 3 '09 at 21:33
  • 1
    Nothing will work in that scenario. The account which runs it will need at least Read Permissions rights and Traverse Folder access on the folders you're recursing through. – squillman Sep 3 '09 at 21:37
  • @squillman: You might be able to do it with "Backup Operators" rights, the BackupFile APIs, and a strong enough will to parse opaqua binary data streams. >smile< That aside, I agree with you. – Evan Anderson Sep 3 '09 at 23:23
1

one-liner, but without inheritance filter, 'cause it checks AccessToString Property.

Get-ChildItem "C:\SOME\DIR" -recurse|foreach{if((Get-Acl $_.FullName).AccessToString -like "*DOMAIN\username*"){write-host $_.FullName}}
| improve this answer | |
  • If this answer is correct, it'd be nice to explain what it does :-) – ckujau Aug 27 '19 at 19:46
  • 1
    Sure. First of all i left "-notlike" instead of like, because I'm using it in the opposite way of what is requested here and i forgot to modify in in "-like" before answering. Now the explanation : loop on all subfolders and files, if the current item-ACL's Accesstostring property is LIKE the username, then print out its name. – ienaxxx Aug 29 '19 at 5:18
  • AccessToString property is a text representation of the ACL. – ienaxxx Aug 29 '19 at 5:23
0

Would accessenum work for your use-case, I wonder?

| improve this answer | |
  • The problem there is that it looks like you can't filter for a specific user or group. – David Sep 4 '09 at 19:40
0

Here is a powershell script I modifed from above that worked for me:

$files = @()
Get-ChildItem "d:\some\path" -recurse | 
    ForEach-Object { 
        $fname = $_.FullName
        if ($fname -notlike "*_vti*") {
            $acl = Get-Acl $($fname)
            foreach ($e in $acl.Access) {
                If ( $e.FileSystemRights -like "*Modify*" -and 
                     $e.IdentityReference -eq "domain\user") 
                {
                    $files += $fname
                    break
                }
            }
        }
    }
$files > d:\out.txt
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.