4

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?

David
  • 243
  • 2
  • 3
  • 10
  • 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 03 '09 at 23:25

5 Answers5

6

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.

David
  • 243
  • 2
  • 3
  • 10
  • 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
4

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}
    }
user10711
  • 432
  • 1
  • 4
  • 9
  • Will this work if you don't have access to some of the files as administrator? – Zoredache Sep 03 '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 03 '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 03 '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 03 '09 at 23:23
2

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}}
ienaxxx
  • 121
  • 3
  • 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 05:18
  • AccessToString property is a text representation of the ACL. – ienaxxx Aug 29 '19 at 05:23
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
syntax53
  • 11
  • 1
0

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

tomfanning
  • 3,378
  • 7
  • 34
  • 34