Remove Azure Privileged Identity Management Assignments using PowerShell and Azure Resource Manager
Problem Statement
In the recent past, there was a bug in the AzureRM Terraform Provider making it hard to manage Privileged Identity Management Assignments persistently. The bug is tracked as an Issue on GitHub and marked as solved using the latest provider (3.85.0). Unfortunately, testing has shown that all assignments need to be removed manually once to fix the issue.
We decided to use PowerShell Azure Resource Manager SDK for that job building a wrapper around Invoke-AzRestMethod (Az.Accounts) | Microsoft Learn.
NOTE: Idealy, Privileged Identity Management Assignments should be managed using Microsoft Graph API. Unfortunately, this requires elevated permissions on Entra ID to setup the delegated permissions for the App Registration.
Source Code
The source code is available from github.
It runs both in Cloud Shell and locally, but you need to login to Azure first when running it locally and download the Az modules.
Query PIM Assignments
To get a complete list of Privileged Identity Management Assignments on Subscription Level, just run Get-AzPimAssignments.ps1
.
This script will iterate across all subscriptions that you have access to and fetch PIM Assignments. All assignments found will be stored in a CSV file in the script root folder with following structure:
Subscription Name | Subscription ID | RoleDefinitionName | PrincipalName | Principal ID | Role Definition ID | Resource ID |
---|---|---|---|---|---|---|
Remove PIM Assignments
Existing Assignments can be removed running Remove-APimAssignment.ps1
.
Running successfully, the script will not return anything.
Parameters and Execution
Data Generation
- Download both script files from the gist.
- Connect to Azure (or provide Client ID, Client Secret and Tenant ID as parameter).
- Run the first script to generate a data file containin all PIM assignments either without parameter or specifying a service connection.
- Import the data from CSV:
$assignmentArr = Import-Csv -FilePath <your result file>
.
Remove PIM Assignments
- Importing the function from the second script file into your session:
. .\Remove-AzPimAssignment.ps1
- Run the removal scripts with individual assignments providing RoleDefinitionId, Scope and PrincipalId as parameters:
Remove-AzPimAssignment -PrincipalId <desired principal id> -RoleDefinitionId <desired role definition> -Scope <desired subscription id>
- Verify the removed eligible role using Azure Portal
Note: After importing the data file generated in the first step, multiple assignments can be removed using the pipeline:
$assignmentArr | Where-Object {$_.SubscriptionName -match "<filterString>"} | ForEach-Object {Remove-AzPimAssignment -PrincipalId $_.PrincipalId -Scope $_.SubscriptionId -RoleDefinitionId $_.RoleDefinitionId}
Annotations
- The resource used to query existing assignments is Microsoft.Authorization/roleEligibilitySchedule As this resource type does not support removal, for deletion, another object gets created when running the removal.
- The resource type used for removal is Microsoft.Authorization/roleEligibilityScheduleRequests To execute the removal, the request type is hardcoded in the script as AdminRemove. As we are technically creating another object, that requires an identifier, the script is generating a GUID serving as resource name.
- When figuring out ARM resources, parameters and dependencies, it is always helpful to execute a workflow on the portal first and then checking both the activity log as well as your browser's developer tools.