Search code examples
powershellaclfileserver

List all folders, where users (except admin) have allow full access


At our company file server we used to have loose permissions several years ago. Meaning, there are folders where users tend to have full permission. This is a bad thing (user playing with rights, locking out the system (and the backup with it) and only giving themselves access.

My goal:

Scan the fileserver folder by folder (files would be too much) and output

  • folder full path
  • Security Identity Reference

if someone has fullaccess besides domain admins or system.

The output would be fine as:

Path, ACL
E:\share\projectfolder, Domain\10JohnDoe
E:\share\commonfolder, Domain\Everyone
...

This is what I have, but it is not nearly enough:

##define variable
$path = "E:\Share"
## begin script

foreach ($file in Get-Childitem $path -Recurse -Directory) {
    if (Get-Acl $file.FullName |
        select -ExpandProperty Access |
        where {$_.IdentityReference -notlike "AT\Domain Admins" -and
            $_.IdentityReference -notlike "NT AUTHORITY\SYSTEM" -and
            $_.AccessControlType -like "Allow" -and
            $_.FileSystemRights -like "FullControl"}
    ) {
        Write-Host $file.FullName >> e:\check_acl.txt
        Get-Acl $file.FullName |
            select -ExpandProperty Access |
            where {$_.IdentityReference -notlike "AT\Domain Admins" -and
                $_.IdentityReference -notlike "NT AUTHORITY\SYSTEM" -and
                $_.AccessControlType -like "Allow" -and
                $_.FileSystemRights -like "FullControl"
            } >> e:\check_acl.txt
    }
}

But I guess, I cannot get the output (into file!) like that.


Solution

  • Write-Host only displays text to the console, it can't be saved. Get-Acl >> check_acl.txt will write the whole "object" and not just the identityreference. What you want is to create a custom object with a Path and ACL (identityreference)-property and export it to csv.

    I've also simplified your identity-exclusion and changed the if-test to a foreach-loop so you don't have to run the whole Get-ACL-line twice.

    Try this:

    ##define variable
    $path = "E:\Share"
    $ExcludeUsers = 'AT\Domain Admins','NT AUTHORITY\SYSTEM','AT\AT-IT','AT\01STREW','AT\01BRUND','AT\01KNAFP','AT\01BECKC'
    ## begin script
    
    #Create regex-pattern to match all excluded users
    $ExcludeUsersRegex = ($ExcludeUsers | % { [regex]::Escape($_) }) -join '|'
    
    
    Get-Childitem $path -Recurse -Directory | ForEach-Object {
        $file = $_
    
        Get-Acl -Path $file.FullName |
        Select-Object -ExpandProperty Access |
        Where-Object {$_.IdentityReference -notmatch $ExcludeUsersRegex -and $_.AccessControlType -eq "Allow" -and $_.FileSystemRights -eq "FullControl"} |
        ForEach-Object {
            #Foreach ACL
            New-Object psobject -Property @{
                Path = $file.FullName
                ACL = $_.IdentityReference
            }
        }
    } | Select-Object -Property Path, ACL | Export-Csv e:\check_acl.csv -NoTypeInformation
    

    Sample output:

    "Path","ACL"
    "C:\Users\frode\Desktop\TEST\YES","CONTOSO\frode"
    "C:\Users\frode\Desktop\TEST\YES","CONTOSO\FrodesOtherAccount"