From 8334df017dcd4bef647ca8254373a2621b946dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Fri, 8 Mar 2024 19:48:40 +0100 Subject: [PATCH 1/6] update description --- EasyPIM/EasyPIM.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EasyPIM/EasyPIM.psd1 b/EasyPIM/EasyPIM.psd1 index 91d40a0..f1475db 100644 --- a/EasyPIM/EasyPIM.psd1 +++ b/EasyPIM/EasyPIM.psd1 @@ -22,7 +22,7 @@ Author = 'Loïc MICHEL' Copyright = '(c) loicmichel. All rights reserved.' # Description of the functionality provided by this module -Description = 'Powershell module to manage PIM Azure Resource and PIM Entra role settings and assignments with simplicity in mind' +Description = 'Powershell module to manage PIM Azure Resource, PIM Entra role and PIM for Group settings and assignments with simplicity in mind' # Minimum version of the PowerShell engine required by this module # PowerShellVersion = '' From 870ca404d9c93447f7759921ca5551afb782e44c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Mon, 18 Mar 2024 16:08:55 +0100 Subject: [PATCH 2/6] update help --- .../Get-PIMEntraRoleActiveAssignment.ps1 | 4 +- .../Get-PIMGroupActiveAssignment.ps1 | 37 +++--- EasyPIM/functions/Get-PIMGroupPolicy.ps1 | 21 +-- .../New-PIMEntraRoleActiveAssignment.ps1 | 6 +- .../New-PIMEntraRoleEligibleAssignment.ps1 | 12 +- .../New-PIMGroupActiveAssignment.ps1 | 23 ++-- .../Remove-PIMEntraRoleActiveAssignment.ps1 | 20 +-- .../functions/Set-PIMAzureResourcePolicy.ps1 | 2 +- EasyPIM/functions/Set-PIMGroupPolicy.ps1 | 12 +- EasyPIM/internal/functions/Invoke-graph.ps1 | 12 +- EasyPIM/internal/functions/Set-Approval.ps1 | 121 ++++++++++-------- .../functions/Set-ApprovalFromCSV.ps1 | 4 +- 12 files changed, 132 insertions(+), 142 deletions(-) diff --git a/EasyPIM/functions/Get-PIMEntraRoleActiveAssignment.ps1 b/EasyPIM/functions/Get-PIMEntraRoleActiveAssignment.ps1 index 00cac2c..46c6088 100644 --- a/EasyPIM/functions/Get-PIMEntraRoleActiveAssignment.ps1 +++ b/EasyPIM/functions/Get-PIMEntraRoleActiveAssignment.ps1 @@ -15,9 +15,9 @@ Filter by principalName .Example - PS> Get-PIMEntraRoleActiveAssignment -tenantID $tid + PS> Get-PIMEntraRoleActiveAssignment -tenantID $tid -rolename "testrole" -principalName "loic" - List active assignement + List active assignement for role "testrole" and user name "loic" .Link diff --git a/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 b/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 index f67a7a5..783a3e4 100644 --- a/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 +++ b/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 @@ -1,24 +1,26 @@ <# .Synopsis - List of PIM Entra Role active assignement + List active assignements for a group .Description Active assignment does not require to activate their role. https://learn.microsoft.com/en-us/graph/api/rbacapplication-list-roleeligibilityscheduleinstances?view=graph-rest-1.0&tabs=http .Parameter tenantID EntraID tenant ID + .PARAMETER groupID + The group id to check + .PARAMETER memberType + Filter results by memberType (owner or member) + .PARAMETER principalName + Filter results by principalName starting with the given value .Parameter summary When enabled will return the most useful information only - .PARAMETER rolename - Filter by rolename - .PARAMETER principalid - Filter by principalid - .PARAMETER principalName - Filter by principalName - .Example - PS> Get-PIMEntraRoleActiveAssignment -tenantID $tid + PS> Get-PIMGroupActiveAssignment -tenantID $tid -groupID $gID - List active assignement + List active assignement for the group $gID + .Example + PS> Get-PIMGroupActiveAssignment -tenantID $tid -groupID $gID -memberType owner -principalName "loic" -summary + Get a summary of the active assignement for the group $gID, for the owner role and for the user "loic" .Link .Notes @@ -32,11 +34,10 @@ function Get-PIMGroupActiveAssignment { [Parameter(Position = 0, Mandatory = $true)] [String] $tenantID, - # select the most usefull info only - [switch]$summary, [string]$groupID, - [string]$rolename, - [string]$principalName + [string]$memberType, + [string]$principalName, + [switch]$summary ) try { @@ -49,17 +50,13 @@ function Get-PIMGroupActiveAssignment { $response.value | ForEach-Object { $r = @{ - #"rolename" = $_.roledefinition.displayName - #"roleid" = $_.roledefinition.id "principalname" = $_.principal.displayName "principalid" = $_.principal.id "principalEmail" = $_.principal.mail "startDateTime" = $_.scheduleInfo.startDateTime "endDateTime" = $_.scheduleInfo.expiration.endDateTime - #"directoryScopeId" = $_.directoryScopeId "memberType" = $_.accessId "assignmentType" = $_.memberType - #"activatedUsing"=$_.activatedUsing "principaltype" = $_.principal."@odata.type" "id" = $_.id } @@ -76,8 +73,8 @@ function Get-PIMGroupActiveAssignment { $resu = $resu | Where-Object { $_.principalid -eq $principalid } } - if ($PSBoundParameters.Keys.Contains('rolename')) { - $resu = $resu | Where-Object { $_.rolename -eq $rolename } + if ($PSBoundParameters.Keys.Contains('memberType')) { + $resu = $resu | Where-Object { $_.memberType -eq $memberType } } if($PSBoundParameters.Keys.Contains('principalName')){ $resu = $resu | Where-Object { $_.principalName -match $principalName } diff --git a/EasyPIM/functions/Get-PIMGroupPolicy.ps1 b/EasyPIM/functions/Get-PIMGroupPolicy.ps1 index 785cf71..9345219 100644 --- a/EasyPIM/functions/Get-PIMGroupPolicy.ps1 +++ b/EasyPIM/functions/Get-PIMGroupPolicy.ps1 @@ -1,13 +1,9 @@ <# .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 +Get member or owner PIM settings for a group .Description - -Get-PIMGroupPolicy will use the Microsoft Graph APIs to retrieve the PIM settings of the role $rolename +Get member or owner PIM settings for a group .PARAMETER tenantID Tenant ID @@ -18,10 +14,17 @@ Id of the group to check .PARAMETER GroupName Search for the group by name +.PARAMETER type +owner or member + +.Example +PS> Get-PIMGroupPolicy -tenantID $tenantID -groupID $gID -type member + +show curent config for the member role of the group $gID .Example - PS> Get-PIMGroupPolicy -tenantID $tenantID -rolename "Global Administrator","Global Reader" +PS> Get-PIMGroupPolicy -tenantID $tenantID -groupname "Mygroup" -type owner - show curent config for the roles global administrator and global reader +show curent config for the owner role of the group "Mygroup" .Link https://learn.microsoft.com/en-us/azure/governance/resource-graph/first-query-rest-api @@ -31,8 +34,6 @@ Search for the group by name Homepage: https://github.com/kayasax/easyPIM Author: MICHEL, Loic Changelog: - Todo: - * allow other scopes #> function Get-PIMGroupPolicy { [CmdletBinding()] diff --git a/EasyPIM/functions/New-PIMEntraRoleActiveAssignment.ps1 b/EasyPIM/functions/New-PIMEntraRoleActiveAssignment.ps1 index 5d40480..dfa9675 100644 --- a/EasyPIM/functions/New-PIMEntraRoleActiveAssignment.ps1 +++ b/EasyPIM/functions/New-PIMEntraRoleActiveAssignment.ps1 @@ -1,14 +1,10 @@ <# .Synopsis - Create an active assignement at the provided scope + Create an active assignement for the role $rolename and for the principal $principalID .Description Active assignment does not require users to activate their role. https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles .Parameter tenantID EntraID tenant ID - .Parameter subscriptionID - subscription ID - .Parameter scope - use scope parameter if you want to work at other scope than a subscription .Parameter principalID objectID of the principal (user, group or service principal) .Parameter rolename diff --git a/EasyPIM/functions/New-PIMEntraRoleEligibleAssignment.ps1 b/EasyPIM/functions/New-PIMEntraRoleEligibleAssignment.ps1 index 138b329..7e329ff 100644 --- a/EasyPIM/functions/New-PIMEntraRoleEligibleAssignment.ps1 +++ b/EasyPIM/functions/New-PIMEntraRoleEligibleAssignment.ps1 @@ -1,14 +1,10 @@ <# .Synopsis - Create an active assignement at the provided scope + Create an eligible assignement for $rolename and for the principal $principalID .Description - Active assignment does not require users to activate their role. https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles + Eligible assignment require users to activate their role. https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles .Parameter tenantID EntraID tenant ID - .Parameter subscriptionID - subscription ID - .Parameter scope - use scope parameter if you want to work at other scope than a subscription .Parameter principalID objectID of the principal (user, group or service principal) .Parameter rolename @@ -24,11 +20,11 @@ .Example - PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -subscriptionID $subscriptionId -rolename "AcrPush" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -startDateTime "2/2/2024 18:20" + PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -rolename "AcrPush" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -startDateTime "2/2/2024 18:20" Create an active assignment fot the role Arcpush, starting at a specific date and using default duration - PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -subscriptionID $subscriptionId -rolename "webmaster" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -justification 'TEST' -permanent + PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -rolename "webmaster" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -justification 'TEST' -permanent Create a permanent active assignement for the role webmaster diff --git a/EasyPIM/functions/New-PIMGroupActiveAssignment.ps1 b/EasyPIM/functions/New-PIMGroupActiveAssignment.ps1 index b36a87d..ca4627c 100644 --- a/EasyPIM/functions/New-PIMGroupActiveAssignment.ps1 +++ b/EasyPIM/functions/New-PIMGroupActiveAssignment.ps1 @@ -1,20 +1,18 @@ <# .Synopsis - Create an active assignement at the provided scope + Create an active assignement for the group $groupID and for the principal $principalID .Description Active assignment does not require users to activate their role. https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles .Parameter tenantID EntraID tenant ID - .Parameter subscriptionID - subscription ID - .Parameter scope - use scope parameter if you want to work at other scope than a subscription + .Parameter groupID + objectID of the group .Parameter principalID objectID of the principal (user, group or service principal) - .Parameter rolename - name of the role to assign + .Parameter type + member type (owner or member) .Parameter duration - duration of the assignment, if not set we will use the maximum allowed value from the role policy + duration of the assignment, if not set we will use the maximum allowed value from the policy .Parameter startDateTime When the assignment wil begin, if not set we will use current time .Parameter permanent @@ -24,14 +22,13 @@ .Example - PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -subscriptionID $subscriptionId -rolename "AcrPush" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -startDateTime "2/2/2024 18:20" + PS> New-PIMGroupActiveAssignment -tenantID $tenantID -groupID $gID -principalID $userID -type member -duration "P7D" - Create an active assignment fot the role Arcpush, starting at a specific date and using default duration + Create an active assignment for the membership role of the group $gID and principal $userID starting now and using a duration of 7 days - PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -subscriptionID $subscriptionId -rolename "webmaster" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -justification 'TEST' -permanent + PS> New-PIMGroupActiveAssignment -tenantID $tenantID -groupID $gID -principalID $userID -type owner -permanent - Create a permanent active assignement for the role webmaster - + Create a permanent active assignement for the ownership role of the group $gID and principal $userID starting now .Link https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles .Notes diff --git a/EasyPIM/functions/Remove-PIMEntraRoleActiveAssignment.ps1 b/EasyPIM/functions/Remove-PIMEntraRoleActiveAssignment.ps1 index 2844fe2..fd1a70a 100644 --- a/EasyPIM/functions/Remove-PIMEntraRoleActiveAssignment.ps1 +++ b/EasyPIM/functions/Remove-PIMEntraRoleActiveAssignment.ps1 @@ -1,6 +1,6 @@ <# .Synopsis - Create an active assignement at the provided scope + Remove an active assignement for $rolename and for the principal $principalID .Description Active assignment does not require users to activate their role. https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles .Parameter tenantID @@ -24,13 +24,13 @@ .Example - PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -subscriptionID $subscriptionId -rolename "AcrPush" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -startDateTime "2/2/2024 18:20" + PS> Remove-PIMEntraRoleActiveAssignment -tenantID $tenantID -rolename "AcrPush" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -startDateTime "2/2/2024 18:20" - Create an active assignment fot the role Arcpush, starting at a specific date and using default duration + Remove the active assignment for the role Arcpush and principal $principalID, at a specific date - PS> New-PIMEntraRoleEligibleAssignment -tenantID $tenantID -subscriptionID $subscriptionId -rolename "webmaster" -principalID 3604fe63-cb67-4b60-99c9-707d46ab9092 -justification 'TEST' -permanent + PS> Remove-PIMEntraRoleActiveAssignment -tenantID $tenantID -rolename "webmaster" -principalname "loic" -justification 'TEST' - Create a permanent active assignement for the role webmaster + Remove the active assignement for the role webmaster and username "loic" .Link https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles @@ -57,21 +57,13 @@ function Remove-PIMEntraRoleActiveAssignment { # the rolename for which we want to create an assigment $rolename, - [string] - # duration of the assignment, if not set we will use the maximum allowed value from the role policy - $duration, - [string] # stat date of assignment if not provided we will use curent time $startDateTime, [string] # justification (will be auto generated if not provided) - $justification, - - [switch] - # the assignment will not expire - $permanent + $justification ) diff --git a/EasyPIM/functions/Set-PIMAzureResourcePolicy.ps1 b/EasyPIM/functions/Set-PIMAzureResourcePolicy.ps1 index b1657bd..bea9d0f 100644 --- a/EasyPIM/functions/Set-PIMAzureResourcePolicy.ps1 +++ b/EasyPIM/functions/Set-PIMAzureResourcePolicy.ps1 @@ -257,7 +257,7 @@ function Set-PIMAzureResourcePolicy { # Bringing all the rules together and patch the policy $allrules = $rules -join ',' - #Write-Verbose "All rules: $allrules" + Write-Verbose "All rules: $allrules" #Patching the policy if ($PSCmdlet.ShouldProcess($_, "Udpdating policy")) { diff --git a/EasyPIM/functions/Set-PIMGroupPolicy.ps1 b/EasyPIM/functions/Set-PIMGroupPolicy.ps1 index 5a44471..d889dc1 100644 --- a/EasyPIM/functions/Set-PIMGroupPolicy.ps1 +++ b/EasyPIM/functions/Set-PIMGroupPolicy.ps1 @@ -1,16 +1,16 @@ <# .Synopsis - Set the setting of the role $rolename + Set the setting for the owner and member roles of a group .Description - Set the setting of the role $rolename + set the setting for the owner and member roles of a group .Example - PS> Set-PIMEntraRolePolicy -tenantID $tenantID -rolename webmaster -ActivationDuration "PT8H" + PS> Set-PIMGroupPolicy -tenantID $tenantID -groupID $gID -ActivationDuration "PT8H" -type "owner" - Limit the maximum PIM activation duration to 8h + Limit the maximum activation duration to 8h for owner role of the group $gID .EXAMPLE - PS> Set-PIMGroupPolicy -tenantID $tenantID -groupID "ba6af9bf-6b28-4799-976e-ff71aed3a1bd" -type owner -ActivationDuration "P1D" -ApprovalRequired $true -Approvers @(@{"Id"="25f3deb5-1c8d-4035-942d-b3cbbad98b8e";"Name"="God";"Type"="user"}) -Notification_EligibleAssignment_Alert @{"isDefaultRecipientEnabled"="true"; "notificationLevel"="All";"Recipients" = @("email1@domain.com","email2@domain.com")} + PS> Set-PIMGroupPolicy -tenantID $tenantID -groupID $gID -type member -ActivationDuration "P1D" -ApprovalRequired $true -Approvers @(@{"Id"="25f3deb5-1c8d-4035-942d-b3cbbad98b8e";"Name"="John";"Type"="user"}) -Notification_EligibleAssignment_Alert @{"isDefaultRecipientEnabled"="true"; "notificationLevel"="All";"Recipients" = @("email1@domain.com","email2@domain.com")} - Require activation approval and set John as an approver + Require approval on activation and set John as an approver, configure some notifications for the member role of the group $gIDs .Link diff --git a/EasyPIM/internal/functions/Invoke-graph.ps1 b/EasyPIM/internal/functions/Invoke-graph.ps1 index 3500510..b9cafce 100644 --- a/EasyPIM/internal/functions/Invoke-graph.ps1 +++ b/EasyPIM/internal/functions/Invoke-graph.ps1 @@ -43,17 +43,7 @@ function invoke-graph { Write-Verbose ">> Connecting to Azure with tenantID $script:tenantID" Connect-MgGraph -Tenant $script:tenantID -Scopes RoleManagementPolicy.ReadWrite.Directory, RoleManagement.ReadWrite.Directory, RoleManagementPolicy.ReadWrite.AzureADGroup } - <# - # Authenticate and get the access token - $token = Get-AzAccessToken -ResourceTypeName MSGraph - - if( $body -ne ""){ - Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Bearer $($token.Token)"} -Method $Method -Body $body - } - else{ - Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Bearer $($token.Token)"} -Method $Method - } - #> + if ( $body -ne "") { Invoke-MgGraphRequest -Uri $uri -Method $Method -Body $body } diff --git a/EasyPIM/internal/functions/Set-Approval.ps1 b/EasyPIM/internal/functions/Set-Approval.ps1 index 280af6b..1594a54 100644 --- a/EasyPIM/internal/functions/Set-Approval.ps1 +++ b/EasyPIM/internal/functions/Set-Approval.ps1 @@ -20,17 +20,34 @@ #> function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { - Write-Verbose "Set-Approval" - if ($null -eq $Approvers) { $Approvers = $script:config.Approvers } - if ($ApprovalRequired -eq $false) { $req = "false" }else { $req = "true" } - - $rule = ' + try { + Write-Verbose "Set-Approval" + if ($null -eq $Approvers) { $Approvers = $script:config.Approvers } + if ($ApprovalRequired -eq $false) { $req = "false" }else { $req = "true" } + <#working sample + {"properties":{"scope":"/subscriptions/eedcaa84-3756-4da9-bf87-40068c3dd2a2","rules":[ +{"id":"Approval_EndUser_Assignment","ruleType":"RoleManagementPolicyApprovalRule", +"target":{"caller":"EndUser","operations":["All"],"level":"Assignment"}, +"setting":{"isApprovalRequired":false, +"isApprovalRequiredForExtension":false, +"isRequestorJustificationRequired":true, +"approvalMode":"SingleStage", +"approvalStages":[{"approvalStageTimeOutInDays":1,"isApproverJustificationRequired":true,"escalationTimeInMinutes":0,"isEscalationEnabled":false, +"primaryApprovers":[{"id":"5dba24e0-00ef-4c21-9702-7c093a0775eb","userType":"Group","description":"0Ext_Partners","isBackup":false}, +{"id":"00b34bb3-8a6b-45ce-a7bb-c7f7fb400507","userType":"User","description":"Bob MARLEY","isBackup":false}, +{"id":"25f3deb5-1c8d-4035-942d-b3cbbad98b8e","userType":"User","description":"Loïc","isBackup":false}, +{"id":"39014f60-8bf7-4d58-88e3-4d6f04f7c279","userType":"User","description":"Loic MICHEL","isBackup":false} +], +"escalationApprovers":[] +}]}}]} + #> + $rule = ' { "setting": {' - if ($null -ne $ApprovalRequired) { - $rule += '"isApprovalRequired": ' + $req + ',' - } - $rule += ' + if ($null -ne $ApprovalRequired) { + $rule += '"isApprovalRequired": ' + $req + ',' + } + $rule += ' "isApprovalRequiredForExtension": false, "isRequestorJustificationRequired": true, "approvalMode": "SingleStage", @@ -41,22 +58,22 @@ function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { "escalationTimeInMinutes": 0, ' - if ($null -ne $Approvers) { - #at least one approver required if approval is enable - $rule += ' + if ($null -ne $Approvers) { + #at least one approver required if approval is enable + $rule += ' "primaryApprovers": [ ' - $cpt = 0 - $Approvers | ForEach-Object { - #write-host $_ - $id = $_.Id - $name = $_.Name - $type = $_.Type + $cpt = 0 + $Approvers | ForEach-Object { + #write-host $_ + $id = $_.Id + $name = $_.Name + $type = $_.Type - if ($cpt -gt 0) { - $rule += "," - } - $rule += ' + if ($cpt -gt 0) { + $rule += "," + } + $rule += ' { "id": "'+ $id + '", "description": "'+ $name + '", @@ -64,14 +81,14 @@ function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { "userType": "'+ $type + '" } ' - $cpt++ - } + $cpt++ + } - $rule += ' + $rule += ' ],' - } + } - $rule += ' + $rule += ' "isEscalationEnabled": false, "escalationApprovers": null }] @@ -95,8 +112,8 @@ function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { }}' -if($entraRole){ - $rule=' + if ($entraRole) { + $rule = ' { "@odata.type": "#microsoft.graph.unifiedRoleManagementPolicyApprovalRule", "id": "Approval_EndUser_Assignment", @@ -111,8 +128,8 @@ if($entraRole){ }, "setting": { "isApprovalRequired": ' - $rule+=$req - $rule+=', + $rule += $req + $rule += ', "isApprovalRequiredForExtension": false, "isRequestorJustificationRequired": true, "approvalMode": "SingleStage", @@ -123,20 +140,20 @@ if($entraRole){ "escalationTimeInMinutes": 0, "isEscalationEnabled": false, "primaryApprovers": [' - if ($null -ne $Approvers) { - #at least one approver required if approval is enable + if ($null -ne $Approvers) { + #at least one approver required if approval is enable - $cpt = 0 - $Approvers | ForEach-Object { - #write-host $_ - $id = $_.Id - $name = $_.Name - ##$type = $_.Type + $cpt = 0 + $Approvers | ForEach-Object { + #write-host $_ + $id = $_.Id + $name = $_.Name + ##$type = $_.Type - if ($cpt -gt 0) { - $rule += "," - } - $rule += ' + if ($cpt -gt 0) { + $rule += "," + } + $rule += ' { "@odata.type": "#microsoft.graph.singleUser", "isBackup": false, @@ -144,10 +161,10 @@ if($entraRole){ "description": "'+ $name + '", } ' - $cpt++ - } + $cpt++ + } - $rule += ' + $rule += ' ], @@ -156,7 +173,11 @@ if($entraRole){ ] } }' -} -} - return $rule -} + } + } + return $rule + } + catch { + MyCatch $_ + } +} \ No newline at end of file diff --git a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 index 16879da..d458814 100644 --- a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 +++ b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 @@ -24,7 +24,7 @@ function Set-ApprovalFromCSV { [CmdletBinding()] param( [Parameter(Mandatory=$false)] - [bool]$ApprovalRequired, + [string]$ApprovalRequired, [Parameter(Mandatory=$false)] [string[]]$Approvers, [Parameter(Mandatory=$false)] @@ -32,7 +32,7 @@ function Set-ApprovalFromCSV { ) write-verbose "Set-ApprovalFromCSV" if ($null -eq $Approvers) { $Approvers = $script:config.Approvers } - if ($ApprovalRequired -eq $false) { $req = "false" }else { $req = "true" } +if ($ApprovalRequired -eq "FALSE") { $req = "false" }else { $req = "true" } if (!$entraRole) { $rule = ' From 95c5e0c07452bc3be59c66c49bd7d703c5b908c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Mon, 18 Mar 2024 20:00:57 +0100 Subject: [PATCH 3/6] fix #28 set-approval --- .../internal/functions/Import-Settings.ps1 | 11 ++-- EasyPIM/internal/functions/Set-Approval.ps1 | 61 ++++++++++++++++++- .../functions/Set-ApprovalFromCSV.ps1 | 40 +++++++++--- ...et-Notification_ActiveAssignment_Alert.ps1 | 3 +- EasyPIM/internal/functions/Update-Policy.ps1 | 2 +- 5 files changed, 99 insertions(+), 18 deletions(-) diff --git a/EasyPIM/internal/functions/Import-Settings.ps1 b/EasyPIM/internal/functions/Import-Settings.ps1 index 709887b..f422b0d 100644 --- a/EasyPIM/internal/functions/Import-Settings.ps1 +++ b/EasyPIM/internal/functions/Import-Settings.ps1 @@ -23,13 +23,16 @@ function Import-Setting ($path) { $csv | ForEach-Object { $rules = @() + $script:scope=$_.policyID -replace "/providers.*" + $rules += Set-ActivationDuration $_.ActivationDuration $enablementRules = $_.EnablementRules.Split(',') $rules += Set-ActivationRequirement $enablementRules - $approvers = @() - $approvers += $_.approvers - $rules += Set-ApprovalFromCSV $_.ApprovalRequired $Approvers + #$approvers = @() + #$approvers += $_.approvers + $rules += Set-ApprovalFromCSV $_.ApprovalRequired $_.Approvers $rules += Set-EligibilityAssignmentFromCSV $_.MaximumEligibleAssignmentDuration $_.AllowPermanentEligibleAssignment + $rules += Set-ActiveAssignmentFromCSV $_.MaximumActiveAssignmentDuration $_.AllowPermanentActiveAssignment $Notification_EligibleAssignment_Alert = @{ @@ -94,7 +97,7 @@ function Import-Setting ($path) { "Recipients" = $_.Notification_Activation_Approver_Recipients.split(',') } $rules += Set-Notification_Activation_Approver $Notification_Activation_Approver - + #> # patch the policy Update-Policy $_.policyID $($rules -join ',') } diff --git a/EasyPIM/internal/functions/Set-Approval.ps1 b/EasyPIM/internal/functions/Set-Approval.ps1 index 1594a54..d47f490 100644 --- a/EasyPIM/internal/functions/Set-Approval.ps1 +++ b/EasyPIM/internal/functions/Set-Approval.ps1 @@ -40,8 +40,63 @@ function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { ], "escalationApprovers":[] }]}}]} - #> - $rule = ' + #> + + $rule = '{ + "id":"Approval_EndUser_Assignment", + "ruleType":"RoleManagementPolicyApprovalRule", + "target":{ + "caller":"EndUser", + "operations":["All"], + "level":"Assignment" + }, + "setting":{ + "isApprovalRequired":"'+ $req + '", + "isApprovalRequiredForExtension":false, + "isRequestorJustificationRequired":true, + "approvalMode":"SingleStage", + "approvalStages":[{ + "approvalStageTimeOutInDays":1, + "isApproverJustificationRequired":true, + "escalationTimeInMinutes":0, + "isEscalationEnabled":false, + "primaryApprovers":[ + ' + $cpt = 0 + $Approvers | ForEach-Object { + #write-host $_ + $id = $_.Id + $name = $_.Name + $type = $_.Type + + if ($cpt -gt 0) { + $rule += "," + } + $rule += ' + { + "id": "'+ $id + '", + "description": "'+ $name + '", + "isBackup": false, + "userType": "'+ $type + '" + } + ' + $cpt++ + } + $rule=$rule -replace ",$" #remove last comma + + <#{"id":"5dba24e0-00ef-4c21-9702-7c093a0775eb","userType":"Group","description":"0Ext_Partners","isBackup":false}, + {"id":"00b34bb3-8a6b-45ce-a7bb-c7f7fb400507","userType":"User","description":"Bob MARLEY","isBackup":false}, + {"id":"25f3deb5-1c8d-4035-942d-b3cbbad98b8e","userType":"User","description":"Loïc","isBackup":false}, + {"id":"39014f60-8bf7-4d58-88e3-4d6f04f7c279","userType":"User","description":"Loic MICHEL","isBackup":false}#> + $rule += ' + ], + "escalationApprovers":[] + }] + } +}' + + + <# $rule = ' { "setting": {' if ($null -ne $ApprovalRequired) { @@ -110,7 +165,7 @@ function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { "enforcedSettings": null }}' - +#> if ($entraRole) { $rule = ' diff --git a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 index d458814..71d8c9e 100644 --- a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 +++ b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 @@ -26,7 +26,7 @@ function Set-ApprovalFromCSV { [Parameter(Mandatory=$false)] [string]$ApprovalRequired, [Parameter(Mandatory=$false)] - [string[]]$Approvers, + [string]$Approvers, [Parameter(Mandatory=$false)] [switch]$entraRole ) @@ -55,21 +55,43 @@ if ($ApprovalRequired -eq "FALSE") { $req = "false" }else { $req = "true" } if ($null -ne $Approvers) { #at least one approver required if approval is enable + $Approvers = $Approvers -replace ",$" # remove the last comma + # turn approvers list to an array + $Approvers= $Approvers -replace "^","@(" + $Approvers= $Approvers -replace "$",")" + write-verbose "APPROVERS: $Approvers" + #then turn the sting into an array of hash table - $Approvers = $Approvers -replace "@" - $Approvers = $Approvers -replace ";", "," - $Approvers = $Approvers -replace "=", ":" + $Appr = Invoke-Expression $Approvers $rule += ' "primaryApprovers": [ - '+ $Approvers + ' + $cpt = 0 + $Appr| ForEach-Object { + + $id = $_.id + $name = $_.description + $type = $_.userType + write-host "ID => $($_.id)" + + if ($cpt -gt 0) { + $rule += "," + } + $rule += ' + { + "id": "'+ $id + '", + "description": "'+ $name + '", + "isBackup": false, + "userType": "'+ $type + '" + } + ' + $cpt++ + } } $rule += ' - ],' - - - $rule += ' + ], "isEscalationEnabled": false, "escalationApprovers": null }] diff --git a/EasyPIM/internal/functions/Set-Notification_ActiveAssignment_Alert.ps1 b/EasyPIM/internal/functions/Set-Notification_ActiveAssignment_Alert.ps1 index 4c4d574..18c8bb1 100644 --- a/EasyPIM/internal/functions/Set-Notification_ActiveAssignment_Alert.ps1 +++ b/EasyPIM/internal/functions/Set-Notification_ActiveAssignment_Alert.ps1 @@ -17,6 +17,7 @@ set the notification sent to admin when active assignment is created #> function Set-Notification_ActiveAssignment_Alert($Notification_ActiveAssignment_Alert, [switch]$EntraRole) { $rule = ' + { "notificationType": "Email", "recipientType": "Admin", "isDefaultRecipientsEnabled": '+ $Notification_ActiveAssignment_Alert.isDefaultRecipientEnabled.ToLower() + ', @@ -26,7 +27,7 @@ function Set-Notification_ActiveAssignment_Alert($Notification_ActiveAssignment_ $Notification_ActiveAssignment_Alert.Recipients | ForEach-Object { $rule += '"' + $_ + '",' } - + $rule = $rule -replace ",$" # remove the last comma $rule += ' ], "id": "Notification_Admin_Admin_Assignment", diff --git a/EasyPIM/internal/functions/Update-Policy.ps1 b/EasyPIM/internal/functions/Update-Policy.ps1 index 9dae135..0a108c2 100644 --- a/EasyPIM/internal/functions/Update-Policy.ps1 +++ b/EasyPIM/internal/functions/Update-Policy.ps1 @@ -23,7 +23,7 @@ function Update-Policy { ) Log "Updating Policy $policyID" -noEcho #write-verbose "rules: $rules" - #$scope = "subscriptions/$script:subscriptionID" + $scope = $script:scope $ARMhost = "https://management.azure.com" #$ARMendpoint = "$ARMhost/$scope/providers/Microsoft.Authorization" From 340b2e3fbd727d2db9a2cb1e6e97be79179b3d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Mon, 18 Mar 2024 20:09:00 +0100 Subject: [PATCH 4/6] fix #28 for entra role --- EasyPIM/internal/functions/Import-EntraRoleSettings.ps1 | 6 +++--- EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/EasyPIM/internal/functions/Import-EntraRoleSettings.ps1 b/EasyPIM/internal/functions/Import-EntraRoleSettings.ps1 index c39f994..da13f18 100644 --- a/EasyPIM/internal/functions/Import-EntraRoleSettings.ps1 +++ b/EasyPIM/internal/functions/Import-EntraRoleSettings.ps1 @@ -38,10 +38,10 @@ function Import-EntraRoleSettings { $enablementRules = $_.EnablementRules.Split(',') $rules += Set-ActivationRequirement $enablementRules -entraRole - $approvers = @() - $approvers += $_.approvers + # $approvers = @() + # $approvers += $_.approvers - $rules += Set-ApprovalFromCSV $_.ApprovalRequired $Approvers -entraRole + $rules += Set-ApprovalFromCSV $_.ApprovalRequired $_.Approvers -entraRole $rules += Set-EligibilityAssignmentFromCSV $_.MaximumEligibleAssignmentDuration $_.AllowPermanentEligibleAssignment -entraRole diff --git a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 index 71d8c9e..68bd8ad 100644 --- a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 +++ b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 @@ -147,7 +147,7 @@ if ($ApprovalRequired -eq "FALSE") { $req = "false" }else { $req = "true" } # write-verbose "approvers: $approvers" $Approvers = $Approvers -replace ",$" # remove the last comma #then turn the sting into an array of hash table - $list = Invoke-Expression $($c.Approvers -replace ",$") + $list = Invoke-Expression $Approvers $list | ForEach-Object { $id = $_.id $name = $_.description From 0d51d382e5dba6c048e7aa55120213e9587fdd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Mon, 18 Mar 2024 20:11:39 +0100 Subject: [PATCH 5/6] V1.5.1 --- EasyPIM/EasyPIM.psd1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EasyPIM/EasyPIM.psd1 b/EasyPIM/EasyPIM.psd1 index f1475db..7ded81a 100644 --- a/EasyPIM/EasyPIM.psd1 +++ b/EasyPIM/EasyPIM.psd1 @@ -4,7 +4,7 @@ RootModule = 'EasyPIM.psm1' # Version number of this module. -ModuleVersion = '1.5.0' +ModuleVersion = '1.5.1' # Supported PSEditions # CompatiblePSEditions = @() @@ -120,7 +120,7 @@ PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. - Tags = @("Azure","PIM","Entra-ID") + Tags = @("Azure","PIM","EntraID") # A URL to the license for this module. LicenseUri = 'https://github.com/kayasax/EasyPIM/blob/main/LICENSE' @@ -148,7 +148,7 @@ PrivateData = @{ } # End of PrivateData hashtable # HelpInfo URI of this module -# HelpInfoURI = '' +HelpInfoURI = 'https://github.com/kayasax/EasyPIM/wiki/Documentation' # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' From c429e06d279c55dde1288b7b7b1d97cb04baf60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Mon, 18 Mar 2024 21:11:24 +0100 Subject: [PATCH 6/6] remove pests --- EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 | 4 ++-- EasyPIM/internal/functions/Import-Settings.ps1 | 2 +- EasyPIM/internal/functions/Set-Approval.ps1 | 4 ++-- EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 | 5 ++--- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 b/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 index 783a3e4..4fe52e0 100644 --- a/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 +++ b/EasyPIM/functions/Get-PIMGroupActiveAssignment.ps1 @@ -7,14 +7,14 @@ EntraID tenant ID .PARAMETER groupID The group id to check - .PARAMETER memberType + .PARAMETER memberType Filter results by memberType (owner or member) .PARAMETER principalName Filter results by principalName starting with the given value .Parameter summary When enabled will return the most useful information only .Example - PS> Get-PIMGroupActiveAssignment -tenantID $tid -groupID $gID + PS> Get-PIMGroupActiveAssignment -tenantID $tid -groupID $gID List active assignement for the group $gID .Example diff --git a/EasyPIM/internal/functions/Import-Settings.ps1 b/EasyPIM/internal/functions/Import-Settings.ps1 index f422b0d..7d8b17e 100644 --- a/EasyPIM/internal/functions/Import-Settings.ps1 +++ b/EasyPIM/internal/functions/Import-Settings.ps1 @@ -97,7 +97,7 @@ function Import-Setting ($path) { "Recipients" = $_.Notification_Activation_Approver_Recipients.split(',') } $rules += Set-Notification_Activation_Approver $Notification_Activation_Approver - #> + #> # patch the policy Update-Policy $_.policyID $($rules -join ',') } diff --git a/EasyPIM/internal/functions/Set-Approval.ps1 b/EasyPIM/internal/functions/Set-Approval.ps1 index d47f490..f4b0efd 100644 --- a/EasyPIM/internal/functions/Set-Approval.ps1 +++ b/EasyPIM/internal/functions/Set-Approval.ps1 @@ -40,7 +40,7 @@ function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { ], "escalationApprovers":[] }]}}]} - #> + #> $rule = '{ "id":"Approval_EndUser_Assignment", @@ -93,7 +93,7 @@ function Set-Approval ($ApprovalRequired, $Approvers, [switch]$entraRole) { "escalationApprovers":[] }] } -}' +}' <# $rule = ' diff --git a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 index 68bd8ad..7b3141d 100644 --- a/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 +++ b/EasyPIM/internal/functions/Set-ApprovalFromCSV.ps1 @@ -59,10 +59,10 @@ if ($ApprovalRequired -eq "FALSE") { $req = "false" }else { $req = "true" } # turn approvers list to an array $Approvers= $Approvers -replace "^","@(" $Approvers= $Approvers -replace "$",")" - write-verbose "APPROVERS: $Approvers" + #write-verbose "APPROVERS: $Approvers" #then turn the sting into an array of hash table - $Appr = Invoke-Expression $Approvers + $Appr = Invoke-Expression $Approvers $rule += ' "primaryApprovers": [ @@ -73,7 +73,6 @@ if ($ApprovalRequired -eq "FALSE") { $req = "false" }else { $req = "true" } $id = $_.id $name = $_.description $type = $_.userType - write-host "ID => $($_.id)" if ($cpt -gt 0) { $rule += ","