private/tests/Test-Assessment.21818.ps1

<#
.SYNOPSIS

#>


function Test-Assessment-21818 {
    [CmdletBinding()]
    param(
        $Database
    )

    Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose

    $activity = "Checking Activation alert for highly privileged role assignments"
    Write-ZtProgress -Activity $activity -Status "Getting PIM policy assignments for highly privileged roles"

    # Query retrieves the associated PIM role management policy assignments for each highly privileged role
    $sqlPolicyAssignments = @"
SELECT
    rmp.id as policyAssignmentId,
    rmp.roleDefinitionId,
    rmp.scopeId,
    rmp.scopeType,
    rmp.policyId,
    rd.displayName as roleDisplayName,
    rd.isPrivileged
FROM main."RoleManagementPolicyAssignment" rmp
INNER JOIN main."RoleDefinition" rd ON rmp.roleDefinitionId = rd.id
WHERE rd.isPrivileged = true
    AND rmp.scopeId = '/'
    AND rmp.scopeType = 'DirectoryRole'
ORDER BY rd.displayName;
"@

    $resultsPolicyAssignments = Invoke-DatabaseQuery -Database $Database -Sql $sqlPolicyAssignments

    # Define PIM notification settings that should be checked
    $notifications = @(
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when members are assigned as eligible to this role"
            NotificationType     = "Role assignment alert"
            RuleId               = "Notification_Admin_Admin_Eligibility"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when members are assigned as eligible to this role"
            NotificationType     = "Notification to the assigned user (assignee)"
            RuleId               = "Notification_Requestor_Admin_Eligibility"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when members are assigned as eligible to this role"
            NotificationType     = "Request to approve a role assignment renewal/extension"
            RuleId               = "Notification_Approver_Admin_Eligibility"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when members are assigned as active to this role"
            NotificationType     = "Role assignment alert"
            RuleId               = "Notification_Admin_Admin_Assignment"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when members are assigned as active to this role"
            NotificationType     = "Notification to the assigned user (assignee)"
            RuleId               = "Notification_Requestor_Admin_Assignment"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when members are assigned as active to this role"
            NotificationType     = "Request to approve a role assignment renewal/extension"
            RuleId               = "Notification_Approver_Admin_Assignment"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when eligible members activate this role"
            NotificationType     = "Role activation alert"
            RuleId               = "Notification_Admin_EndUser_Assignment"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when eligible members activate this role"
            NotificationType     = "Notification to activated user (requestor)"
            RuleId               = "Notification_Requestor_EndUser_Assignment"
        }
        [PSCustomObject]@{
            NotificationScenario = "Send notifications when eligible members activate this role"
            NotificationType     = "Request to approve an activation"
            RuleId               = "Notification_Approver_EndUser_Assignment"
        }
    )

    $notificationRules = @()
    # This flag is used to control the flow of a loop, allowing the script to break out of the outer loop when set to $true.
    $exitLoop = $false
    $passed = $true

    # Query activation notification rules for administrators
    # For each policy ID, retrieve notification rules for role activation events sent to administrators
    Write-ZtProgress -Activity $activity -Status "Getting activation notification rules"

    foreach ($policyAssignment in $resultsPolicyAssignments) {
        $policyId = $policyAssignment.policyId
        $roleDisplayName = $policyAssignment.roleDisplayName

        foreach ($ruleId in $notifications.ruleId) {
            try {
                $uri = "policies/roleManagementPolicies/$policyId/rules/$ruleId"

                $rule = Invoke-ZtGraphRequest -RelativeUri $uri -ApiVersion 'v1.0' -ErrorAction Stop

                if ($rule) {
                    $notificationRules += ($rule | Add-Member -MemberType NoteProperty -Name RoleDisplayName -Value $roleDisplayName -Force -PassThru)

                    # TO-DO: When the performance of the API is improved, we can collect all rules and move the check outside the loop to determine if the test passes or fails.
                    # Check if isDefaultRecipientsEnabled is true and notificationRecipients is an empty array
                    if ($rule.isDefaultRecipientsEnabled -eq $true -and
                        $rule.notificationRecipients.Count -eq 0) {
                        $passed = $false
                        $exitLoop = $true
                        break  # Exit inner loop if condition is met
                    }
                }
            }
            catch {
                Write-Error "Failed to retrieve rule $ruleId for policy $($policyId): $($_.Exception.Message)"
            }
        }
        if ($exitLoop) {
            break # Exit outer loop if condition is met
        }
    }

    $testResultMarkdown = ""

    # Output the result of the check
    if ($passed) {
        $testResultMarkdown += "Role notifications are properly configured for privileged role.`n`n%TestResult%"
    }
    else {
        $testResultMarkdown += "Role notifications are not properly configured.`n`n%TestResult%"
    }

    # Build the detailed sections of the markdown

    # Define variables to insert into the format string
    $reportTitle = "Notifications for high privileged roles"
    $tableRows = ""

    # Create a here-string with format placeholders {0}, {1}, etc.
    $formatTemplate = @'

## {0}


| Role Name | Notification Scenario | Notification Type | Default Recipients Enabled | Additional Recipients |
| :-------- | :-------------------- | :---------------- | :------------------------- | :-------------------- |
{1}

'@


    foreach ($notificationRule in $notificationRules) {
        $matchingNotification = $notifications | Where-Object { $_.RuleId -eq $notificationRule.id }
        $tableRows += @"
| $($notificationRule.roleDisplayName) | $($matchingNotification.notificationScenario) | $($matchingNotification.notificationType) | $($notificationRule.isDefaultRecipientsEnabled) | $($notificationRule.notificationRecipients -join ', ') |`n
"@

    }

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

    # Replace the placeholder with the detailed information
    $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $mdInfo


    $params = @{
        TestId             = '21818'
        Title              = "Activation alert for highly privileged role assignments"
        UserImpact         = 'Low'
        Risk               = 'High'
        ImplementationCost = 'Low'
        AppliesTo          = 'Identity'
        Tag                = 'Identity'
        Status             = $passed
        Result             = $testResultMarkdown
    }
    Add-ZtTestResultDetail @params
}