Category Archives: Microsoft Graph

Authenticate to Microsoft Graph from PowerShell Interactively


You are a developer or power user in a company with Microsoft 365 tenant.
You need to connect to Microsoft Graph and then call Microsoft Graph API to consume some MS Graph resources on behalf of authenticated user programmatically with PowerShell – e.g. add/remove documents or list items, search for sites or documents content etc. – whatever available with Graph API.

You do not have tenant admin permissions or any tenant-level admin permissions (SharePoint, Teams, Exchange etc. ). But you can register an Azure App and request tenant admin consent.


  • register an Azure App
  • under authentication blade – add platform – “Mobile and Desktop app”
    add “http://localhost” (and select …/nativeclient Url ?)
  • under API permissions blade – add delegated permissions you need
    (refer to specific API you’ll use)
  • install MSAL.PS PowerShell module
  • use the following code to get graph access token and call graph API
$AppId = ""
$TenantId = ""
$connectionDetails = @{
    'TenantId'    = $AppId
    'ClientId'    = $TenantId
    'Interactive' = $true

$token = Get-MsalToken @connectionDetails
# or 
$token = Get-MsalToken -TenantId $TenantId -ClientId $appId -Interactive 

$Headers = @{
    'Authorization' = "bearer $($token.AccessToken)"

Invoke-RestMethod -Uri '' -Headers $Headers

You can find the code sample here:

Did not work:

Az PowerShell module did not work for me:

Connect-AzAccount -Tenant ""
$azAccessToken = Get-AzAccessToken -Resource "" 

$Headers = @{
  'Authorization' = "$($azAccessToken.Type) $($azAccessToken.Token)"

Invoke-RestMethod -Uri '' -Headers $Headers

As I understand we need somehow let Azure know API permissions we want (e.g. via app registerd)…

PnP did not work for me too:

$url = ""
Connect-PnPOnline -ClientId "" -Url $url -Interactive 
$pnpToken = Get-PnPGraphAccessToken 
$Headers = @{
    'Authorization' = "bearer $($pnpToken)"
Invoke-RestMethod -Uri '' -Headers $Headers

# did not work as well:
$pnpToken = Get-PnPAppAuthAccessToken
$pnpToken = Get-PnPAccessToken 

the error message was (maybe I missed something – please let me know):

“code”: “InvalidAuthenticationToken”, “message”: “Access token validation failure. Invalid audience.”


Connect-PnPOnline with a certificate stored in Azure Key Vault


You run some PnP PowerShell code unattended e.g. daemon/service app, background job – under application permissions – with no user interaction.
Your app needs to connect to SharePoint and/or Microsoft Graph API. Your organization require authentication with a certificate (no secrets). You want certificate stored securely in Azure Key Vault.

Solution (Step-by-step process)

  1. Obtain a certificate (create a self-signed or request trusted)
  2. In Azure where you have Microsoft 365 SharePoint tenant
    1. Create a new Registered App in Azure; save App (client) id, Directory (Tenant) Id
    2. Configure App: add MS Graph and SharePoint API application (not delegated) permissions
    3. Upload the certificate to the app under “Certificates & secrets”
  3. In Azure where you have paid subscription (could be same or different)
    1. Create an Azure Key Vault
    2. Upload certificate to the Key Vault manually (with GUI)
  4. While you develop/debug your custom daemon application at your local machine
    1. Provide permissions to the Key Vault via Access Control and Access Policies to your personal account
    2. Connect to Azure (the one where your Key Vault is) running Connect-AzAccount
      – so your app can get a Certificate to authenticate to SharePoint Online
  5. For your application deployed to Azure (e.g. Azure Function App )
    1. Turn On managed identity (Your Function App -> Identity -> Status:On) and Save; notice an Object (Principal) Id just created
    2. Provide for your managed identity principal Id permissions to the Key Vault via Key Vault Access Policies, so when your daemon app is running in the cloud – it could go to the key Vault and retrieve Certificate

Here is the sample PowerShell code to get certificate from Azure Key Vault and Connect to SharePoint with PnP (Connect-PnPOnline):

# ensure you use PowerShell 7

# connect to your Azure subscription
Connect-AzAccount -Subscription "<subscription id>" -Tenant "<tenant id>"
Get-AzSubscription | fl

# Specify Key Vault Name and Certificate Name
$VaultName = "<azure key vault name>"
$certName = "certificate name as it stored in key vault"

# Get certificate stored in KeyVault (Yes, get it as SECRET)
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certName
$secretValueText = ($secret.SecretValue | ConvertFrom-SecureString -AsPlainText )

# connect to PnP
$tenant = "" # or tenant Id
$siteUrl = ""
$clientID = "<App (client) Id>" # Azure Registered App with the same certificate and API permissions configured
Connect-PnPOnline -Url $siteUrl -ClientId $clientID -Tenant $tenant -CertificateBase64Encoded $secretValueText


The same PowerShell code in GitHub: Connect-PnPOnline-with-certificate.ps1