From 1f619b5f22dafb009b6400599e2496ac8f1270ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20MICHEL?= Date: Mon, 7 Oct 2024 09:52:36 +0200 Subject: [PATCH] V1.7.1 add approval management for groups --- EasyPIM/EasyPIM.psd1 | 5 +- .../Approve-PIMGroupPendingApproval.ps1 | 71 +++++++++++++++ .../Deny-PIMGroupPendingApproval.ps1 | 71 +++++++++++++++ .../functions/Get-PIMGroupPendingApproval.ps1 | 88 +++++++++++++++++++ 4 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 EasyPIM/functions/Approve-PIMGroupPendingApproval.ps1 create mode 100644 EasyPIM/functions/Deny-PIMGroupPendingApproval.ps1 create mode 100644 EasyPIM/functions/Get-PIMGroupPendingApproval.ps1 diff --git a/EasyPIM/EasyPIM.psd1 b/EasyPIM/EasyPIM.psd1 index fe6ce31..9e40dca 100644 --- a/EasyPIM/EasyPIM.psd1 +++ b/EasyPIM/EasyPIM.psd1 @@ -100,7 +100,10 @@ FunctionsToExport = @( 'Deny-PIMAzureResourcePendingApproval', 'Get-PIMEntraRolePendingApproval', 'Approve-PIMEntraRolePendingApproval', - 'Deny-PIMEntraRolePendingApproval' + 'Deny-PIMEntraRolePendingApproval', + 'Get-PIMGroupPendingApproval', + 'Approve-PIMGroupPendingApproval', + 'Deny-PIMGroupPendingApproval' ) # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. diff --git a/EasyPIM/functions/Approve-PIMGroupPendingApproval.ps1 b/EasyPIM/functions/Approve-PIMGroupPendingApproval.ps1 new file mode 100644 index 0000000..54b8806 --- /dev/null +++ b/EasyPIM/functions/Approve-PIMGroupPendingApproval.ps1 @@ -0,0 +1,71 @@ +<# +.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 + +Approve-PIMGroupPendingApprovall will use the Microsoft Graph APIs to retrieve the requests pending your approval + +.PARAMETER approvalID +approval ID from get-PIMAzureResourcePendingApproval + +.PARAMETER justification +justification for the approval + +.Example + PS> approve-PIMAzureResourcePendingApproval -approvalID $approvalID -justification "I approve this request" + + Approve a pending request + +.Link + +.Notes + Homepage: https://github.com/kayasax/easyPIM + Author: MICHEL, Loic + Changelog: + Todo: + * allow other scopes +#> +function Approve-PIMGroupPendingApproval { + [CmdletBinding()] + [OutputType([String])] + param ( + + [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, + ValueFromPipelineByPropertyName = $true)] + [System.String] + # Approval ID + $approvalID, + + [Parameter(Position = 1, Mandatory = $true)] + [System.String] + # justification + $justification + + ) + process { + try { + #$script:tenantID = $tenantID + + Write-Verbose "approve-PIMGroupPendingApproval start with parameters: approvalid => $approvalID, justification => $justification" + + #Get the stages: + #in groups stageID is the same as the approvalID + + + #approve the request + #https://learn.microsoft.com/en-us/graph/api/approvalstage-update?view=graph-rest-1.0&tabs=http + + $body = '{"justification":"' + $justification + '","reviewResult":"Approve"}' + Invoke-graph -endpoint "identityGovernance/privilegedAccess/group/assignmentApprovals/$approvalID/steps/$approvalID" -body $body -version "beta" -Method PATCH + return "Success, request approved" + + } + catch { + MyCatch $_ + } + } +} \ No newline at end of file diff --git a/EasyPIM/functions/Deny-PIMGroupPendingApproval.ps1 b/EasyPIM/functions/Deny-PIMGroupPendingApproval.ps1 new file mode 100644 index 0000000..9a5ab0d --- /dev/null +++ b/EasyPIM/functions/Deny-PIMGroupPendingApproval.ps1 @@ -0,0 +1,71 @@ +<# +.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 + +Deny-PIMGroupPendingApprovall will use the Microsoft Graph APIs to retrieve the requests pending your approval + +.PARAMETER approvalID +approval ID from get-PIMAzureResourcePendingApproval + +.PARAMETER justification +justification for the approval + +.Example + PS> Deny-PIMAzureResourcePendingApproval -approvalID $approvalID -justification "I Deny this request" + + Deny a pending request + +.Link + +.Notes + Homepage: https://github.com/kayasax/easyPIM + Author: MICHEL, Loic + Changelog: + Todo: + * allow other scopes +#> +function Deny-PIMGroupPendingApproval { + [CmdletBinding()] + [OutputType([String])] + param ( + + [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, + ValueFromPipelineByPropertyName = $true)] + [System.String] + # Approval ID + $approvalID, + + [Parameter(Position = 1, Mandatory = $true)] + [System.String] + # justification + $justification + + ) + process { + try { + #$script:tenantID = $tenantID + + Write-Verbose "Deny-PIMGroupPendingApproval start with parameters: approvalid => $approvalID, justification => $justification" + + #Get the stages: + #in groups stageID is the same as the approvalID + + + #Deny the request + #https://learn.microsoft.com/en-us/graph/api/approvalstage-update?view=graph-rest-1.0&tabs=http + + $body = '{"justification":"' + $justification + '","reviewResult":"Deny"}' + Invoke-graph -endpoint "identityGovernance/privilegedAccess/group/assignmentApprovals/$approvalID/steps/$approvalID" -body $body -version "beta" -Method PATCH + return "Success, request Denied" + + } + catch { + MyCatch $_ + } + } +} \ No newline at end of file diff --git a/EasyPIM/functions/Get-PIMGroupPendingApproval.ps1 b/EasyPIM/functions/Get-PIMGroupPendingApproval.ps1 new file mode 100644 index 0000000..20cd45d --- /dev/null +++ b/EasyPIM/functions/Get-PIMGroupPendingApproval.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-PIMGroupPendingApproval will use the Microsoft Graph APIs to retrieve the requests pending your approval + +.PARAMETER tenantID +Tenant ID + +.Example + PS> Get-PIMGroupPendingApproval -tenantID $tenantID + + show pending request you can approve + +.Link + +.Notes + Homepage: https://github.com/kayasax/easyPIM + Author: MICHEL, Loic + Changelog: + Todo: + * allow other scopes +#> +function Get-PIMGroupPendingApproval{ + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseOutputTypeCorrectly", "")] + [CmdletBinding()] + param ( + + [Parameter(Position = 0, Mandatory = $true)] + [System.String] + # Tenant ID + $tenantID + + ) + try { + $script:tenantID = $tenantID + + Write-Verbose "Get-PIMAzureResourcePendingApproval start with parameters: tenantID => $tenantID" + + $endpoint="identityGovernance/privilegedAccess/group/assignmentScheduleRequests/filterByCurrentUser(on='approver')?`$filter=status eq 'PendingApproval'" + $response = Invoke-Graph -Endpoint $endpoint -Method "GET" + + $out = @() + + $pendingApproval = $response.value + + if ($null -ne $pendingApproval) { + $pendingApproval | ForEach-Object { + $details=invoke-mgGraphRequest $("https://graph.microsoft.com/v1.0/identityGovernance/privilegedAccess/group/assignmentScheduleRequests/"+$_.id) -Method get + #$details + $principalDisplayName = invoke-mgGraphRequest $("https://graph.microsoft.com/v1.0/directoryobjects/"+$details.Principalid+"/") -Method get + $groupDisplayName = invoke-mgGraphRequest $("https://graph.microsoft.com/v1.0/directoryobjects/"+$details.Groupid+"/") -Method get + + + $request = @{ + "principalId" = $details.Principalid; + "principalDisplayname" = $principalDisplayName.displayName; + "groupId" = $details.groupId; + "groupDisplayname" = $groupDisplayName.displayName; + "role" = $details.AccessID; + "status" = $details.status; + "startDateTime" = $details.CreatedDateTime; + "ticketInfo" = $details.ticketInfo; + "justification" = $details.justification; + "approvalId" = $details.approvalId; + "createdOn" = $details.createdDateTime; + } + $o = New-Object -TypeName PSObject -Property $request + $out += $o + } + } + if ($out.length -eq 0) { + #write-host "No pending approval" + return $null + } + return $out + + } + catch { + MyCatch $_ + } + +} \ No newline at end of file