93 lines
3.7 KiB
PowerShell
93 lines
3.7 KiB
PowerShell
Set-StrictMode -Version Latest
|
|
|
|
function Get-FolderPermissionMapping {
|
|
<#
|
|
.SYNOPSIS
|
|
Audits folder permissions, focusing on explicit entries and "break points" in inheritance.
|
|
#>
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
|
|
[string]$Path
|
|
)
|
|
|
|
process {
|
|
# 1. Path Validation
|
|
if (-not (Test-Path $Path)) {
|
|
Write-Error "The path '$Path' does not exist or is unreachable."
|
|
return
|
|
}
|
|
|
|
# 2. Setup Directory Structure
|
|
$ReportPath = Join-Path -Path $PSScriptRoot -ChildPath "Reports"
|
|
if (-not (Test-Path $ReportPath)) {
|
|
New-Item -Path $ReportPath -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
$Timestamp = Get-Date -Format "yyyyMMdd-HHmm"
|
|
$FullFilePath = Join-Path -Path $ReportPath -ChildPath "PermissionAudit_$Timestamp.csv"
|
|
|
|
Write-Host "--- Starting Audit on $Path ---" -ForegroundColor Cyan
|
|
Write-Verbose "Output File: $FullFilePath"
|
|
|
|
# 3. Get Local Shares
|
|
$LocalShares = Get-CimInstance -ClassName Win32_Share | Select-Object Name, Path
|
|
|
|
# 4. Define the Processing Logic (Reusable for Root and Subfolders)
|
|
$ProcessFolder = {
|
|
param($TargetFolder)
|
|
try {
|
|
$Acl = Get-Acl -Path $TargetFolder.FullName -ErrorAction Stop
|
|
|
|
# IMPORTANT: We look for ANY entry that is NOT inherited.
|
|
# These are the "Differences" from the parent.
|
|
$ExplicitAccess = $Acl.Access | Where-Object { -not $_.IsInherited }
|
|
|
|
if ($ExplicitAccess) {
|
|
$MatchingShare = $LocalShares | Where-Object { $TargetFolder.FullName -like "$($_.Path)*" } | Select-Object -First 1
|
|
$ShareName = if ($MatchingShare) { $MatchingShare.Name } else { "Local/Sub-Folder" }
|
|
|
|
foreach ($Access in $ExplicitAccess) {
|
|
[PSCustomObject]@{
|
|
LocalPath = $TargetFolder.FullName
|
|
ShareName = $ShareName
|
|
Identity = $Access.IdentityReference
|
|
Rights = $Access.FileSystemRights
|
|
Inheritance = if ($Acl.AreAccessRulesProtected) { "Disabled" } else { "Enabled (Mixed)" }
|
|
} | Export-Csv -Path $FullFilePath -Append -NoTypeInformation -Encoding utf8
|
|
}
|
|
return $true
|
|
}
|
|
}
|
|
catch {
|
|
Write-Warning "Could not read ACL for: $($TargetFolder.FullName)"
|
|
}
|
|
return $false
|
|
}
|
|
|
|
# 5. Execution
|
|
$FoundCount = 0
|
|
|
|
# Step A: Check the Root Folder first
|
|
Write-Host "Checking Root: $Path" -ForegroundColor Gray
|
|
$RootObj = Get-Item -Path $Path
|
|
if (& $ProcessFolder $RootObj) { $FoundCount++ }
|
|
|
|
# Step B: Scan all subfolders
|
|
Write-Host "Scanning subfolders (this may take time)..." -ForegroundColor Gray
|
|
Get-ChildItem -Path $Path -Recurse -Directory -ErrorAction SilentlyContinue | ForEach-Object {
|
|
if (& $ProcessFolder $_) {
|
|
$FoundCount++
|
|
# Visual feedback every time we find a unique folder
|
|
Write-Host "[Found Unique] $($_.Name)" -ForegroundColor Green
|
|
}
|
|
}
|
|
|
|
if (Test-Path $FullFilePath) {
|
|
Write-Host "--- Audit Complete! ---" -ForegroundColor Cyan
|
|
Write-Host "Results saved to: $FullFilePath" -ForegroundColor White
|
|
} else {
|
|
Write-Host "Scan finished, but no folders with unique/explicit permissions were found." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
} |