Map folder permissions
This commit is contained in:
93
Functions/Get-FolderPermissionMapping.ps1
Normal file
93
Functions/Get-FolderPermissionMapping.ps1
Normal file
@@ -0,0 +1,93 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user