Private/Get-ElevationPolicyNote.ps1

function Get-ElevationPolicyNote {
    <#
        .SYNOPSIS
        Explains, from policy, why an elevation attempt was refused.
 
        .DESCRIPTION
        Reports. It decides nothing and changes nothing about what is
        attempted, and names what is set only once an attempt has failed.
 
        "Elevation was declined or failed" is true and useless on a managed
        machine. Naming the value responsible turns the same failure into
        something someone can take to whoever manages the policy.
 
        The registry values under
        HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System that
        explain a failure:
 
          ConsentPromptBehaviorUser = 0 a standard user's request is denied
                                            outright; no prompt is ever shown
          ValidateAdminCodeSignatures = 1 only executables with a validated
                                            signature may elevate
          EnableLUA = 0 there is no consent prompt to answer
 
        A running privilege-management broker is also named. Nothing a broker
        does appears in the registry: it can deny an elevation, or allow one
        application and refuse another, without leaving a value behind, so a
        machine can refuse while every value above reads as permissive.
 
        Brokers are recognised by vendor name in the service list, so a vendor
        absent from that list is not mentioned. Nothing is decided either way --
        a missing entry costs a sentence of explanation.
 
        Returns nothing when nothing restrictive is found, so a caller can append
        the result and say nothing extra on an ordinary machine.
 
        .EXAMPLE
        $note = Get-ElevationPolicyNote
        if ($note) { Write-Warning $note }
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param()

    $notes = [System.Collections.Generic.List[string]]::new()

    $policy = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'

    # One read, then look for the values on the object. Asking for a named value
    # that is absent throws, and Start-Transcript records the throw even when it
    # is caught -- which reads as a fault in a log where nothing went wrong.
    $values = Get-ItemProperty -LiteralPath $policy -ErrorAction SilentlyContinue

    if ($values) {
        $names = $values.PSObject.Properties.Name

        if ($names -contains 'EnableLUA' -and $values.EnableLUA -eq 0) {
            $notes.Add('UAC is switched off (EnableLUA is 0), so there is no consent prompt to answer.')
        }

        if ($names -contains 'ConsentPromptBehaviorUser' -and $values.ConsentPromptBehaviorUser -eq 0) {
            $notes.Add('Policy denies elevation requests from standard users outright (ConsentPromptBehaviorUser is 0), so a standard user is never prompted.')
        }

        if ($names -contains 'ValidateAdminCodeSignatures' -and $values.ValidateAdminCodeSignatures -eq 1) {
            $notes.Add('Policy allows only executables with a validated signature to elevate (ValidateAdminCodeSignatures is 1).')
        }
    }

    # Vendor-identifying names rather than a bare "privilege", which matches
    # unrelated services.
    $brokerPatterns = @(
        '*defendpoint*', '*avecto*', '*beyondtrust*', '*privilege management*',
        '*adminbyrequest*', '*admin by request*', '*cyberark*',
        '*arellia*', '*thycotic*', '*delinea*'
    )

    $broker = $null
    try {
        $running = @(Get-Service -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq 'Running' })
        foreach ($service in $running) {
            foreach ($pattern in $brokerPatterns) {
                if ($service.Name -like $pattern -or $service.DisplayName -like $pattern) {
                    $broker = $service.DisplayName
                    break
                }
            }
            if ($broker) { break }
        }
    } catch {
        Write-Verbose "Could not enumerate services to look for a privilege broker: $($_.Exception.Message)"
    }

    if ($broker) {
        $notes.Add("A privilege-management broker is running on this machine ($broker). Those grant or deny elevation per application and leave nothing in the registry, so it may have refused this one even though the policy values above look permissive.")
    }

    if ($notes.Count -eq 0) { return }

    'Policy on this machine may be the cause: ' + ($notes -join ' ')
}