Public/Manager.Authorization.ps1
function Reset-Authorization{ <# .SYNOPSIS Reset the ACL and attributes of a path to its default state if we have already known the default state exactly. For more information on the motivations, rationale, logic, limitations and usage of this function, see the [post](https://little-train.com/posts/ebaccba2.html). .DESCRIPTION Reset ACL of `$Path` to its default state by 3 steps: 1. Get path type by `Get-PathType` 2. Get default SDDL of `$Path` by `Get-DefaultSddl` according to `$path_type` 3. Set SDDL of `$Path` to default SDDL by `Set-Acl` .PARAMETER Path The path to be reset. .PARAMETER Recurse A switch parameter to indicate whether to reset the ACL of all files and directories in the path recursively. .INPUTS String or FormattedFileSystemPath. .OUTPUTS None. .COMPONENT ```powershell $new_acl = Get-Acl -LiteralPath $Path $sddl = ... # Get default SDDL of `$Path` $new_acl.SetSecurityDescriptorSddlForm($sddl) Set-Acl -LiteralPath $Path -AclObject $new_acl ``` .NOTES Only support Windows. .LINK [Authorization](https://little-train.com/posts/ebaccba2.html) [ShouldProcess](https://learn.microsoft.com/zh-cn/powershell/scripting/learn/deep-dives/everything-about-shouldprocess?view=powershell-7.3) #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [FormattedFileSystemPath]$Path, [switch]$Recurse ) try { Assert-IsWindowsAndAdmin Assert-ValidPath4Authorization $Path $path_type = Get-PathType $Path -SkipPlatformCheck -SkipPathCheck $sddl = Get-DefaultSddl -PathType $path_type $new_acl = Get-Acl -LiteralPath $Path if($PSCmdlet.ShouldProcess("$Path",'set the original ACL')){ Reset-PathAttribute $Path -SkipPlatformCheck -SkipPathCheck if ($new_acl.Sddl -ne $sddl){ try { Write-Log "`$Path is:`n`t $Path" Write-Log "Current Sddl is:`n`t $($new_acl.Sddl)" Write-Log "Target Sddl is:`n`t $($sddl)" $new_acl.SetSecurityDescriptorSddlForm($sddl) Write-Log "After dry-run, the sddl is:`n`t $($new_acl.Sddl)" Set-Acl -LiteralPath $Path -AclObject $new_acl Write-Log "After applying ACL modification, the sddl is:`n`t $((Get-Acl -LiteralPath $Path).Sddl)" } catch [System.ArgumentException]{ Write-Log "`$Path is too long: '$Path'" } } if ($Recurse){ if ($Path.IsFile){ throw "Cannot use `-Recurse` on a file: $Path" } if ($Path.IsSymbolicLink){ throw "Cannot use `Recurse` on a symbolic link: $Path" } if ($Path.IsJunction){ throw "Cannot use `-Recurse` on a junction: $Path" } if ($Path.IsInSystemVolumeInfo){ throw "Cannot use `-Recurse` on a path in System Volume Information: $Path" } if ($Path.IsInRecycleBin){ throw "Cannot use `-Recurse` on a path in Recycle Bin: $Path" } # Recurse bypass: files, symbolic link directories, junctions, System Volume Information, `$Recycle.Bin $paths = Get-ChildItem -LiteralPath $Path -Force -Recurse -Attributes !ReparsePoint -ErrorAction Continue # The progress bar is refer to Chat-Gpt $total = $paths.Count $current = 0 foreach ($item in $paths) { $current++ $progressPercentage = ($current / $total) * 100 $progressStatus = "Processing file $current of $total" Write-Progress -Activity "Traversing Directory" -Status $progressStatus -PercentComplete $progressPercentage # Do your personal jobs, such as: $file.FullName Reset-Authorization -Path $item.FullName } Write-Progress -Activity "Traversing Directory" -Completed } } } catch { Write-Log "Reset-Authorization Exception: $PSItem" Write-Log "Operation has been skipped on $Path." } } |