Private/Test/Test-IsLowPrivilegePrincipal.ps1

function Test-IsLowPrivilegePrincipal {
    <#
        .SYNOPSIS
        Tests if a security principal is a low-privilege (custom) principal.
 
        .DESCRIPTION
        Examines security principal identifiers (SIDs or NTAccount names) to determine if they
        represent low-privilege or custom principals - those that are neither high-privilege
        administrative principals nor overly broad dangerous principals.
         
        This function identifies "middle ground" principals by excluding two categories:
        1. Safe/Administrative principals: Domain Admins, Enterprise Admins, SYSTEM, Domain Controllers, etc.
        2. Dangerous principals: Everyone, Authenticated Users, Domain Users, Domain Computers, etc.
         
        Principals that don't match either category represent custom security configurations
        such as specific service accounts, security groups, or users that have been granted
        permissions outside the standard administrative model. These should be reviewed to
        ensure they align with security policies and least privilege principles.
 
        .PARAMETER IdentityReference
        One or more security principal identifiers to test. Can be SIDs, NTAccount names,
        or any string representation of a security principal.
 
        .PARAMETER SafeEnrollee
        An array of SIDs and regex patterns identifying high-privilege administrative principals
        that are considered safe/expected to have enrollment permissions.
        Default includes Domain Admins, Enterprise Admins, SYSTEM, Domain Controllers, Key Admins, etc.
 
        .PARAMETER DangerousEnrollee
        An array of SIDs, NTAccount names, and regex patterns identifying overly broad dangerous principals.
        Default includes NULL SID, Everyone, Anonymous Logon, Authenticated Users, Domain Users, etc.
 
        .INPUTS
        System.String[]
        You can pipe security principal identifiers to this function.
 
        .OUTPUTS
        System.Boolean
        Returns $true if the principal is low-privilege (neither safe nor dangerous), $false otherwise.
        When multiple principals are provided, returns one boolean per principal.
 
        .EXAMPLE
        Test-IsLowPrivilegePrincipal -IdentityReference 'CONTOSO\WebServerAdmins'
        Returns $true if 'CONTOSO\WebServerAdmins' is neither an admin group nor a dangerous principal.
 
        .EXAMPLE
        Test-IsLowPrivilegePrincipal -IdentityReference 'Everyone'
        Returns $false as 'Everyone' is a dangerous principal.
 
        .EXAMPLE
        Test-IsLowPrivilegePrincipal -IdentityReference 'S-1-5-21-1234567890-1234567890-1234567890-512'
        Returns $false as SIDs ending in -512 represent Domain Admins groups (safe principal).
 
        .EXAMPLE
        $ace.IdentityReference | Test-IsLowPrivilegePrincipal
        Tests an ACE's identity reference to determine if it's a custom/low-privilege principal.
 
        .EXAMPLE
        'CONTOSO\ServiceAccount' | Test-IsLowPrivilegePrincipal
        Returns $true for a custom service account that isn't in safe or dangerous lists.
 
        .EXAMPLE
        $customSafe = @('-512$', '-519$', '-544$')
        Test-IsLowPrivilegePrincipal -IdentityReference 'CONTOSO\CustomGroup' -SafeEnrollee $customSafe
        Uses a custom list of safe administrative principals.
 
        .NOTES
        Safe/Administrative principals excluded by default:
        - Domain Admins (-512), Enterprise Admins (-519), Builtin Administrators (-544)
        - SYSTEM (-18), Builtin Administrator (-500)
        - Cert Publishers (-517)
        - Domain Controllers (-516), Read-Only Domain Controllers (-521)
        - Enterprise Domain Controllers (-498), Enterprise Read-Only Domain Controllers (-9)
        - Key Admins (-526), Enterprise Key Admins (-527)
        - SELF (S-1-5-10)
         
        Dangerous principals excluded by default:
        - NULL SID, Everyone, Anonymous Logon, BUILTIN\Users
        - Authenticated Users, Domain Users, Domain Computers
         
        The function uses regex matching to support both exact matches (SIDs, NTAccount names)
        and pattern matches (SID suffixes).
 
        .LINK
        https://posts.specterops.io/certified-pre-owned-d95910965cd2
    #>

    [CmdletBinding()]
    [OutputType([bool])]
    param (
        [Parameter(Mandatory, ValueFromPipeline)]
        [string[]]$IdentityReference,
        
        [Parameter()]
        [string[]]$SafeEnrollee,
        
        [Parameter()]
        [string[]]$DangerousEnrollee
    )

    #requires -Version 5.1

    begin {
        # Load principal patterns from data file if not provided
        if (-not $SafeEnrollee -or -not $DangerousEnrollee) {
            $principalDefinitions = Import-PowerShellDataFile -Path "$PSScriptRoot\..\Data\PrincipalDefinitions.psd1"
            
            if (-not $SafeEnrollee) {
                $SafeEnrollee = $principalDefinitions.SafePrincipals
                Write-Verbose "Loaded $($SafeEnrollee.Count) safe principal patterns from PrincipalDefinitions.psd1"
            }
            
            if (-not $DangerousEnrollee) {
                $DangerousEnrollee = $principalDefinitions.DangerousPrincipals
                Write-Verbose "Loaded $($DangerousEnrollee.Count) dangerous principal patterns from PrincipalDefinitions.psd1"
            }
        }
        
        $safeEnrolleePattern = $SafeEnrollee -join '|'
        $dangerousEnrolleePattern = $DangerousEnrollee -join '|'
    }

    process {
        $IdentityReference | ForEach-Object {
            Write-Verbose "Testing if '$_' is a low-privilege principal..."
            
            $isDangerous = Test-IsDangerousPrincipal -IdentityReference $_ -DangerousEnrollee $DangerousEnrollee
            $isSafe = $_ -match $safeEnrolleePattern
            $isLowPrivilege = (-not $isSafe) -and (-not $isDangerous)
            
            if ($isDangerous) {
                Write-Verbose "'$_' is a dangerous principal (not low-privilege)"
            } elseif ($isSafe) {
                Write-Verbose "'$_' is a safe/administrative principal (not low-privilege)"
            } else {
                Write-Verbose "'$_' is a low-privilege/custom principal"
            }
            
            $isLowPrivilege
        }
    }

    end {
    }
}