diff --git a/File Server/FolderAudit.ps1 b/File Server/FolderAudit.ps1 index 9b3a43b..38c2a20 100644 --- a/File Server/FolderAudit.ps1 +++ b/File Server/FolderAudit.ps1 @@ -1,9 +1,11 @@ <# .SYNOPSIS - Audits a base directory for any form of unique/non-inherited permissions. + Audits a base directory for any form of unique/non-inherited permissions, + ignoring standard built-in administrative groups. .DESCRIPTION Loops through all subfolders, identifies where inheritance is blocked OR where explicit, non-inherited permissions exist, and exports them to a CSV. + Filters out Built-in Administrators and Domain Admins to reduce noise. .PARAMETER BaseDir The root directory path you want to scan. .PARAMETER ReportFolder @@ -38,7 +40,7 @@ if (-not (Test-Path $ReportFolder)) { Write-Host "Starting comprehensive permission audit on: $BaseDir" -ForegroundColor Cyan Write-Host "Results will be saved to: $OutputFile" -ForegroundColor Cyan -Write-Host "Scanning for blocked inheritance and explicit local permissions..." -ForegroundColor Yellow +Write-Host "Scanning for unique permissions (Ignoring Admin/Domain Admin groups)..." -ForegroundColor Yellow # Initialize array to hold results $Report = [System.Collections.Generic.List[PSCustomObject]]::new() @@ -57,17 +59,30 @@ foreach ($Folder in $AllFolders) { # 1. Check if inheritance is blocked ($true) $IsInheritanceBlocked = $Acl.AreAccessRulesProtected - # 2. Look specifically for any access rules applied directly to this folder (IsInherited -eq $false) - $ExplicitRules = $Acl.Access | Where-Object { $_.IsInherited -eq $false } + # 2. Extract explicit, non-inherited rules, FILTERING OUT standard admin accounts + # This matches "BUILTIN\Administrators", "NT AUTHORITY\SYSTEM", and any group ending in "Domain Admins" + $ExplicitRules = $Acl.Access | Where-Object { + $_.IsInherited -eq $false -and + $_.IdentityReference.Value -notmatch "BUILTIN\\Administrators" -and + $_.IdentityReference.Value -notmatch "Domain Admins" -and + $_.IdentityReference.Value -notmatch "NT AUTHORITY\\SYSTEM" + } - # If inheritance is blocked OR there are explicit rules present, we need to flag it + # We flag the folder IF: + # - Inheritance is blocked (regardless of rules, because the tree is broken here) + # - OR there are meaningful explicit rules left over after filtering out the admins if ($IsInheritanceBlocked -or ($ExplicitRules.Count -gt 0)) { - Write-Host "Found unique/non-inherited permissions: $($Folder.FullName)" -ForegroundColor Magenta - - # Extract names of users/groups with explicit, non-inherited access + # Extract names of remaining users/groups with explicit, non-inherited access $ExplicitAccessString = ($ExplicitRules | ForEach-Object { $_.IdentityReference.Value }) -join "; " + # If the folder only had Admin rules and inheritance wasn't blocked, skip it + if (-not $IsInheritanceBlocked -and [string]::IsNullOrEmpty($ExplicitAccessString)) { + continue + } + + Write-Host "Found unique/non-inherited permissions: $($Folder.FullName)" -ForegroundColor Magenta + # Determine the type of change for easy sorting in Excel/CSV $PermissionStatus = if ($IsInheritanceBlocked) { "Inheritance Blocked" } else { "Inheriting but has Explicit Local Rules" } @@ -77,7 +92,7 @@ foreach ($Folder in $AllFolders) { "Full Path" = $Folder.FullName "Permission Status" = $PermissionStatus "Inheritance Blocked"= $IsInheritanceBlocked - "Explicit Access" = $ExplicitAccessString + "Explicit Access" = if ($ExplicitAccessString) { $ExplicitAccessString } else { "Only Admin Groups Present" } "Last Modified" = $Folder.LastWriteTime }) }