Public/inherit-permissions.ps1
|
# inherit-permissions.ps1 # Resets NTFS ACL on a folder so it inherits from its parent again. Useful # when someone has added explicit Allow/Deny entries (often after a # copy-paste between volumes) that block proper access. # # Two-step flow: # 1. Re-enable inheritance, preserving currently-inherited rules so the # folder doesn't lose access while transitioning. # 2. Optionally strip the explicit (non-inherited) ACEs that remain. # # Pure local — no Graph or Exchange. Requires permission to modify the # target's ACL (typically NTFS Owner or local Administrators). $path = Read-Host "Enter folder path" if (-not (Test-Path -LiteralPath $path)) { Write-Host "Path not found: $path" -ForegroundColor Red return } $item = Get-Item -LiteralPath $path -Force if (-not $item.PSIsContainer) { Write-Host "Path must be a folder, not a file." -ForegroundColor Red return } $acl = Get-Acl -LiteralPath $item.FullName $inheritanceBlocked = $acl.AreAccessRulesProtected $explicitRules = @($acl.Access | Where-Object { -not $_.IsInherited }) Write-Host "" Write-Host " Target: $($item.FullName)" -ForegroundColor Cyan Write-Host " Inheritance currently: $(if ($inheritanceBlocked) { 'BLOCKED' } else { 'enabled' })" Write-Host " Explicit (non-inherited) ACEs: $($explicitRules.Count)" Write-Host "" if (-not $inheritanceBlocked -and $explicitRules.Count -eq 0) { Write-Host "Folder is already fully inherited. Nothing to do." -ForegroundColor Green return } if ($explicitRules.Count -gt 0) { Write-Host "Explicit rules:" -ForegroundColor Yellow foreach ($r in $explicitRules) { Write-Host " $($r.IdentityReference) — $($r.AccessControlType) $($r.FileSystemRights)" -ForegroundColor DarkGray } Write-Host "" } if ((Read-Host "Re-enable inheritance? (y/n)") -ne "y") { Write-Host "Aborted." -ForegroundColor Red return } # SetAccessRuleProtection(isProtected, preserveInheritance): # isProtected=$false → folder inherits from parent # preserveInheritance=$true → keep currently-inherited rules during the # transition so we don't briefly lose access $acl.SetAccessRuleProtection($false, $true) $strip = $false if ($explicitRules.Count -gt 0) { $strip = (Read-Host "Also remove the $($explicitRules.Count) explicit ACE(s) listed above? (y/n)") -eq "y" if ($strip) { foreach ($r in $explicitRules) { $acl.RemoveAccessRule($r) | Out-Null } } } try { Set-Acl -LiteralPath $item.FullName -AclObject $acl -ErrorAction Stop Write-Host "" Write-Host "Inheritance re-enabled." -ForegroundColor Green if ($strip) { Write-Host "Explicit ACEs removed." -ForegroundColor Green } } catch { Write-Host "" Write-Host "Failed: $_" -ForegroundColor Red Write-Host "(May need an elevated session, or take ownership first:" -ForegroundColor DarkGray Write-Host " takeown /f `"$($item.FullName)`" /r /d y)" -ForegroundColor DarkGray } |