Post

Testing Microsoft Graph Locally with App Permissions

Debugging is not always difficult because the code itself is complicated. Often, it is difficult because behavior outside the application is hard to reproduce realistically. That was exactly my situation when I wanted to test Microsoft Graph calls for an Azure Function.

It was important to me not to send the requests in some arbitrary way, but with the exact tokens and permissions that my function would use later. In other words: with an app registration, a certificate, and the same authentication flow as in the production scenario.

That led to a small PowerShell script that reproduces exactly this path: it authenticates with a certificate, acquires an access token for Microsoft Graph, executes the desired Graph call, and saves the response directly as a JSON file.

This was extremely helpful for debugging. Instead of only reading logs from the function, I could pinpoint very precisely where a problem actually occurred: during authentication, in the application permissions, or only in the actual Graph request.

The JSON output is especially useful. The response can be inspected, compared, and documented cleanly. That makes troubleshooting much easier to follow than a test that runs only inside the function itself.

At its core, the approach is intentionally simple. The token request looks like this:

1
2
3
4
5
6
7
$body = @{
    client_id             = $ClientId
    scope                 = "https://graph.microsoft.com/.default"
    grant_type            = "client_credentials"
    client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
    client_assertion      = $clientAssertion
}

The Graph call itself also stays intentionally lean:

1
2
3
4
$graphResponse = Invoke-RestMethod `
    -Method Get `
    -Uri $GraphUri `
    -Headers @{ Authorization = "Bearer $AccessToken" }

For me, the script is primarily a pragmatic tool from everyday work. No large framework, no complicated test setup - just a direct way to test Graph access under realistic conditions and capture results in a reproducible way.

The full script can be found in this GitHub Gist.

This post is licensed under CC BY 4.0 by the author.