PowerShell PIM - llewellyn-marriott/notes GitHub Wiki

# Importing all of Microsoft.Graph takes a long time, only import what we need
Import-Module Microsoft.Graph.Authentication
Select-MgProfile -Name "beta"
Import-Module Microsoft.Graph.Identity.SignIns
Import-Module Microsoft.Graph.DeviceManagement.Enrolment

$requiredScopes = @("RoleManagement.Read.All", "RoleManagementPolicy.Read.Directory", "User.Read.All")
$context = Get-MgContext
if($NULL -eq $context) {
    $context = @{
        Scopes = @()
    }
}

$hasRequiredScopes = (Compare-Object $requiredScopes $context.Scopes -IncludeEqual -ExcludeDifferent).Count -eq $requiredScopes.Count

if(-not $hasRequiredScopes) {
    Connect-MgGraph -Scopes $requiredScopes
}


#$roleDefinitions = Get-MgRoleManagementDirectoryRoleDefinition
$policyAssignments = Get-MgPolicyRoleManagementPolicyAssignment -Filter "scopeId eq '/' and scopeType eq 'DirectoryRole'" -ExpandProperty 'policy($expand=rules)'
$eligibilitySchedules = Get-MgRoleManagementDirectoryRoleEligibilitySchedule -ExpandProperty "directoryScope,principal,roleDefinition" 

$matchPolicyAssignment = @{
    l="PolicyAssignment";
    e={
        $policyAssignments | Where-Object RoleDefinitionId -eq $_.RoleDefinitionId;
    }
}

$combinedRoleSettings = $eligibilitySchedules | Select-Object -Property *,$matchPolicyAssignment | Sort-Object RoleDefinitionId


# Notification_Admin_Admin_Assignment
# Notification_Admin_Admin_Eligibility
# Notification_Admin_EndUser_Assignment
# Notification_Approver_Admin_Assignment
# Notification_Approver_Admin_Eligibility
# Notification_Approver_EndUser_Assignment
# Notification_Requestor_Admin_Assignment
# Notification_Requestor_Admin_Eligibility
# Notification_Requestor_EndUser_Assignment

# $rule["@odata.type"] -eq "#microsoft.graph.unifiedRoleManagementPolicyNotificationRule"
# "Notification_Requestor_EndUser_Assignment" -split "_"
# 0: Notification
# 1: $recipientType = $rule.AdditionalProperties.recipientType;
# 2: $targetCaller = $rule.Target.caller;
# 3: $targetLevel = $rule.Target.level;
# group by $targetCaller $targetLevel (the action that will spawn the notification)
#
# $defaultRecipient = $target.AdditionalProperties.isDefaultRecipientsEnabled;
# $additionalRecipients = $target.AdditionalProperties.notificationRecipients;

$report = $combinedRoleSettings | ForEach-Object {

    $policy = $_.PolicyAssignment.Policy;

    $viewModel = [PSCustomObject][Ordered]@{
        Name = $_.RoleDefinition.DisplayName
        EligiblePrincipal = $_.Principal.AdditionalProperties.userPrincipalName
    }

    $groupedRules = $policy.Rules | Sort-Object { $_["@odata.type"] } | Group-Object { $_["@odata.type"] }
    $groupedRules | ForEach-Object {
        $rules = $_.Group
        $ruleType = $_.Name
        switch($ruleType) {
            "#microsoft.graph.unifiedRoleManagementPolicyNotificationRule" {
                $rules | Select-Object -Property *,@{
                    l="RecipientType";
                    e={
                        $_.AdditionalProperties.recipientType;
                    }
                },
                @{
                    l="TargetCaller";
                    e={
                        $_.Target.caller;
                    }
                },
                @{
                    l="TargetLevel";
                    e={
                        $_.Target.level
                    }
                } | Sort-Object -Property TargetCaller,TargetLevel,RecipientType | ForEach-Object {
                    $rule = $_;

                    $abbr = "N_" + $rule.TargetCaller.Substring(0,3) + $rule.TargetLevel.Substring(0,3) + "_" + $rule.RecipientType.Substring(0,3);

                    $recipients = @();
                    if($rule.AdditionalProperties.isDefaultRecipientsEnabled) {
                        $recipients += "<Default>";
                    }

                    $additionalRecipients = $rule.AdditionalProperties.notificationRecipients;
                    if(-not [String]::IsNullOrEmpty($additionalRecipients)) {
                        $recipients += $additionalRecipients;
                    }

                    $viewModel | Add-Member -NotePropertyName $abbr -NotePropertyValue ($recipients -join ';')
                }
            }
            "#microsoft.graph.unifiedRoleManagementPolicyApprovalRule" {
                $rules | ForEach-Object {
                    $rule = $_
                    $viewModel | Add-Member -NotePropertyName "ReqApproval" -NotePropertyValue ($rule.AdditionalProperties.setting.isApprovalRequired)

                    $approvers = @()

                    $primaryApprovers = $rule.AdditionalProperties.setting.approvalStages.primaryApprovers;
                    if($NULL -ne $primaryApprovers) {
                        $approvers = $primaryApprovers | ForEach-Object {
                            $dirObject = Get-MgDirectoryObject -DirectoryObjectId $_.id
                            return $dirObject.userPrincipalName
                        }
                    }
                    $viewModel | Add-Member -NotePropertyName "Approvers" -NotePropertyValue ($approvers -join ';')
                }
            }
            "#microsoft.graph.unifiedRoleManagementPolicyAuthenticationContextRule" {}
            "#microsoft.graph.unifiedRoleManagementPolicyEnablementRule" {
                $rules | Sort-Object -Property Id | ForEach-Object {
                    $rule = $_
                    if($rule.Target.caller -eq "EndUser" -and $rule.Target.level -eq "Assignment") {
                        $enabledRules = $rule.AdditionalProperties.enabledRules
                        $viewModel | Add-Member -NotePropertyName "ReqMFA" -NotePropertyValue ($enabledRules -contains "MultiFactorAuthentication")
                        $viewModel | Add-Member -NotePropertyName "ReqJust" -NotePropertyValue ($enabledRules -contains "Justification")
                        $viewModel | Add-Member -NotePropertyName "ReqTicket" -NotePropertyValue ($enabledRules -contains "Ticketing")
                    }
                }
            }
            "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" {
                $rules | Sort-Object -Property Id | ForEach-Object {
                    $rule = $_
                    if($rule.Target.caller -eq "EndUser" -and $rule.Target.level -eq "Assignment") {
                        $viewModel | Add-Member -NotePropertyName "MaxDur" -NotePropertyValue ($rule.AdditionalProperties.maximumDuration)
                    }
                }
            }

        }
    }

    return $viewModel
}

$report | ft *

# Approval_EndUser_Assignment
# AuthenticationContext_EndUser_Assignment
# Enablement_Admin_Assignment
# Enablement_Admin_Eligibility
# Enablement_EndUser_Assignment
# Expiration_Admin_Assignment
# Expiration_Admin_Eligibility
# Expiration_EndUser_Assignment

⚠️ **GitHub.com Fallback** ⚠️