Private/RoleManagement/Azure/Invoke-AzureResourceRoleActivation.ps1
|
function Invoke-AzureResourceRoleActivation { <# .SYNOPSIS Activates Azure Resource PIM roles using Azure REST API. .PARAMETER Scope The Azure resource scope (subscription, resource group, or resource). .PARAMETER RoleDefinitionId The role definition ID to activate. .PARAMETER PrincipalId The principal ID (user object ID) requesting activation. .PARAMETER RequestType The request type (typically 'SelfActivate'). .PARAMETER Justification Justification text for the activation. .PARAMETER ScheduleInfo Schedule information including start time and expiration. .PARAMETER TicketInfo Optional ticket information if required by policy. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Scope, [Parameter(Mandatory)] [string]$RoleDefinitionId, [Parameter(Mandatory)] [string]$PrincipalId, [Parameter(Mandatory)] [string]$RequestType, [Parameter(Mandatory)] [string]$Justification, [Parameter(Mandatory)] [hashtable]$ScheduleInfo, [hashtable]$TicketInfo ) try { Write-Verbose "Activating Azure Resource role: $RoleDefinitionId in scope: $Scope" # Ensure we have an active Azure context $azContext = Get-AzContext if (-not $azContext) { throw "No Azure context available. Please connect to Azure first using Connect-AzAccount." } Write-Verbose "Using Azure context: $($azContext.Account.Id) in tenant $($azContext.Tenant.Id)" Write-Verbose "Using Az.Resources module for Azure Resource role activation" # Generate a unique name for the request $requestName = [System.Guid]::NewGuid().ToString() # Ensure the role definition ID is in the correct format (full ARM resource ID) $fullRoleDefinitionId = if ($RoleDefinitionId.StartsWith('/')) { $RoleDefinitionId # Already a full resource ID } else { "$Scope/providers/Microsoft.Authorization/roleDefinitions/$RoleDefinitionId" } # According to Microsoft docs, the correct parameters for New-AzRoleAssignmentScheduleRequest are: $activationParams = @{ Name = $requestName Scope = $Scope RoleDefinitionId = $fullRoleDefinitionId PrincipalId = $PrincipalId RequestType = $RequestType Justification = $Justification } # Add expiration duration using the correct parameter name if ($ScheduleInfo.Expiration -and $ScheduleInfo.Expiration.Duration) { $activationParams.ExpirationDuration = $ScheduleInfo.Expiration.Duration } # Add expiration type if ($ScheduleInfo.Expiration -and $ScheduleInfo.Expiration.Type) { $activationParams.ExpirationType = $ScheduleInfo.Expiration.Type } # Add ticket information if provided using correct parameter names if ($TicketInfo -and $TicketInfo.TicketNumber) { $activationParams.TicketNumber = $TicketInfo.TicketNumber if ($TicketInfo.TicketSystem) { $activationParams.TicketSystem = $TicketInfo.TicketSystem } } Write-Verbose "Submitting Azure Resource role activation using New-AzRoleAssignmentScheduleRequest" Write-Verbose "Parameters: Name=$requestName, Scope=$Scope, RoleDefinitionId=$RoleDefinitionId, PrincipalId=$PrincipalId" Write-Verbose "RequestType=$RequestType, ExpirationDuration=$($ScheduleInfo.Expiration.Duration)" # Use the Az.Resources cmdlet to activate the role $response = New-AzRoleAssignmentScheduleRequest @activationParams -ErrorAction Stop Write-Verbose "Azure Resource role activation request submitted successfully" Write-Verbose "Response ID: $($response.Id), Status: $($response.Status), Type: $($response.Type)" return $response } catch { Write-Verbose "Azure Resource role activation failed: $($_.Exception.Message)" if ($_.Exception.Response) { try { $responseStream = $_.Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($responseStream) $responseBody = $reader.ReadToEnd() $reader.Close() Write-Verbose "Error response body: $responseBody" } catch { Write-Verbose "Could not read error response body" } } throw "Failed to activate Azure Resource role: $($_.Exception.Message)" } } |