A PowerShell module for making day-to-day Managed Identity operations in Azure a little easier.
The Managed Identity Automation Utilities brings together Azure Resource Graph, Azure RBAC, and Microsoft Graph application permissions into a set of PowerShell commands that are designed to work naturally with the pipeline.
Whether you're looking for managed identities across a tenant, checking their permissions, or bringing those permissions back to a desired state, the goal is to make common identity operations simple, scriptable, and repeatable.
Note: This README reflects the functionality currently implemented in the codebase.
With the current version you can:
- Build a tenant-wide inventory of resources that use managed identities, including system-assigned and user-assigned identities.
- Find and filter identities by name, resource group, and identity type.
- Read Microsoft Graph application permissions assigned to managed identities.
- Grant and revoke Microsoft Graph application permissions.
- Reconcile Graph application permissions to a desired state.
- Read, grant, and revoke Azure RBAC role assignments.
- Combine commands in pipeline-friendly workflows.
The idea is to keep things familiar for PowerShell users:
Get-MIIdentity -Name func |
Get-MIPermissionor:
Get-MIIdentity -Name func-api-prod |
Set-MIPermission -Type FunctionApp -Permission @(
'User.Read.All'
'Group.Read.All'
)Managed Identity Automation Utilities is still growing, and there are a few areas that aren't implemented yet.
Currently:
- There are no advanced governance or reporting features such as orphan detection, over-privilege analysis, dashboards, or exports.
- Identity creation and deletion aren't part of the module yet.
- Inventory queries currently request up to 1000 resources per execution and don't implement pagination.
- Permission commands expose a
-Typeparameter, but currently onlyFunctionAppis supported and the value doesn't yet change the underlying behavior.
These are known gaps rather than hidden limitations, and they're good candidates for future improvements.
Get-MIInventoryGet-MIIdentity
Get-MIPermissionGrant-MIPermissionSet-MIPermission— reconcile permissions by granting missing permissions and revoking unwanted ones.Revoke-MIPermission
Get-MIRoleAssignmentGrant-MIRoleAssignmentRevoke-MIRoleAssignment
These commands support the implementation but aren't intended to be the primary workflow:
Get-MIGraphPermission— retrieves available Microsoft Graph application roles.Get-MIRoleDefinitionGet-MIRoleScope
The module currently targets PowerShell 7+.
You also need the following Az modules available:
Az.AccountsAz.ResourcesAz.ResourceGraph
Start by connecting to Azure:
Connect-AzAccountYour account also needs sufficient permissions to read and modify the relevant Azure RBAC and Microsoft Graph application role assignments.
From the repository root:
Import-Module ./src/MIAU.psm1 -ForceStart with an inventory of identities across your environment:
Get-MIInventoryYou can filter the inventory using the identity and resource properties:
Get-MIIdentity -Name func
Get-MIIdentity -ResourceGroupName rg-apps-prod
Get-MIIdentity -SystemAssigned
Get-MIIdentity -UserAssignedBecause the commands are pipeline-friendly, you can go directly from identities to their permissions:
Get-MIIdentity -Name func |
Get-MIPermissionFor example:
$grantMIPermissionSplat = @{
Type = 'FunctionApp'
Permission = 'User.Read.All'
}
Get-MIIdentity -Name func-api-prod |
Grant-MIPermission @grantMIPermissionSplatSet-MIPermission is intended for declarative-style workflows.
Give it the permissions you want, and it will grant missing permissions and revoke permissions that aren't part of the desired state:
$setMIPermissionSplat = @{
Type = 'FunctionApp'
Permission = @(
'User.Read.All'
'Group.Read.All'
)
}
Get-MIIdentity -Name func-api-prod |
Set-MIPermission @setMIPermissionSplatThis also works naturally with multiple identities:
$setMIPermissionSplat = @{
Type = 'FunctionApp'
Permission = @(
'User.Read.All'
'Group.Read.All'
)
}
Get-MIIdentity -Name func |
Set-MIPermission @setMIPermissionSplatRead existing assignments:
Get-MIIdentity -Name func-api-prod |
Get-MIRoleAssignmentGrant a role:
$grantMIRoleAssignmentSplat = @{
RoleDefinitionName = 'Reader'
Scope = '/subscriptions/<subId>'
}
Get-MIIdentity -Name func-api-prod |
Grant-MIRoleAssignment @grantMIRoleAssignmentSplatRevoke a role:
$revokeMIRoleAssignmentSplat = @{
RoleDefinitionName = 'Reader'
Scope = '/subscriptions/<subId>'
}
Get-MIIdentity -Name func-api-prod |
Revoke-MIRoleAssignment @revokeMIRoleAssignmentSplatIdentity commands return a custom PowerShell object with:
PSTypeName = MI.Identity
The object contains the information needed to continue working with the identity through the pipeline.
NameIdentityTypePrincipalIdTenantId
ResourceNameResourceTypeResourceIdResourceKindResourceGroupName
SubscriptionIdSubscriptionNameLocation
Resource tags are normalized into simple name/value objects, making them easier to consume from PowerShell:
Name Value
---- -----
AZFun Second
Environment Production
Commands that modify permissions and role assignments support PowerShell's standard safety features:
-WhatIf
-ConfirmSo before making changes, you can preview what would happen:
$setMIPermissionSplat = @{
Type = 'FunctionApp'
Permission = 'User.Read.All'
WhatIf = $true
}
Get-MIIdentity -Name func |
Set-MIPermission @setMIPermissionSplatThis is particularly useful when working against multiple identities through the pipeline.
There are plenty of directions this project can take.
Some of the obvious next steps include:
- Implementing
Get-MIOverview. - Improving inventory scalability with paging.
- Adding richer governance and reporting capabilities.
- Detecting orphaned or potentially over-privileged identities.
- Adding automated tests and command help.
- Adding an explicit module manifest and dependency declarations.
- Cleaning up command/file naming inconsistencies.
The intention is to grow Managed Identity Automation Utilities incrementally while keeping the commands useful for real-world PowerShell automation.
Issues and pull requests are welcome.
When reporting an issue, it helps to include:
- Expected behavior
- Actual behavior
- Reproduction command(s)
- Redacted sample output, where possible
The more context you can provide, the easier it is to reproduce and fix an issue.
This is an independent project and is not affiliated with or endorsed by Microsoft. This README and parts of the source code were created with the help of AI.