assign microsoft graph permissions to a managed identity with powershell

Assign Microsoft Graph permissions to a Managed Identity with PowerShell

6/19/2026

Assign Microsoft Graph permissions to a Managed Identity with PowerShell

There is still no normal Entra portal flow for granting Microsoft Graph application permissions to a managed identity. If you need this, PowerShell is the practical path, and that is exactly why this pattern matters for engineers building Microsoft Copilot and AI agents, Azure automation, or backend jobs that authenticate without secrets.

The source walkthrough is good and short. The important bit is not the loop itself; it is the security implication. The moment you grant Graph app roles to a managed identity, you have created a non-human principal with tenant-wide API reach. That can be the right design, but only if you are deliberate about scope. An agent should not get a blank check to your tenant.

What are you actually assigning?

You are assigning application permissions by creating app role assignments on the managed identity's service principal. Microsoft documents New-MgServicePrincipalAppRoleAssignment as the cmdlet for this, and it requires the three IDs you would expect:

  • the client service principal ID, here the managed identity
  • the resource service principal ID, here usually Microsoft Graph
  • the app role ID for the permission being granted

The source uses the Microsoft Graph enterprise app ID 00000003-0000-0000-c000-000000000000, which is the right anchor when the target API is Graph.

The practical way to do it

I would tighten the original approach slightly: filter only application-capable roles, fail if the managed identity name is ambiguous, and use the body parameter form that Microsoft shows in its own examples.

Connect-MgGraph -Scopes "Application.Read.All","AppRoleAssignment.ReadWrite.All"

$ManagedIdentityName = "My Managed Identity"
$Permissions = @(
    "User.Read.All",
    "GroupMember.Read.All"
)

$GraphSp = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
$ManagedIdentity = Get-MgServicePrincipal -Filter "DisplayName eq '$ManagedIdentityName'"

if (-not $ManagedIdentity) {
    throw "Managed identity '$ManagedIdentityName' not found."
}

if (@($ManagedIdentity).Count -gt 1) {
    throw "More than one service principal matched '$ManagedIdentityName'. Use the object ID instead of display name."
}

$AppRolesToAssign = $GraphSp.AppRoles | Where-Object {
    $_.Value -in $Permissions -and $_.AllowedMemberTypes -contains "Application"
}

foreach ($AppRole in $AppRolesToAssign) {
    $Body = @{
        principalId = $ManagedIdentity.Id
        resourceId  = $GraphSp.Id
        appRoleId   = $AppRole.Id
    }

    New-MgServicePrincipalAppRoleAssignment `
        -ServicePrincipalId $ManagedIdentity.Id `
        -BodyParameter $Body
}

That is the core pattern. It fits well in controlled AI workflow automation pipelines where identity setup is part of deployment, not a one-off portal click.

What I would watch before you run it

First, the required Graph scopes are powerful enough that you should use them only for the setup session. The source calls out Application.Read.All and AppRoleAssignment.ReadWrite.All, and Microsoft’s cmdlet documentation lists those as valid delegated permissions. Good. Use them, do the change, disconnect.

Second, stop using display names in long-lived automation if you can avoid it. Display names collide. For most orgs this is a minor admin nuisance; for larger tenants it becomes a real governance problem. Resolve the service principal once, record the object ID, and treat identity assignment like code.

Third, only grant the exact Graph app roles you need. Community discussions around this pattern all point to the same gap: because there is no friendly admin UX for managed identities here, people tend to overcompensate with broad permissions. That is how a harmless automation account turns into a tenant-wide data reader. If you are not sure what an identity already has, this is a good place for an AI and automation audit.

Verdict

This is the right approach, and the source is directionally correct. My only criticism is the usual one with identity scripts: the easy version is also the risky version. Use PowerShell, but make it deterministic, least-privilege, and reviewable. If you are granting Graph to managed identities by hand in production, you are one silent permission creep away from a mess.

Microsoft GraphPowerShellManaged IdentityMicrosoft Entra

Keep reading