Do you also get frustrated when you need to activate your PIM role through the Entra Admin Portal? Especially when you need to activate more roles for you work?
I’ve created a little Graph PowerShell function which puts all your Eligible roles in a menu so you can select which role to activate.
Prerequisites
I use a Enterprise Graph Application with specific permissions (least privileged). You need the following delegated permissions.
Permission | Bron |
RoleEligibitySchedule.Read.Directory | Get-MgRoleManagementDirectoryRoleEligibilitySchedule (Microsoft.Graph.Identity.Governance) | Microsoft Learn |
EntitlementManagement.ReadWrite.All | New-MgRoleManagementDirectoryRoleAssignment (Microsoft.Graph.Identity.Governance) | Microsoft Learn |
function Activate-PIMRole {
[CmdletBinding(SupportsShouldProcess)]
# https://worktogether.tech/2023/01/07/enable-pim-role-thru-microsoft-graph-powershell/
Write-Host "Activate one of your PIM roles"
# Check if there is a existing connection to MgGraph
if ((Get-MgContext) -eq $null) {
$null = Connect-MGGraph -TenantId '<tenantId>' -ClientId '<clientId of your Graph application>' # Use $null to capture unwanted output
}
Install-Module -Name 'Microsoft.Graph.Identity.Governance' -RequiredVersion 2.19.0 -Scope AllUsers
$context = Get-MgContext
$currentUser = Get-MgUser -UserId $context.Account
$currentUserId = $currentUser.Id
$currentUserUPN = $currentUser.UserPrincipalName
# Get all available roles
# https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.governance/get-mgrolemanagementdirectoryroleeligibilityschedule?view=graph-powershell-1.0
$myRoles = Get-MgRoleManagementDirectoryRoleEligibilitySchedule -ExpandProperty RoleDefinition -All -Filter "principalId eq '$currentuserId'"
Write-Host "Your available roles are:"
Write-Host ''
$menu = @{}
for ($i=0; $i -lt $myRoles.count; $i++) {
Write-Host "$i. $($myRoles[$i].RoleDefinition.DisplayName)"
$menu.Add($i,($myRoles[$i].RoleDefinition.DisplayName))
}
[int]$selectedRole = Read-Host "Enter number of role to activate"
Write-Host ''
# Setup parameters for activation
$params = @{
Action = "selfActivate"
PrincipalId = $myRoles[$selectedRole].PrincipalId
RoleDefinitionId = $myRoles[$selectedRole].RoleDefinitionId
DirectoryScopeId = $myRoles[$selectedRole].DirectoryScopeId
Justification = "Enable role for [$currentUserUPN] with script"
ScheduleInfo = @{
StartDateTime = Get-Date
Expiration = @{
Type = "AfterDuration"
Duration = "PT4H"
}
}
TicketInfo = @{
TicketNumber = 'CHA111111'
TicketSystem = 'ServiceManager'
}
}
# Activate the role
Write-Host "Activate role [$($myRoles[$selectedRole].RoleDefinition.DisplayName)]"
try {
$null = New-MgRoleManagementDirectoryRoleAssignmentScheduleRequest -BodyParameter $params
}
catch {
Write-Host "...something went wrong with [New-MgRoleManagementDirectoryRoleAssignmentScheduleRequest - Activate]"
Write-Host "`tERROR : $($_.Exception.message)"
}
Write-Host "...done"
Write-Host ''
# Wait until Role Assignment is activated
}
I also like to add code to check if role is really activated. You can add below to the end of the function:
# Wait until Role Assignment is activated
Write-Host "...wait until Role Assignment [$($myRoles[$selectedRole].RoleDefinition.DisplayName)] is activated"
do {
Write-Host "...wait"
Start-Sleep -Seconds 5
} while ((((Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($myRoles[$selectedRole].RoleDefinitionId)'").PrincipalId) -eq $currentUserId) -eq $false)
Write-Host "...done"
Write-Host ''
And just call the function with this cmdlet:
Activate-PIMRole