Microsoft Graph PowerShell authentication

Last reviewed 2026-07-18 by the Just Software engineering team · print-friendly

All methods use the Microsoft.Graph PowerShell SDK (Install-Module Microsoft.Graph). Check what you're connected as with Get-MgContext; end the session with Disconnect-MgGraph.

When to use what

Method Identity type Permissions used Secrets to manage Typical use
Interactive (browser) Delegated (you) Delegated scopes, limited by your role None Ad-hoc admin work at the console
Device code Delegated (you) Delegated scopes None Headless/remote sessions, no local browser
Client secret Application Application permissions (admin-consented) Secret string — expires, can leak Scripts/services where certificates aren't feasible yet
Certificate Application Application permissions (admin-consented) Certificate + private key Unattended automation on servers, scheduled tasks
Managed identity Application Application permissions (granted via Graph) None Anything running in Azure: Automation, Functions, VMs

Rule of thumb: interactive for humans, managed identity for anything hosted in Azure, certificate for unattended automation outside Azure, client secret only when the platform can't hold a certificate. Device code is interactive auth for terminals that can't pop a browser.

1. Delegated interactive

Connect-MgGraph -Scopes "User.Read.All","Group.ReadWrite.All"

Opens a browser sign-in. You get the intersection of the requested scopes and what your account/role is allowed. Request only the scopes the task needs — they're cached in the token for the session.

2. Device code

Connect-MgGraph -Scopes "User.Read.All" -UseDeviceCode

Prints a code and https://microsoft.com/devicelogin URL; complete sign-in on any other device. Same delegated permissions as interactive.

3. Client secret (app registration)

Requires an app registration with application permissions granted and admin-consented.

$clientId     = "00000000-0000-0000-0000-000000000000"
$tenantId     = "contoso.onmicrosoft.com"
$clientSecret = ConvertTo-SecureString "<secret-value>" -AsPlainText -Force
$credential   = New-Object System.Management.Automation.PSCredential ($clientId, $clientSecret)

Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential

Never hardcode the secret — pull it from Key Vault or an environment variable at runtime. Secrets expire (max 2 years); track the rotation date.

4. Certificate-based (app registration)

Upload the certificate's public key to the app registration, keep the private key in the machine's certificate store.

# By thumbprint (cert in CurrentUser\My or LocalMachine\My)
Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint "A1B2C3D4E5F6..."

# Or by subject name
Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateSubjectName "CN=graph-automation"

Create a self-signed certificate for this purpose with:

New-SelfSignedCertificate -Subject "CN=graph-automation" -CertStoreLocation "Cert:\CurrentUser\My" `
  -KeyExportPolicy NonExportable -KeySpec Signature -KeyLength 2048

Preferred over client secrets: the private key never appears in code or config, and it can be made non-exportable.

5. Managed identity (Azure-hosted only)

# System-assigned managed identity
Connect-MgGraph -Identity

# User-assigned managed identity
Connect-MgGraph -Identity -ClientId "<client-id-of-the-user-assigned-identity>"

Works inside Azure Automation, Functions, App Service, VMs and anywhere else a managed identity is available. No credential exists to rotate or leak. Graph application permissions must be assigned to the identity's service principal first — there is no portal UI for this; grant the app role via Graph itself (for example New-MgServicePrincipalAppRoleAssignment).

Handy follow-ups

Get-MgContext                                  # who am I, which scopes, which auth type
Find-MgGraphCommand -Command Get-MgUser        # which permissions does a cmdlet need
Find-MgGraphPermission user.read               # search permission names
Disconnect-MgGraph
An unhandled error has occurred. Reload 🗙