You are currently viewing PowerShell and Microsoft Graph API (Client Secret Authentication)

PowerShell and Microsoft Graph API (Client Secret Authentication)

At a glance

$AppId = "Application (Client) ID"
$client_secret = "Client secret"
$TenantId = "TenantName.onmicrosoft.com"

$body = @{
    client_id     = $AppId
    scope         = "https://graph.microsoft.com/.default"
    client_secret = $client_secret
    grant_type    = "client_credentials"
}

try { $tokenRequest = Invoke-WebRequest -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing -ErrorAction Stop }
catch { Write-Host "Unable to obtain access token, aborting..."; return }

$token = ($tokenRequest.Content | ConvertFrom-Json).access_token

$authHeader1 = @{
   'Content-Type'='application\json'
   'Authorization'="Bearer $token"
}
$URL="https://graph.microsoft.com/v1.0/users"
$Users= Invoke-WebRequest -Headers $AuthHeader1 -Uri $URL
$result = ($Users.Content | ConvertFrom-Json).Value

On detail

With the Graph API, Microsoft offers us a huge possibility to retrieve, send, change, create and delete things in the tenant.
In this post I will describe how to use the Graph API with PowerShell and how to handle the data.
The Graph API is based on the OAuth 2.0 framework

When you want to use the Graph API you have to specify an endpoint.
The endpoint is the definition of what you can query e.g.:

  • /users
  • /groups
  • /applications
  • …..

All endpoints: Microsoft Graph REST API v1.0 reference

Use case:

In this post we will have a look into query details of users.

1. Preparation in the tenant

1.1 The very first thing is, to create a app registration and client secret:

1.2 Assign needed API permissions

1.3 Save the Application (Client) ID:1.4 Create a client secret:

1.5 Save the generated client secret:

2. Let’s script

#Define the basic inputs for the script
$AppId = "Enter AppId from step 1.3"
$client_secret = "Enter client secret from step 1.5"
$TenantId = "Directory (tenant) ID - you can find this in the overview section in AAD"

#Create request body
$body = @{
    client_id     = $AppId
    scope         = "https://graph.microsoft.com/.default"
    client_secret = $client_secret

    #There different grant_types see here
    grant_type    = "client_credentials"
}

#retrive access token
try { 
$tokenRequest = Invoke-WebRequest -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing -ErrorAction Stop 
}
catch { Write-Host "Unable to obtain access token, aborting..."; return }

#Put token into separate variable
$token = ($tokenRequest.Content | ConvertFrom-Json).access_token

#Create authentication header
$authHeader1 = @{
   'Content-Type'='application\json'
   'Authorization'="Bearer $token"
}

#Define URL and endpoint you want to query
$URL="https://graph.microsoft.com/v1.0/users"

#Send Query to API - Per default the method is POST
$Users = Invoke-WebRequest -Headers $AuthHeader1 -Uri $URL

#Display the results - You can drill down with the ".value" property
$result = ($Users.Content | ConvertFrom-Json).Value

3. Output

"value": [
        {
            "businessPhones": [],
            "displayName": "Conf Room Adams",
            "givenName": null,
            "jobTitle": null,
            "mail": "Adams@M365x447367.OnMicrosoft.com",
            "mobilePhone": null,
            "officeLocation": null,
            "preferredLanguage": null,
            "surname": null,
            "userPrincipalName": "Adams@M365x447367.OnMicrosoft.com",
            "id": "4c30f103-543a-47bb-ad23-9a970c0a733b"
        }, {....}

4. Further explanations

Different grant types:

  • Client_Credentials (detailed description)
    With this options you can authenticate with your App registration ID and Client Secret (non interactive)
  • authorization_code (detailed description)
    User login with their credentials and client id and client secret – in other words: on behalf of the user

Maximum results per query:

Depending on the endpoint you query the set of results varies.
My experience was, that most of the queries are limited to 1.000 results.
If you want to get more results you have to use the @odata.nextLink property:
($LastLogin.Content | ConvertFrom-Json | Select-Object ‘@odata.nextLink’).’@odata.nextLink’

This Post Has 2 Comments

  1. Will

    This is awesome. Thank you so much.

Leave a Reply