en-US/about_Invoke-FvAdOuAceRemediation.help.txt
|
TOPIC about_Invoke-FvAdOuAceRemediation SHORT DESCRIPTION Assesses, reports on, remediates and rolls back over-permissive explicit Everyone/GenericAll ACEs on Active Directory Organizational Units. LONG DESCRIPTION Six functions are provided: Get-FvAdOuAce - read-only assessment of a supplied OU's ACEs Get-FvAdOuAceReport - opt-in, explicit domain-wide reporting sweep Backup-FvAdOuAcl - pre-change security-descriptor backup (DACL only) Reset-FvAdOuAce - remediation: removes the offending explicit ACE(s) Restore-FvAdOuAcl - rollback: restores a DACL from a Backup-FvAdOuAcl manifest Invoke-FvAdOuAceRemediation - single entry point, dispatches to the above by mutually exclusive parameter set (-Assess/-Report/-Remediate/ -Rollback); default is read-only assessment. DESIGN CHOICES - The security descriptor is read and written via the nTSecurityDescriptor attribute (Get-ADObject -Properties nTSecurityDescriptor / Set-ADObject -Replace), never via Get-Acl/Set-Acl against the AD:\ provider drive. The AD:\ drive's behaviour under PowerShell 7 is unreliable; nTSecurityDescriptor is the underlying LDAP attribute and gives predictable, object-based read/write. - ACEs are enumerated via '$securityDescriptor.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])', never via the '.Access' property. This was verified against a live, non-production OU read during this build: '.Access' returned only 1 of 33 real ACEs on the same object (it appears to omit inherited rules by default), which would have silently under-reported findings and under-remediated targets. - A right "matches the watchlist" when the ACE's rights fully contain at least one watchlisted right's bit pattern, not merely when any bit overlaps. GenericAll's numeric value (983551 / 0xF01FF) is a combination of many lower-privilege bits (including ReadProperty), so a naive combined-mask "any bit overlaps" test would flag an ordinary ReadProperty-only ACE as a GenericAll match purely by bit coincidence - confirmed during this build. Testing full containment per watchlisted right avoids that. - Backup and restore are scoped to the DACL only (AccessControlSections.Access). Owner, primary group and the SACL are deliberately left untouched throughout this module - restoring or altering them is out of scope. - ACE matching is performed exclusively on resolved SecurityIdentifier values. There is no comparison anywhere against a display-name string such as "Everyone". - Only explicit (IsInherited -eq $false) Allow ACEs are ever removed. Inherited ACEs are reported, never remediated - an inherited over-permissive ACE must be fixed at its source (a parent container), which this module does not touch. UNVERIFIED ASSUMPTION Writing nTSecurityDescriptor back via 'Set-ADObject -Identity <dn> -Replace @{ ntSecurityDescriptor = $securityDescriptor }' (where $securityDescriptor is the System.DirectoryServices.ActiveDirectorySecurity instance returned by 'Get-ADObject -Properties nTSecurityDescriptor') is a long-standing, widely used community pattern. The current Microsoft Learn reference page for Set-ADObject documents -Replace generically as a Hashtable of LDAP attribute names to values and does not carry a worked nTSecurityDescriptor example, so this specific usage could NOT be confirmed against a current Microsoft-authored code sample during this build. Test this write path against a non-production OU before relying on it in change control. OTHER STATED ASSUMPTIONS - "Restore the default permissions" is implemented as two distinct, non-equivalent modes (RestoreMode parameter on Reset-FvAdOuAce). RemoveAce (default) removes only the offending explicit ACE(s) and is the minimal, reversible reading. SchemaDefaultDacl rebuilds the OU's DACL from the live organizationalUnit classSchema object's defaultSecurityDescriptor and discards ALL custom delegations on the OU, not just the offending ACE - it must be deliberately selected, never assumed. - A live OU's effective DACL is the schema default merged with inheritable ACEs from its parents; SchemaDefaultDacl mode does not reproduce a pristine OU exactly, and says so at runtime via Write-Warning. - No change-record/ticket-ID parameter is included; none was requested. - Backup manifests are written wherever the caller points -BackupPath, with no automatic retention or pruning. - Execution identity is assumed to hold WriteDacl on each target OU and read access to the schema naming context. This is not enforced by the module - a failed write surfaces as a per-OU 'Failed' result, per the per-OU error isolation design. NON-GOALS (deliberately out of scope) - Group Policy objects, Conditional Access policies, tenant settings, domain-root ACLs. - Inherited ACEs, inheritance flags, SE_DACL_PROTECTED, object ownership, the SACL. - A GUI, an HTML dashboard beyond Get-FvAdOuAceReport's own export, or a scheduled task. COMMANDS Get-FvAdOuAce Get-FvAdOuAceReport Backup-FvAdOuAcl Reset-FvAdOuAce Restore-FvAdOuAcl Invoke-FvAdOuAceRemediation EXAMPLES # Read-only assessment of one OU (the default mode) Invoke-FvAdOuAceRemediation -OrganizationalUnit 'OU=Example,DC=contoso,DC=local' # Domain-wide reporting sweep, exported as CSV and HTML Invoke-FvAdOuAceRemediation -Report -SearchBase 'DC=contoso,DC=local' ` -OutputPath 'C:\Reports' -OutputFormat Csv, Html # Preview remediation with no changes made Invoke-FvAdOuAceRemediation -Remediate -OrganizationalUnit 'OU=Example,DC=contoso,DC=local' ` -BackupPath 'C:\Backups' -WhatIf # Remediate, then roll back from the manifest Backup-FvAdOuAcl wrote $result = Invoke-FvAdOuAceRemediation -Remediate -OrganizationalUnit 'OU=Example,DC=contoso,DC=local' ` -BackupPath 'C:\Backups' -Confirm:$false Invoke-FvAdOuAceRemediation -Rollback -ManifestPath $result.BackupManifestPath -Confirm:$false NOTES This module requires PowerShell 7.0 or later and the ActiveDirectory RSAT module (Windows-only). Modifying an OU's discretionary ACL is a Tier-0-adjacent change: Reset-FvAdOuAce and Restore-FvAdOuAcl both require WriteDacl on the target OU, declare SupportsShouldProcess with ConfirmImpact 'High', and Reset-FvAdOuAce always takes a Backup-FvAdOuAcl snapshot before writing and aborts the OU if that backup fails. SEE ALSO Get-Help Get-FvAdOuAce -Full Get-Help Invoke-FvAdOuAceRemediation -Full |