Private/Core/Remove-OrphanedSidEntry.ps1

#Requires -Version 5.1

<#
.SYNOPSIS
    Public API wrapper for SID removal operations
 
.DESCRIPTION
    Provides the public interface for SID removal operations. This lightweight
    wrapper delegates to the modular workflow orchestration while maintaining
    a clean, stable public API.
 
    This follows the PowerShell community "controller" pattern where the public
    function coordinates workflow without implementing business logic directly.
 
.NOTES
    Author: Jeffrey Stuhr
    Blog: https://www.techbyjeff.net
    LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/
    Last Updated: 2025-07-05
    Version: 2.0.0 (Modular Architecture)
    PowerShell Version: 5.1+ (Windows), 7.x+ (Cross-platform)
 
    TROUBLESHOOTING:
    - For removal failures: .\Troubleshooting\Security\SID-Removal-Issues.md
    - For backup errors: .\Troubleshooting\Common\Backup-Errors.md
    - For validation problems: .\Troubleshooting\Security\Security-Validation-Issues.md
 
    DEPENDENCIES:
    - Requires Operations\Invoke-RemovalWorkflow.ps1 for workflow orchestration
    - All modular dependencies are handled by the workflow orchestrator
#>


function Remove-OrphanedSidEntry {
    <#
    .SYNOPSIS
        Removes orphaned SIDs from Active Directory objects with enterprise-grade security
 
    .DESCRIPTION
        This enterprise-grade function removes orphaned Security Identifiers (SIDs) from
        Active Directory object ACLs with comprehensive security validation, backup creation,
        and verification. The function implements a modular architecture with specialized
        components for maximum reliability and maintainability.
 
        BUSINESS VALUE:
        - Improves Active Directory security by removing stale access permissions
        - Provides comprehensive audit trails for regulatory compliance
        - Reduces security risks from orphaned and unknown access entries
        - Supports enterprise-scale operations with automated workflows
        - Enables secure remediation with full rollback capabilities
 
        SECURITY FEATURES:
        - Protected SID validation prevents removal of critical system accounts
        - Security risk assessment with configurable approval workflows
        - Comprehensive backup creation before any modifications
        - Real-time verification of removal operations
        - Full audit logging with correlation tracking for compliance
 
        MODULAR ARCHITECTURE:
        - Security validation: Specialized security assessment and risk analysis
        - ACL operations: Focused ACL retrieval, modification, and application
        - Verification: Independent post-operation validation
        - Workflow orchestration: Coordinated multi-step process management
        - Security logging: Comprehensive audit trail generation
 
    .PARAMETER ObjectDN
        [String[]] (Mandatory: Yes, Pipeline: ByValue)
 
        Specifies one or more Active Directory object distinguished names for SID removal.
 
        VALIDATION RULES:
        - Must be valid LDAP distinguished names
        - Objects must exist in Active Directory
        - Must have read access to security descriptors
 
        BUSINESS CONTEXT:
        Target objects that require orphaned SID cleanup. Commonly includes
        organizational units, groups, and shared resources with inherited permissions.
 
        EXAMPLES:
        - Single OU: "OU=Finance,DC=contoso,DC=com"
        - Multiple objects: @("OU=HR,DC=contoso,DC=com", "CN=SharedFolder,CN=Computer,DC=contoso,DC=com")
 
    .PARAMETER OrphanedSIDs
        [String[]] (Mandatory: Yes)
 
        Specifies the orphaned SIDs to remove from the target objects.
 
        VALIDATION RULES:
        - Must be valid SID format (S-1-5-...)
        - SIDs will be validated against protected SID lists
        - Cannot include well-known system SIDs
 
        BUSINESS CONTEXT:
        These are the problematic SIDs identified during discovery that reference
        deleted or inaccessible security principals.
 
        EXAMPLES:
        - Single SID: "S-1-5-21-1234567890-1234567890-1234567890-1001"
        - Multiple SIDs: @("S-1-5-21-...-1001", "S-1-5-21-...-1002")
 
    .PARAMETER BackupPath
        [String] (Optional)
 
        Specifies the directory path for backup storage before SID removal.
 
        VALIDATION RULES:
        - Directory must be accessible with write permissions
        - Sufficient disk space for backup files
        - Defaults to .\Backup\[timestamp] if not specified
 
        BUSINESS CONTEXT:
        Critical for rollback capabilities and compliance requirements.
        Backups enable restoration if removal operations need to be reversed.
 
        EXAMPLES:
        - Network path: "\\backup-server\ad-backups\sid-removal"
        - Local path: "C:\ADBackups\SIDRemoval"
 
    .PARAMETER WhatIfMode
        [Switch] (Optional)
 
        Enables preview mode to show what changes would be made without executing them.
 
        BUSINESS CONTEXT:
        Essential for validation in production environments. Allows review of
        planned changes before execution for risk assessment and approval.
 
    .PARAMETER CorrelationId
        [String] (Optional)
 
        Provides a unique identifier for tracking operations across logs and systems.
 
        BUSINESS CONTEXT:
        Enables end-to-end tracking for audit compliance and troubleshooting.
        Auto-generated if not provided for seamless operation tracking.
 
    .EXAMPLE
        PS> Remove-OrphanedSidEntry -ObjectDN "OU=Finance,DC=contoso,DC=com" -OrphanedSIDs "S-1-5-21-1234567890-1234567890-1234567890-1001"
 
        DESCRIPTION: Basic orphaned SID removal from a single organizational unit
        OUTPUT: RemovalOperationResult with success status and removal details
        USE CASE: Standard cleanup operation for single object with specific orphaned SID
        DURATION: Typically 2-5 seconds for simple ACL structures
 
    .EXAMPLE
        PS> Remove-OrphanedSidEntry -ObjectDN "OU=SharedResources,DC=contoso,DC=com" -OrphanedSIDs @("S-1-5-21-...-1001", "S-1-5-21-...-1002") -BackupPath "\\backup\AD" -WhatIfMode
 
        DESCRIPTION: Preview mode for multiple SID removal with custom backup location
        OUTPUT: Shows planned changes without executing, validates all components
        USE CASE: Production change validation and approval workflow preparation
        DURATION: ~1-2 seconds for preview operations
 
    .EXAMPLE
        PS> @("OU=HR,DC=contoso,DC=com", "OU=IT,DC=contoso,DC=com") | Remove-OrphanedSidEntry -OrphanedSIDs $orphanedSIDs -CorrelationId "CHANGE-2025-001"
 
        DESCRIPTION: Pipeline processing of multiple objects with correlation tracking
        OUTPUT: RemovalOperationResult objects for each processed object
        USE CASE: Enterprise automation workflows with change management tracking
        DURATION: Scales linearly with number of objects (~3-7 seconds per object)
 
    .INPUTS
        [String[]] - ObjectDN values can be provided via pipeline
 
    .OUTPUTS
        [RemovalOperationResult] Object containing:
        - ObjectDN: Distinguished name of processed object
        - CorrelationId: Unique tracking identifier
        - IntendedRemovals: Number of SIDs planned for removal
        - ActualRemovals: Number of SIDs successfully removed
        - FailedRemovals: Number of SIDs that failed removal
        - RemovedSIDs: Array of successfully removed SIDs
        - FailedSIDs: Array of SIDs that failed removal
        - BlockedSIDs: Array of SIDs blocked by security policies
        - Success: Overall operation success status
        - ErrorMessage: Detailed error information if applicable
        - ProcessingTime: Duration of the removal operation
        - SecurityValidation: Comprehensive security validation results
 
    .NOTES
        ARCHITECTURAL IMPROVEMENTS (v2.0):
        - Modular design with specialized component delegation
        - Security validation isolated to specialized security modules
        - ACL operations modularized for focused functionality
        - Verification logic separated for independent testing
        - Workflow orchestration handles complex coordination
        - Enhanced testability with independent module validation
 
        SECURITY CONSIDERATIONS:
        - Implements protected SID validation to prevent critical system damage
        - Uses privileged SID pattern detection for additional safety
        - Creates comprehensive backups before any changes
        - Provides rollback capability through backup restoration
        - Logs all security decisions for audit compliance
 
        PERFORMANCE CHARACTERISTICS:
        - Processing Rate: 5-20 objects/second depending on ACL complexity
        - Memory Usage: Optimized for large-scale operations (~50-100MB typical)
        - Backup Creation: <100ms per object typically
        - Verification: Real-time validation of changes
 
        BUSINESS COMPLIANCE:
        - Full audit trail with correlation ID tracking
        - Security validation with risk-based controls
        - Backup and recovery capabilities for rollback
        - Integration with enterprise governance workflows
 
        TROUBLESHOOTING:
        - For security validation failures: .\Troubleshooting\Security\Security-Validation-Issues.md
        - For ACL access errors: .\Troubleshooting\Security\Permission-Issues.md
        - For backup failures: .\Troubleshooting\Common\Backup-Errors.md
        - For verification failures: .\Troubleshooting\Common\Verification-Issues.md
        - For module integration issues: .\Troubleshooting\Common\Module-Integration-Issues.md
 
    .LINK
        https://docs.microsoft.com/en-us/powershell/module/activedirectory/
        .\Troubleshooting\Security\SID-Removal-Issues.md
        .\Documentation\RemovalOperations-Architecture-Guide.md
    #>


    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([RemovalOperationResult])]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string[]]$ObjectDN,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string[]]$OrphanedSIDs,

        [Parameter()]
        [string]$BackupPath,

        [Parameter()]
        [switch]$WhatIfMode,

        [Parameter()]
        [string]$CorrelationId = [System.Guid]::NewGuid().ToString()
    )

    process {
        foreach ($dn in $ObjectDN) {
            try {
                Write-StructuredLog "Starting SID removal operation for $dn (Public API v2.0)" -Level Verbose -CorrelationId $CorrelationId

                # Invoke-RemovalWorkflow honours -WhatIfMode and $WhatIfPreference itself and prints the
                # preview, so both still reach it unchanged; this guard only answers -Confirm.
                if (-not $WhatIfMode -and -not $WhatIfPreference -and
                    -not $PSCmdlet.ShouldProcess($dn, 'Remove orphaned SIDs from the ACL')) {
                    $declined = "Removal declined at the confirmation prompt for $dn"
                    Write-StructuredLog $declined -Level Warning -CorrelationId $CorrelationId
                    continue
                }

                # Delegate to modular workflow orchestration
                $result = Invoke-RemovalWorkflow -ObjectDistinguishedName $dn -OrphanedSIDs $OrphanedSIDs -BackupPath $BackupPath -WhatIfMode:$WhatIfMode -CorrelationId $CorrelationId

                Write-StructuredLog "SID removal operation completed for $dn - Success: $($result.Success)" -Level Verbose -CorrelationId $CorrelationId
                # Emit, do not return: a return here would end the foreach and silently skip every
                # distinguished name after the first when several arrive by parameter
                $result
            }
            catch {
                # Create error result object for consistency
                $errorResult = [RemovalOperationResult]::new()
                $errorResult.ObjectDN = $dn
                $errorResult.CorrelationId = $CorrelationId
                $errorResult.IntendedRemovals = $OrphanedSIDs.Count
                $errorResult.Success = $false
                $errorResult.ErrorMessage = "Public API workflow delegation failed: $($_.Exception.Message)"

                Write-StructuredLog "SID removal operation failed for $dn : $($_.Exception.Message)" -Level Error -CorrelationId $CorrelationId
                $errorResult
            }
        }
    }
}