functions/System/Drift/Get-AccountPoliciesDrift.ps1

function Get-AccountPoliciesDrift {
    <#
    .SYNOPSIS
    Detects configuration drift in account policies (password length, complexity).

    .DESCRIPTION
    Checks if minimum password length and password complexity settings match security baselines.
    Returns PSCustomObject with drift findings (empty array if compliant).

    .PARAMETER MinimumPasswordLength
    Expected minimum password length (default: 12 characters).

    .PARAMETER RequirePasswordComplexity
    Whether password complexity should be enabled (default: $true).

    .EXAMPLE
    $drifts = Get-AccountPoliciesDrift
    if ($drifts.Count -gt 0) { $drifts | Write-Output }

    .NOTES
    DEPENDENCIES: Write-Log (Core)
    APPLIES TO: Windows Server 2016+ (HKLM registry paths)
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [int]$MinimumPasswordLength = 12,
        [bool]$RequirePasswordComplexity = $true
    )

    $regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"
    $findings = @()

    try {
        # Check minimum password length
        $minPasswordProperty = Get-ItemProperty -Path $regPath -Name MinimumPasswordLength -ErrorAction SilentlyContinue
        $minPassword = $minPasswordProperty.MinimumPasswordLength
        if ($minPassword -lt $MinimumPasswordLength) {
            $findings += [PSCustomObject]@{
                Category = "Account Policy"
                Setting = "Minimum Password Length"
                Expected = "$MinimumPasswordLength characters"
                Actual = "$minPassword characters"
                Status = "DRIFT"
                Severity = "HIGH"
            }
            Write-Log -Message "Account Policy drift: Min password length is $minPassword (expected $MinimumPasswordLength)" `
                -Level Warning -Caller $MyInvocation.MyCommand.Name
        }

        # Check password complexity
        $complexityProperty = Get-ItemProperty -Path $regPath -Name PasswordComplexity -ErrorAction SilentlyContinue
        $complexity = $complexityProperty.PasswordComplexity
        $complexityEnabled = $complexity -eq 1
        if ($complexityEnabled -ne $RequirePasswordComplexity) {
            if ($RequirePasswordComplexity) {
                $expectedText = "Enabled (1)"
            }
            else {
                $expectedText = "Disabled (0)"
            }
            if ($complexityEnabled) {
                $actualText = "Enabled ($complexity)"
            }
            else {
                $actualText = "Disabled ($complexity)"
            }
            $findings += [PSCustomObject]@{
                Category = "Account Policy"
                Setting = "Password Complexity"
                Expected = $expectedText
                Actual = $actualText
                Status = "DRIFT"
                Severity = "HIGH"
            }
            if ($complexityEnabled) {
                $current = 'enabled'
            }
            else {
                $current = 'disabled'
            }
            if ($RequirePasswordComplexity) {
                $expected = 'enabled'
            }
            else {
                $expected = 'disabled'
            }
            Write-Log -Message "Account Policy drift: Password complexity is $current (expected $expected)" `
                -Level Warning -Caller $MyInvocation.MyCommand.Name
        }
    }
    catch {
        Write-Log -Message "Error checking account policies: $_" -Level Error -Caller $MyInvocation.MyCommand.Name
        throw
    }

    # Return array (even if empty) to avoid PowerShell array-unwrapping for single elements
    return @($findings)
}