112 lines
5.0 KiB
PowerShell
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 = "Non_Inherited_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
|
|
} |