Delete Azure RBAC role assignments for Unknown principals
If you’ve been managing Azure and Entra for more than 5 minutes, you’ve probably come across this issue before:
Someone has assigned a principal some permission, the principal has then subsequently been deleted or otherwise removed, and you’re left with this annoying reminder - and because the principal no longer exists, you’ve no idea who it was before!
Most of the time, you don’t usually mind about that and you just want it gone. But if multiple permissions have been granted at multiple scopes, it can be a challenge to make sure you catch them all.
Luckily, Azure Powershell is your friend here and you can quite easily:
- Find all of the offending RBAC assignments
- Delete them
We’ll want to make sure we don’t delete anything we’re not intending to, so we need to make sure there are some controls in place - I’m going to achieve that by making the default behaviour of my script not delete anything, forcing you to check the list of principals before deleting them.
Without further ado, below is a script you can use for this purpose:
[CmdletBinding()]
param (
[Parameter()]
[switch]$delete,
[Parameter()]
$subId,
[Parameter(Mandatory)]
$tenantId
)
#Connect to Azure if not already connected to the tenant
if ($($(Get-AzContext).Tenant.Id) -ne $tenantId) {
if (!$subId) {
Connect-AzAccount -Tenant $tenantId | Out-Null
}
else {
Connect-AzAccount -Tenant $tenantId -Subscription $subId | Out-Null
}
} elseif ($subId -and $($(Get-AzContext).Subscription.Id) -ne $subId) { #Change the context to the targeted subscription if sub ID is provided and doesn't match the existing context
Set-AzContext -Subscription $subId
}
#Get a list of role assignments, filtered on those where the ObjectType is 'Unknown'
$roleAssignments = Get-AzRoleAssignment | Where-Object ObjectType -eq "Unknown" | Select-Object DisplayName, ObjectId, RoleDefinitionName, Scope
#If there are role assignments in the filtered list, perform the following code
if ($roleAssignments.Count -gt 0) {
Write-Host "Once you have reviewed the below list, re-run the script with the -delete flag to delete the listed role assignments. You will be prompted again to confirm you want to proceed" -ForegroundColor DarkRed
Write-Host " "
Write-Host ($roleAssignments | Format-Table | Out-String)
#Will only fall into those section if the -delete flag has been added during script instantiation
if ($delete) {
$confirm = Read-Host "Would you like to proceed? (Y/N)"
switch ($($confirm).ToUpper()) {
"Y" {
$roleAssignments | Remove-AzRoleAssignment
}
"N" {
Write-Host "You have chosen not to proceed at this time" -ForegroundColor DarkRed
}
default {
Write-Host "You did not enter a valid choice. Please re-run the script and only type Y or N" -ForegroundColor DarkRed
}
}
}
}
else {
Write-Host "There are no RBAC assignments to delete" -ForegroundColor DarkGreen
}