public/cisa/entra/Test-MtCisaUnmanagedRoleAssignment.ps1

function Test-MtCisaUnmanagedRoleAssignment {
    <#
    .SYNOPSIS
    Checks for active role assingments with no start time

    .DESCRIPTION
    Provisioning users to highly privileged roles SHALL NOT occur outside of a PAM system.

    .EXAMPLE
    Test-MtCisaUnmanagedRoleAssignment

    Returns true if all role assignments have a start time

    .LINK
    https://maester.dev/docs/commands/Test-MtCisaUnmanagedRoleAssignment
    #>

    [CmdletBinding()]
    [OutputType([bool])]
    param()

    if (!(Test-MtConnection Graph)) {
        Add-MtTestResultDetail -SkippedBecause NotConnectedGraph
        return $null
    }

    $EntraIDPlan = Get-MtLicenseInformation -Product EntraID
    $pim = $EntraIDPlan -eq "P2" -or $EntraIDPlan -eq "Governance"
    if (-not $pim) {
        Add-MtTestResultDetail -SkippedBecause NotLicensedEntraIDP2
        return $null
    }

    $roles = Get-MtRole -CisaHighlyPrivilegedRoles
    $roleAssignments = @()

    foreach ($role in $roles) {
        $principal = $null
        $roleAssignment = [PSCustomObject]@{
            role      = $role.displayName
            principal = $principal
        }
        $assignmentsSplat = @{
            ApiVersion      = "v1.0"
            RelativeUri     = "roleManagement/directory/roleAssignmentSchedules"
            Filter          = "roleDefinitionId eq '$($role.id)' and assignmentType eq 'Assigned'"
            QueryParameters = @{
                expand = "principal"
            }
        }
        $assignments = Invoke-MtGraphRequest @assignmentsSplat | Where-Object {`
                $null -eq $_.createdUsing -or `
                $null -eq $_.scheduleInfo.startDateTime }

        $roleAssignment.principal = $assignments.principal

        $roleAssignments += $roleAssignment
    }

    $testResult = ($roleAssignments.principal | Measure-Object).Count -eq 0

    if ($testResult) {
        $testResultMarkdown = "Well done. Your tenant has no unmanaged active role assignments."
    } else {
        $testResultMarkdown = "Your tenant has active assignments without a start date:`n`n%TestResult%"
    }

    if (-not $testResult) {
        $result = "| Role | Principal Type | Display Name | Status |`n"
        $result += "| --- | --- | --- | --- |`n"
        foreach ($roleAssignment in ($roleAssignments | Where-Object { $_.principal })) {
            foreach ($principal in $roleAssignment.principal) {
                $principalType = $principal.'@odata.type'.Split('.')[-1]
                $entraPortalUrl = $__MtSession.AdminPortalUrl.Entra
                $portalDeepLink = switch ($principal.'@odata.type') {
                    '#microsoft.graph.user' { "$($entraPortalUrl)#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/$($principal.id)" }
                    '#microsoft.graph.servicePrincipal' { "$($entraPortalUrl)#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/$($principal.id)" }
                    '#microsoft.graph.group' { "$($entraPortalUrl)#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/$($principal.id)" }
                    default { $null }
                }
                $displayName = if ($portalDeepLink) {
                    "[$(Get-MtSafeMarkdown $principal.displayName)]($portalDeepLink)"
                } else {
                    Get-MtSafeMarkdown $principal.displayName
                }
                $result += "| $($roleAssignment.role) | $principalType | $displayName | ❌ No Start Date |`n"
            }
        }
    }

    $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result

    Add-MtTestResultDetail -Result $testResultMarkdown

    return $testResult
}