2
0
Files
PowershellScripts/File Server/FolderAudit.ps1
T

112 lines
5.0 KiB
PowerShell

<#
.SYNOPSIS
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
The directory path where the final CSV report should be saved.
.EXAMPLE
.\FolderAudit.ps1 -BaseDir "C:\CompanyData" -ReportFolder "C:\AuditReports"
#>
param (
[Parameter(Mandatory = $true, HelpMessage = "Enter the base directory path to scan.")]
[string]$BaseDir,
[Parameter(Mandatory = $false, HelpMessage = "Enter the folder path where the report should be saved.")]
[string]$ReportFolder = "C:\Temp\AuditReports"
)
# Generate timestamped filename (Format: ddMMyyyy-HHmm)
$TimeStamp = Get-Date -Format "ddMMyyyy-HHmm"
$ReportName = "Permission_Audit_$TimeStamp.csv"
$OutputFile = Join-Path -Path $ReportFolder -ChildPath $ReportName
# Verify directories exist
if (-not (Test-Path $BaseDir)) {
Write-Error "The specified base directory does not exist: $BaseDir"
exit
}
if (-not (Test-Path $ReportFolder)) {
Write-Host "Report folder does not exist. Creating it now: $ReportFolder" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $ReportFolder -Force | Out-Null
}
Write-Host "Starting comprehensive permission audit on: $BaseDir" -ForegroundColor Cyan
Write-Host "Results will be saved to: $OutputFile" -ForegroundColor Cyan
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()
# Get the base folder itself and all subfolders
$Folders = Get-ChildItem -Path $BaseDir -Recurse -Directory -ErrorAction SilentlyContinue
# Include the root folder in the audit
$AllFolders = @($GetItem = Get-Item $BaseDir) + $Folders
foreach ($Folder in $AllFolders) {
try {
# Get Access Control List (ACL) for the folder
$Acl = Get-Acl -Path $Folder.FullName
# 1. Check if inheritance is blocked ($true)
$IsInheritanceBlocked = $Acl.AreAccessRulesProtected
# 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"
}
# 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)) {
# 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" }
# Append data to our report object
$Report.Add([PSCustomObject]@{
"Folder Name" = $Folder.Name
"Full Path" = $Folder.FullName
"Permission Status" = $PermissionStatus
"Inheritance Blocked"= $IsInheritanceBlocked
"Explicit Access" = if ($ExplicitAccessString) { $ExplicitAccessString } else { "Only Admin Groups Present" }
"Last Modified" = $Folder.LastWriteTime
})
}
}
catch {
Write-Warning "Permission denied or error reading: $($Folder.FullName)"
}
}
# Export data to CSV
if ($Report.Count -gt 0) {
$Report | Export-Csv -Path $OutputFile -NoTypeInformation -Encoding UTF8
Write-Host "`nAudit complete! Found $($Report.Count) folders with unique/non-inherited permissions." -ForegroundColor Green
Write-Host "Results exported to: $OutputFile" -ForegroundColor Green
} else {
Write-Host "`nAudit complete. All subfolders are perfectly inheriting permissions." -ForegroundColor Green
}