Route a PowerShell script through GraphWarden
A PowerShell script using Microsoft.Graph cmdlets connects to GraphWarden by passing a custom access token and a Graph endpoint override. After Connect-MgGraph, every cmdlet you already use (Get-MgUser, New-MgGroup, and the rest) works unchanged. This page shows the complete setup.
Prerequisites
Route a PowerShell script with an AI assistant
Route my PowerShell script using Connect-MgGraph through GraphWarden.
My script currently calls Connect-MgGraph with client-credential auth against https://graph.microsoft.com.
I need:
1. The tested pattern to acquire a token from the GraphWarden proxy's token endpoint
2. A Connect-MgGraph invocation that uses that token against the proxy as the Graph endpoint
3. A sanity check that Get-MgContext confirms the endpoint is the proxy
Reference documentation: https://graphwarden.com/llms.txt
Ask me for my proxy URL and proxy credentials.
Reference: llms.txt
The two overrides
A direct-to-Graph PowerShell script does two things: it calls Connect-MgGraph (which acquires a token from Azure AD) and then issues cmdlets that hit https://graph.microsoft.com. To route through GraphWarden you override both.
- Token acquisition — post your Proxy Client ID and Proxy Client Secret to
POST {proxy-host}/proxy/token(per the proxy architecture — recon #210). The response is a proxy JWT; you pass it toConnect-MgGraphas-AccessToken. - Graph endpoint —
Connect-MgGraphnormally targetshttps://graph.microsoft.com. Microsoft.Graph v2.x exposes-Environment(for the set of named clouds Microsoft ships) and honours theMICROSOFT_GRAPH_API_ENDPOINTenvironment variable for custom endpoints. Setting that variable to your proxy URL before callingConnect-MgGraphpoints every subsequent cmdlet at the proxy.
Complete script (client-credentials flow)
The script below reads three environment variables, acquires a proxy JWT, and runs a single verification call. It is copy-paste runnable once the three variables are set. Inline comments flag the GraphWarden-specific lines.
# 1. Configuration — read from the environment, never hardcode secrets.
$ProxyUrl = $env:GRAPHWARDEN_PROXY_URL # e.g. https://proxy.example.com
$ClientId = $env:GRAPHWARDEN_CLIENT_ID # Proxy Client ID from App Admin
$ClientSecret = $env:GRAPHWARDEN_CLIENT_SECRET # Proxy Client Secret from App Admin
if (-not $ProxyUrl -or -not $ClientId -or -not $ClientSecret) {
throw "Set GRAPHWARDEN_PROXY_URL, GRAPHWARDEN_CLIENT_ID, and GRAPHWARDEN_CLIENT_SECRET before running."
}
# 2. Acquire a proxy JWT via client_credentials against the proxy token endpoint.
# Authority is the proxy, NOT Azure AD. See recon #210.
$TokenResponse = Invoke-RestMethod `
-Method Post `
-Uri "$ProxyUrl/proxy/token" `
-ContentType 'application/x-www-form-urlencoded' `
-Body @{
grant_type = 'client_credentials'
client_id = $ClientId
client_secret = $ClientSecret
}
$SecureToken = ConvertTo-SecureString -String $TokenResponse.access_token -AsPlainText -Force
# 3. Point Microsoft.Graph at the proxy BEFORE Connect-MgGraph. The env var is
# read when the connection is established; setting it afterwards has no effect.
$env:MICROSOFT_GRAPH_API_ENDPOINT = $ProxyUrl
# 4. Connect using the proxy JWT. -NoWelcome suppresses the banner so scripts stay quiet.
Connect-MgGraph -AccessToken $SecureToken -NoWelcome
# 5. Verification call — standard cmdlet, now routed through GraphWarden.
Get-MgUser -Top 1 | Select-Object Id, DisplayName, UserPrincipalName
The important line is Connect-MgGraph -AccessToken $SecureToken. Everything after that is standard Microsoft.Graph — cmdlets compose request URIs against the endpoint set in MICROSOFT_GRAPH_API_ENDPOINT, so Get-MgUser issues GET {proxy-host}/v1.0/users with the proxy JWT attached.
Verifying the connection
Get-MgContext returns the current connection state. Confirm the endpoint is the proxy, not the public Graph host.
$context = Get-MgContext
Write-Host "Account: $($context.Account)"
Write-Host "AuthType: $($context.AuthType)"
Write-Host "Graph endpoint: $([Microsoft.Graph.PowerShell.Authentication.GraphSession]::Instance.GraphEndpoint)"
if ($env:MICROSOFT_GRAPH_API_ENDPOINT -and
$env:MICROSOFT_GRAPH_API_ENDPOINT -ne 'https://graph.microsoft.com') {
Write-Host "Routing through GraphWarden: $env:MICROSOFT_GRAPH_API_ENDPOINT"
} else {
Write-Warning "MICROSOFT_GRAPH_API_ENDPOINT is not set — cmdlets will hit Microsoft Graph directly."
}
The $env:MICROSOFT_GRAPH_API_ENDPOINT check is the quickest way to catch a forgotten override; the SDK property confirms what the module actually resolved at connection time.
Running your existing script
Once the connection is established every cmdlet you already use flows through the proxy. You do not rewrite your script — Get-MgUser, New-MgGroup, Set-MgUserLicense, and the other cmdlets compose the same request URIs, and the proxy enforces the ruleset bound to your App Identity on each call.
One reminder: keep the Connect-MgGraph call at the top of your script and acquire a fresh proxy JWT on each script run. Proxy JWTs expire after roughly one hour; for long-running scripts, wrap the token acquisition in a helper function that refreshes on 401.
Troubleshooting
The five failure modes below cover the common onboarding surprises when wiring a PowerShell script against GraphWarden for the first time.
AADSTS* error from Connect-MgGraph
The script is still authenticating against Azure AD instead of the proxy — usually because -AccessToken was not passed (so Connect-MgGraph fell back to interactive / device-code sign-in) or because the Proxy Client ID and Proxy Client Secret are wrong. Verify the two values copied from GraphWarden App Admin match the App Identity for this script, and confirm Invoke-RestMethod against /proxy/token returned a 200 with an access_token field.
403 Forbidden from Get-MgUser
A rule in the ruleset bound to your App Identity returned a block verdict. The response body names the matched rule. Review the ruleset in GraphWarden App Admin — check the match pattern, the conditions, and the scopes your App Identity was granted. The What-If Simulator replays the request without touching production Graph.
502 Bad Gateway
The proxy is reachable but Microsoft Graph returned a non-2xx upstream response. Check the proxy's health endpoint and Graph's status page; retry with the same payload after a short backoff.
Cmdlet appears to hit graph.microsoft.com directly
The MICROSOFT_GRAPH_API_ENDPOINT environment variable was not set before Connect-MgGraph, or was set in a parent process that the PowerShell session did not inherit. Run Get-MgContext and compare the reported endpoint against the proxy URL. If the variable is missing, set it explicitly in the script (as shown in the sample above) rather than relying on session inheritance.
PowerShell 5.1 raises a TLS 1.2 error
Windows PowerShell 5.1 defaults to TLS 1.0 / 1.1 on older .NET Framework versions. GraphWarden serves TLS 1.2+. Add the one-liner below before Invoke-RestMethod:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
PowerShell 7+ negotiates TLS 1.2+ by default and does not need this workaround.
Last reviewed: