tests/Test-Assessment.21815.ps1

<#
.SYNOPSIS
 
#>


function Test-Assessment-21815 {
    [ZtTest(
        Category = 'Privileged access',
        ImplementationCost = 'High',
        MinimumLicense = ('P2'),
        Pillar = 'Identity',
        RiskLevel = 'High',
        SfiPillar = 'Protect identities and secrets',
        TenantType = ('Workforce'),
        TestId = 21815,
        Title = 'All privileged role assignments are activated just in time and not permanently active',
        UserImpact = 'Low'
    )]
    [CmdletBinding()]
    param(
        $Database
    )

    Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose
    if ( -not (Get-ZtLicense EntraIDP2) ) {
        Add-ZtTestResultDetail -SkippedBecause NotLicensedEntraIDP2
        return
    }

    $activity = "Checking All privileged role assignments are activated just in time and not permanently active"
    Write-ZtProgress -Activity $activity -Status "Getting privileged role assignments"

    $sql = @"
select distinct principalId, principalDisplayName, userPrincipalName, roleDisplayName, privilegeType, isPrivileged
from vwRole
"@

    $roleAssignments = Invoke-DatabaseQuery -Database $Database -Sql $sql

    # Check if any privileged role assignment in the results has privilegeType set to Permanent
    $permanentPrivileged = $roleAssignments | Where-Object { $_.isPrivileged -eq $true -and $_.privilegeType -eq 'Permanent' }

    # Issue #266: Exclude emergency access accounts from failures
    # Emergency accounts are expected to have permanent privileged role assignments per Microsoft best practices
    Write-ZtProgress -Activity $activity -Status "Identifying emergency access accounts"
    $emergencyAccounts = Get-ZtEmergencyAccessAccounts -Database $Database
    $emergencyAccountIds = @($emergencyAccounts | Select-Object -ExpandProperty Id)

    # Filter out emergency access accounts from the results
    $results = @($permanentPrivileged | Where-Object { $_.principalId -notin $emergencyAccountIds })
    $excludedEmergencyAccounts = @($permanentPrivileged | Where-Object { $_.principalId -in $emergencyAccountIds })

    # Count of *distinct* excluded emergency accounts (one user can have multiple permanent role assignments)
    $excludedAccountCount = @($excludedEmergencyAccounts | Select-Object -ExpandProperty principalId -Unique).Count

    $testResultMarkdown = ""

    if ($results.Count -eq 0) {
        $passed = $true
        if ($excludedAccountCount -gt 0) {
            $testResultMarkdown += "No privileged users have permanent role assignments (excluding $excludedAccountCount emergency access account(s) which are expected to have permanent assignments)."
        }
        else {
            $testResultMarkdown += "No privileged users have permanent role assignments."
        }
    }
    else {
        $passed = $false
        $testResultMarkdown += "Privileged users with permanent role assignments were found.`n`n%TestResult%"
    }

        # Build the detailed sections of the markdown

    # Define variables to insert into the format string
    $reportTitle = "Privileged users with permanent role assignments"
    $tableRows = ""

    if (-not $passed) {
        # Create a here-string with format placeholders {0}, {1}, etc.
        $formatTemplate = @'
 
## {0}
 
 
| User | UPN | Role Name | Assignment Type |
| :--- | :-- | :-------- | :-------------- |
{1}
 
'@


        foreach ($result in $results) {
            $portalLink = 'https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/{0}/hidePreviewBanner~/true' -f $result.principalId
            $tableRows += @"
| [$(Get-SafeMarkdown($result.principalDisplayName))]($portalLink) | $($result.userPrincipalName) | $($result.roleDisplayName) | $($result.privilegeType) |`n
"@

        }

        # Format the template by replacing placeholders with values
        $mdInfo = $formatTemplate -f $reportTitle, $tableRows
    }

    # Build section for excluded emergency access accounts (Issue #266)
    $emergencySection = ''
    if ($excludedEmergencyAccounts.Count -gt 0) {
        $emergencySection = @'
 
## Excluded emergency access accounts
 
The following emergency access accounts were excluded from this check as they are expected to have permanent privileged role assignments per [Microsoft best practices](https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access).
 
| User | UPN | Role Name |
| :--- | :-- | :-------- |
'@

        foreach ($emergency in $excludedEmergencyAccounts) {
            $portalLink = 'https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/{0}/hidePreviewBanner~/true' -f $emergency.principalId
            $emergencySection += "| [$(Get-SafeMarkdown($emergency.principalDisplayName))]($portalLink) | $($emergency.userPrincipalName) | $($emergency.roleDisplayName) |`n"
        }
    }

    if ($passed) {
        # Pass message has no %TestResult% placeholder; append excluded section if any
        $testResultMarkdown += $emergencySection
    }
    else {
        # Replace the placeholder with the detailed failure table plus excluded section
        $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", ($mdInfo + $emergencySection)
    }

    $params = @{
        TestId             = '21815'
        Title              = "All privileged role assignments are activated just in time and not permanently active"
        UserImpact         = 'Low'
        Risk               = 'High'
        ImplementationCost = 'High'
        AppliesTo          = 'Identity'
        Tag                = 'Identity'
        Status             = $passed
        Result             = $testResultMarkdown
    }

    Add-ZtTestResultDetail @params
}