From b752f2bedee008dbf0642e4aa384bfa707532e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Thu, 7 Mar 2024 20:56:21 +0100 Subject: [PATCH] add get-PIMGroupPolicy --- EasyPIM/functions/Get-PIMGroupPolicy.ps1 | 88 +++++++++++ EasyPIM/internal/functions/Invoke-graph.ps1 | 2 +- .../internal/functions/get-GroupConfig.ps1 | 143 ++++++++++++++++++ 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 EasyPIM/functions/Get-PIMGroupPolicy.ps1 create mode 100644 EasyPIM/internal/functions/get-GroupConfig.ps1 diff --git a/EasyPIM/functions/Get-PIMGroupPolicy.ps1 b/EasyPIM/functions/Get-PIMGroupPolicy.ps1 new file mode 100644 index 0000000..785cf71 --- /dev/null +++ b/EasyPIM/functions/Get-PIMGroupPolicy.ps1 @@ -0,0 +1,88 @@ +<# +.Synopsis +EASYPIM +Powershell module to manage PIM Azure Resource Role settings with simplicity in mind +Get-PIMGroupPolicy will return the policy rules (like require MFA on activation) of the selected rolename at the subscription level +Support querrying multi roles at once + +.Description + +Get-PIMGroupPolicy will use the Microsoft Graph APIs to retrieve the PIM settings of the role $rolename + +.PARAMETER tenantID +Tenant ID + +.PARAMETER GroupID +Id of the group to check + +.PARAMETER GroupName +Search for the group by name + +.Example + PS> Get-PIMGroupPolicy -tenantID $tenantID -rolename "Global Administrator","Global Reader" + + show curent config for the roles global administrator and global reader + +.Link + https://learn.microsoft.com/en-us/azure/governance/resource-graph/first-query-rest-api + https://learn.microsoft.com/en-us/graph/identity-governance-pim-rules-overview + Duration ref https://en.wikipedia.org/wiki/ISO_8601#Durations +.Notes + Homepage: https://github.com/kayasax/easyPIM + Author: MICHEL, Loic + Changelog: + Todo: + * allow other scopes +#> +function Get-PIMGroupPolicy { + [CmdletBinding()] + [OutputType([PSCustomObject])] + param ( + + [Parameter(Position = 0, Mandatory = $true)] + [System.String] + # Tenant ID + $tenantID, + + [Parameter(Position = 1)] + [System.String[]] + # Array of role name + $groupID, + + [Parameter(Position = 2)] + [System.String] + # Array of role name + $groupName, + + [Parameter(Mandatory = $true)] + [System.String] + #owner or member + $type + + + ) + try { + $script:tenantID = $tenantID + + if ($PSBoundParameters.ContainsKey('groupname')) { + $endpoint="/groups?`$filter=startswith(displayName,'$($groupName)')" + $response=invoke-graph -Endpoint $endpoint + $groupID+=$response.value.id + + } + + + $out = @() + $groupID | ForEach-Object { + + #get curent config + $config = get-GroupConfig $_ $type + $out += $config + } + Write-Output $out -NoEnumerate + } + catch { + MyCatch $_ + } + +} \ No newline at end of file diff --git a/EasyPIM/internal/functions/Invoke-graph.ps1 b/EasyPIM/internal/functions/Invoke-graph.ps1 index 11cb0a3..3500510 100644 --- a/EasyPIM/internal/functions/Invoke-graph.ps1 +++ b/EasyPIM/internal/functions/Invoke-graph.ps1 @@ -41,7 +41,7 @@ function invoke-graph { if ( $null -eq (get-mgcontext) -or ( (get-mgcontext).TenantId -ne $script:tenantID ) ) { Write-Verbose ">> Connecting to Azure with tenantID $script:tenantID" - Connect-MgGraph -Tenant $script:tenantID -Scopes RoleManagementPolicy.ReadWrite.Directory, RoleManagement.ReadWrite.Directory + Connect-MgGraph -Tenant $script:tenantID -Scopes RoleManagementPolicy.ReadWrite.Directory, RoleManagement.ReadWrite.Directory, RoleManagementPolicy.ReadWrite.AzureADGroup } <# # Authenticate and get the access token diff --git a/EasyPIM/internal/functions/get-GroupConfig.ps1 b/EasyPIM/internal/functions/get-GroupConfig.ps1 new file mode 100644 index 0000000..027eb27 --- /dev/null +++ b/EasyPIM/internal/functions/get-GroupConfig.ps1 @@ -0,0 +1,143 @@ +<#Get-PIMGroupPolicyGet-PIMGroupPolicy + .Synopsis + Get rules for the group $groupID + .Description + will convert the json rules to a PSCustomObject + .Parameter id + Id of the group to check + .Example + PS> get-config -scope $scop -rolename role1 + + Get the policy of the role role1 at the specified scope + + .Notes + Author: Loïc MICHEL + Homepage: https://github.com/kayasax/EasyPIM + #> +function get-Groupconfig ( $id, $type) { + + try { + + $endpoint = "policies/roleManagementPolicyAssignments?`$filter=scopeId eq '$id' and scopeType eq 'Group' and roleDefinitionId eq '$type'&`$expand=policy(`$expand=rules)" + $response = invoke-graph -Endpoint $endpoint + + $policyId=$response.value.id + #$response + # Get config values in a new object: + + # Maximum end user activation duration in Hour (PT24H) // Max 24H in portal but can be greater + $_activationDuration = $response.value.policy.rules | Where-Object { $_.id -eq "Expiration_EndUser_Assignment" } | Select-Object -ExpandProperty maximumduration + # End user enablement rule (MultiFactorAuthentication, Justification, Ticketing) + $_enablementRules = $response.value.policy.rules | Where-Object { $_.id -eq "Enablement_EndUser_Assignment" } | Select-Object -expand enabledRules + # approval required + $_approvalrequired = $($response.value.policy.rules | Where-Object { $_.id -eq "Approval_EndUser_Assignment" }).setting.isapprovalrequired + # approvers + $approvers = $($response.value.policy.rules | Where-Object { $_.id -eq "Approval_EndUser_Assignment" }).setting.approvalStages.primaryApprovers + if(( $approvers | Measure-Object | Select-Object -ExpandProperty Count) -gt 0){ + $approvers | ForEach-Object { + if($_."@odata.type" -eq "#microsoft.graph.groupMembers"){ + $_.userType = "group" + $_.id=$_.groupID + } + else{ #"@odata.type": "#microsoft.graph.singleUser", + $_.userType = "user" + $_.id=$_.userID + } + + $_approvers += '@{"id"="' + $_.id + '";"description"="' + $_.description + '";"userType"="' + $_.userType + '"},' + } + } + + # permanent assignmnent eligibility + $_eligibilityExpirationRequired = $response.value.policy.rules | Where-Object { $_.id -eq "Expiration_Admin_Eligibility" } | Select-Object -expand isExpirationRequired + if ($_eligibilityExpirationRequired -eq "true") { + $_permanantEligibility = "false" + } + else { + $_permanantEligibility = "true" + } + # maximum assignment eligibility duration + $_maxAssignmentDuration = $response.value.policy.rules | Where-Object { $_.id -eq "Expiration_Admin_Eligibility" } | Select-Object -expand maximumDuration + + # pemanent activation + $_activeExpirationRequired = $response.value.policy.rules | Where-Object { $_.id -eq "Expiration_Admin_Assignment" } | Select-Object -expand isExpirationRequired + if ($_activeExpirationRequired -eq "true") { + $_permanantActiveAssignment = "false" + } + else { + $_permanantActiveAssignment = "true" + } + # maximum activation duration + $_maxActiveAssignmentDuration = $response.value.policy.rules | Where-Object { $_.id -eq "Expiration_Admin_Assignment" } | Select-Object -expand maximumDuration + + ################# + # Notifications # + ################# + + # Notification Eligibility Alert (Send notifications when members are assigned as eligible to this role) + $_Notification_Admin_Admin_Eligibility = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Admin_Admin_Eligibility" } + # Notification Eligibility Assignee (Send notifications when members are assigned as eligible to this role: Notification to the assigned user (assignee)) + $_Notification_Eligibility_Assignee = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Requestor_Admin_Eligibility" } + # Notification Eligibility Approvers (Send notifications when members are assigned as eligible to this role: request to approve a role assignment renewal/extension) + $_Notification_Eligibility_Approvers = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Approver_Admin_Eligibility" } + + # Notification Active Assignment Alert (Send notifications when members are assigned as active to this role) + $_Notification_Active_Alert = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Admin_Admin_Assignment" } + # Notification Active Assignment Assignee (Send notifications when members are assigned as active to this role: Notification to the assigned user (assignee)) + $_Notification_Active_Assignee = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Requestor_Admin_Assignment" } + # Notification Active Assignment Approvers (Send notifications when members are assigned as active to this role: Request to approve a role assignment renewal/extension) + $_Notification_Active_Approvers = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Approver_Admin_Assignment" } + + # Notification Role Activation Alert (Send notifications when eligible members activate this role: Role activation alert) + $_Notification_Activation_Alert = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Admin_EndUser_Assignment" } + # Notification Role Activation Assignee (Send notifications when eligible members activate this role: Notification to activated user (requestor)) + $_Notification_Activation_Assignee = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Requestor_EndUser_Assignment" } + # Notification Role Activation Approvers (Send notifications when eligible members activate this role: Request to approve an activation) + $_Notification_Activation_Approver = $response.value.policy.rules | Where-Object { $_.id -eq "Notification_Approver_EndUser_Assignment" } + + + $config = [PSCustomObject]@{ + + PolicyID = $policyId + ActivationDuration = $_activationDuration + EnablementRules = $_enablementRules -join ',' + ApprovalRequired = $_approvalrequired + Approvers = $_approvers -join ',' + AllowPermanentEligibleAssignment = $_permanantEligibility + MaximumEligibleAssignmentDuration = $_maxAssignmentDuration + AllowPermanentActiveAssignment = $_permanantActiveAssignment + MaximumActiveAssignmentDuration = $_maxActiveAssignmentDuration + Notification_Eligibility_Alert_isDefaultRecipientEnabled = $($_Notification_Admin_Admin_Eligibility.isDefaultRecipientsEnabled) + Notification_Eligibility_Alert_NotificationLevel = $($_Notification_Admin_Admin_Eligibility.notificationLevel) + Notification_Eligibility_Alert_Recipients = $($_Notification_Admin_Admin_Eligibility.notificationRecipients) -join ',' + Notification_Eligibility_Assignee_isDefaultRecipientEnabled = $($_Notification_Eligibility_Assignee.isDefaultRecipientsEnabled) + Notification_Eligibility_Assignee_NotificationLevel = $($_Notification_Eligibility_Assignee.NotificationLevel) + Notification_Eligibility_Assignee_Recipients = $($_Notification_Eligibility_Assignee.notificationRecipients) -join ',' + Notification_Eligibility_Approvers_isDefaultRecipientEnabled = $($_Notification_Eligibility_Approvers.isDefaultRecipientsEnabled) + Notification_Eligibility_Approvers_NotificationLevel = $($_Notification_Eligibility_Approvers.NotificationLevel) + Notification_Eligibility_Approvers_Recipients = $($_Notification_Eligibility_Approvers.notificationRecipients -join ',') + Notification_Active_Alert_isDefaultRecipientEnabled = $($_Notification_Active_Alert.isDefaultRecipientsEnabled) + Notification_Active_Alert_NotificationLevel = $($_Notification_Active_Alert.notificationLevel) + Notification_Active_Alert_Recipients = $($_Notification_Active_Alert.notificationRecipients -join ',') + Notification_Active_Assignee_isDefaultRecipientEnabled = $($_Notification_Active_Assignee.isDefaultRecipientsEnabled) + Notification_Active_Assignee_NotificationLevel = $($_Notification_Active_Assignee.notificationLevel) + Notification_Active_Assignee_Recipients = $($_Notification_Active_Assignee.notificationRecipients -join ',') + Notification_Active_Approvers_isDefaultRecipientEnabled = $($_Notification_Active_Approvers.isDefaultRecipientsEnabled) + Notification_Active_Approvers_NotificationLevel = $($_Notification_Active_Approvers.notificationLevel) + Notification_Active_Approvers_Recipients = $($_Notification_Active_Approvers.notificationRecipients -join ',') + Notification_Activation_Alert_isDefaultRecipientEnabled = $($_Notification_Activation_Alert.isDefaultRecipientsEnabled) + Notification_Activation_Alert_NotificationLevel = $($_Notification_Activation_Alert.NotificationLevel) + Notification_Activation_Alert_Recipients = $($_Notification_Activation_Alert.NotificationRecipients -join ',') + Notification_Activation_Assignee_isDefaultRecipientEnabled = $($_Notification_Activation_Assignee.isDefaultRecipientsEnabled) + Notification_Activation_Assignee_NotificationLevel = $($_Notification_Activation_Assignee.NotificationLevel) + Notification_Activation_Assignee_Recipients = $($_Notification_Activation_Assignee.NotificationRecipients -join ',') + Notification_Activation_Approver_isDefaultRecipientEnabled = $($_Notification_Activation_Approver.isDefaultRecipientsEnabled) + Notification_Activation_Approver_NotificationLevel = $($_Notification_Activation_Approver.NotificationLevel) + Notification_Activation_Approver_Recipients = $($_Notification_Activation_Approver.NotificationRecipients -join ',') + } + return $config + } + catch { + Mycatch $_ + } +} \ No newline at end of file