The GraphRequest PowerShell module allows to send single requests to the Microsoft Graph API.
Key features:
- Handles Microsoft Graph v1.0 and Beta APIs
- Automatic Pagination Support
- Retry Logic with exponential Backoff for transient errors (e.g. 429, 503)
- Custom Headers and Query Parameters for flexible API queries
- Optional Raw JSON Output
- Simple HTTP Proxy Support (for debugging)
- Verbose Logging Option
- User-Agent Customization
Note:
- Cleartext access tokens can be obtained, for example, using EntraTokenAid.
- Use GraphBatchRequest to send Batch Request to the Graph API.
- Find first party apps with pre-consented scopes to bypass Graph API consent GraphPreConsentExplorer
| Parameter | Description |
|---|---|
-AccessToken(Mandatory) | The OAuth access token to authenticate against Microsoft Graph API. |
-Method(Mandatory) | HTTP Method to use (GET, POST, PATCH, PUT, DELETE) |
-Uri(Mandatory) | Relative Graph URI (e.g. /users) |
-VerboseMode | Enables verbose logging to provide additional information about request processing. |
-UserAgent | Custom UserAgent |
-BetaAPI | If specified, uses the Microsoft Graph Beta endpoint instead of v1.0. |
-RawJson | If specified, returns the response as a raw JSON string instead of a PowerShell object. |
-MaxRetries(Default: 5) | Specifies the maximum number of retry attempts for failed requests. |
-Proxy | Use a Proxy (e.g. http://127.0.0.1:8080) |
-Body | Request body as PowerShell hashtable/object (will be converted to JSON). |
-QueryParameters | Query parameters for more complex queries |
-DisablePagination | Prevents the function from automatically following @odata.nextLink for paginated results. |
-AdditionalHeaders | Add additional HTTP headers (e.g. for ConsistencyLevel) |
-JsonDepthResponse(Default: 10) | Specifies the depth for JSON conversion (request). Useful for deeply nested objects in combination with -RawJson. |
-$Suppress404 | Supress 404 Messages (example if a queried User object is not found in the tenant) |
$AccessToken="YOUR_ACCESS_TOKEN"$Response=Send-GraphRequest-AccessToken $AccessToken-Method GET -Uri '/users'#Show Data$Response$AccessToken="YOUR_ACCESS_TOKEN"$Body=@{
displayName="TestSecurityGroup"mailEnabled=$falsemailNickname="TestSecurityGroup$(Get-Random)"securityEnabled=$truegroupTypes=@()
}
$Response=Send-GraphRequest-AccessToken $AccessToken-Method POST -Uri "/groups"-Body $Body"#Show Response$Response$AccessToken="YOUR_ACCESS_TOKEN"Send-GraphRequest-AccessToken $AccessToken-Method GET -Uri '/groups?$select=displayName'-BetaAPI$AccessToken="YOUR_ACCESS_TOKEN"Send-GraphRequest-AccessToken $AccessToken-Method GET -Uri '/users'-QueryParameters @{ '$filter'="startswith(displayName,'Alex')" } -Proxy "http://127.0.0.1:8080"$AccessToken="YOUR_ACCESS_TOKEN"Send-GraphRequest-AccessToken $AccessToken-Method GET -Uri '/users'-AdditionalHeaders @{ 'ConsistencyLevel'='eventual' }$AccessToken="YOUR_ACCESS_TOKEN"$QueryParameters=@{
'$select'="Id,DisplayName,IsMemberManagementRestricted"
}
$headers=@{ 'Accept'='application/json;odata.metadata=none' }
Send-GraphRequest-AccessToken $AccessToken-Method GET -Uri "/directory/administrativeUnits"-QueryParameters $QueryParameters-AdditionalHeaders $headers$AccessToken="YOUR_ACCESS_TOKEN"try {
Send-GraphRequest-AccessToken $AccessToken-Method GET -Uri '/doesnotexist'-BetaAPI -ErrorAction Stop
} catch {
$err=$_Write-Host"[!] Auth error occurred:"Write-Host" Message : $($err.Exception.Message)"Write-Host" FullyQualifiedErrorId : $($err.FullyQualifiedErrorId)"Write-Host" TargetURL: $($err.TargetObject)"Write-Host" Category : $($err.CategoryInfo.Category)"Write-Host" Script Line : $($err.InvocationInfo.Line)"
}$AccessToken="YOUR_ACCESS_TOKEN"$QueryParameters=@{
'$select'="id,SignInActivity"'$top'="1"
}
Send-GraphRequest-AccessToken $AccessToken-Method GET -Uri "/users"-QueryParameters $QueryParameters-DisablePagination