Private/Test/Test-IsStandardOwner.ps1

function Test-IsStandardOwner {
    <#
    .SYNOPSIS
        Tests whether an owner SID matches standard PKI ownership patterns.
 
    .DESCRIPTION
        Evaluates an owner identity (SID or NTAccount) against a list of standard
        ownership patterns to determine if the owner is an approved administrative
        principal for AD CS objects.
         
        Standard owners typically include:
        - Enterprise Admins (SID ending in -519)
        - Domain Admins (SID ending in -512)
        - Administrators (SID ending in -544)
        - SYSTEM (S-1-5-18)
        - Enterprise Domain Controllers (SID ending in -516)
        - Schema Admins (SID ending in -518)
         
        By default, uses the script-level $script:StandardOwners array populated by
        Initialize-PrincipalDefinitions. Custom patterns can be provided via parameter.
 
    .PARAMETER OwnerIdentity
        The owner identity to test. Can be a SID string (S-1-5-...) or NTAccount
        name (DOMAIN\User). If an NTAccount is provided, it will be translated to SID.
 
    .PARAMETER StandardOwners
        Optional array of standard owner SID patterns. If not provided, uses
        $script:StandardOwners. Patterns can be exact SIDs or regex patterns
        (ending with $).
 
    .INPUTS
        System.String
        You can pipe owner identities (SIDs or NTAccount names) to this function.
 
    .OUTPUTS
        System.Boolean
        Returns $true if the owner matches a standard pattern, $false otherwise.
 
    .EXAMPLE
        Test-IsStandardOwner -OwnerIdentity 'S-1-5-21-1234567890-1234567890-1234567890-519'
        Tests if the SID matches Enterprise Admins pattern (ends with -519).
 
    .EXAMPLE
        Test-IsStandardOwner -OwnerIdentity 'CONTOSO\Domain Admins'
        Translates the NTAccount to SID and tests if it matches standard patterns.
 
    .EXAMPLE
        'S-1-5-18' | Test-IsStandardOwner
        Pipeline example testing if SYSTEM is a standard owner.
 
    .EXAMPLE
        $customStandard = @('S-1-5-21-.*-512$', 'S-1-5-21-.*-519$')
        Test-IsStandardOwner -OwnerIdentity 'DOMAIN\Administrator' -StandardOwners $customStandard
        Uses custom standard owner patterns for validation.
 
    .NOTES
        This function is designed to work in conjunction with Set-HasNonStandardOwner
        and follows the pattern established by Test-IsDangerousPrincipal and
        Test-IsLowPrivilegePrincipal.
         
        Standard owner patterns support both exact SID matches and regex patterns
        (patterns ending with $).
 
    .LINK
        Set-HasNonStandardOwner
    #>

    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$OwnerIdentity,

        [Parameter()]
        [string[]]$StandardOwners
    )

    #requires -Version 5.1

    begin {
        # Use script-level StandardOwners if not provided
        if (-not $StandardOwners) {
            if (-not $script:StandardOwners -or $script:StandardOwners.Count -eq 0) {
                Write-Warning "StandardOwners not initialized and none provided. Cannot validate ownership."
                return $false
            }
            $StandardOwners = $script:StandardOwners
        }
        
        Write-Verbose "Using $($StandardOwners.Count) standard owner patterns"
    }

    process {
        # Convert owner to SID if it's not already
        $ownerSid = $null
        if ($OwnerIdentity -match '^S-1-') {
            $ownerSid = $OwnerIdentity
            Write-Verbose "Testing if '$OwnerIdentity' is a standard owner..."
        } else {
            try {
                $ownerPrincipal = New-Object System.Security.Principal.NTAccount($OwnerIdentity)
                $ownerSid = $ownerPrincipal.Translate([System.Security.Principal.SecurityIdentifier]).Value
                Write-Verbose "Testing if '$OwnerIdentity' ($ownerSid) is a standard owner..."
            } catch {
                Write-Verbose "Could not translate owner '$OwnerIdentity' to SID: $_"
                return $false
            }
        }
        
        if (-not $ownerSid) {
            return $false
        }
        
        # Check if owner SID matches any standard owner pattern
        foreach ($pattern in $StandardOwners) {
            # Check for exact SID match
            if ($pattern -eq $ownerSid) {
                Write-Verbose "'$ownerSid' matches standard owner pattern (exact): $pattern"
                return $true
            }
            # Check for regex pattern match (patterns ending in $)
            elseif ($pattern -match '\$$' -and $ownerSid -match $pattern) {
                Write-Verbose "'$ownerSid' matches standard owner pattern (regex): $pattern"
                return $true
            }
        }
        
        Write-Verbose "'$ownerSid' is not a standard owner"
        return $false
    }
}