Using Microsoft Graph Search API: user context

Assuming we have a registered Azure app configured correctly, including Authentication and API permissions provided – we should be ready to authenticate and call Graph API on behalf of a user.

Microsoft Graph API allows you to work with all the Microsoft 365 content – including search through Exchange e-mail messages, Yammer (Viva Engage) and Teams chat messages and surely OneDrive and SharePoint content (please refer to the original doc).

Let me focus on searching in SharePoint Online and OD here but you can use the same technique to search through other Microsoft 365 services. I will use PowerShell but same ideas should work for other platforms/languages – Python, C#, node.js etc.

Let us authenticate first. We’d need a MSAL.PS module for that.

# Ensure we have MSAL.PS module installed
Get-Module MSAL.PS -ListAvailable | ft name, Version, Path 
# Install-Module MSAL.PS -Force -Scope CurrentUser -AcceptLicense
Import-Module MSAL.PS

# Authenticate to Microsoft Interactively 
$clientid = 'd82858e0-ed99-424f-a00f-cef64125e49c' # your client id
$TenantId = '7ddc7314-9f01-45d5-b012-71665bb1c544' # your tenant id
$token = Get-MsalToken -TenantId $TenantId -ClientId $clientid -Interactive
$headers = @{Authorization = "Bearer $($token.AccessToken)" }

Below is how I search Microsoft 365 content programmatically from PowerShell using MS Graph API being authenticates as user.

# Search
# MS Graph Search API url (beta or v1.0):
$apiUrl = ""

# specify where to search - entity types
$entityTypes = "['driveItem','listItem','list','drive','site']"
$entityTypes = "['driveItem','listItem']"

# query
$query = "test*"

# build a simple request body
$body = @"
  "requests": [
      "entityTypes": $entityTypes,
      "query": {
        "queryString": "$query"

# call Graph API:
$res = Invoke-RestMethod -Headers $Headers -Uri $apiUrl -Body $Body -Method Post -ContentType 'application/json'

# explore returned object


4 thoughts on “Using Microsoft Graph Search API: user context

  1. Pingback: Search Microsoft 365 content programmatically ⋆ Microsoft 365 engineering

  2. Michael Kelly

    I keep getting a bad request and am using your code verbatim. Any suggestions? I have all the correct app permissions and other details needed are correct as well (tenant, client, secret).

    $apiUrl = “”

    $entityTypes = “[‘driveItem’,’listItem’,’list’,’drive’,’site’]”
    $query = “test*”

    $body = @”
    “requests”: [
    “entityTypes”: $entityTypes,
    “query”: {
    “queryString”: “$query”
    “region”: “NAM”

    $res = Invoke-RestMethod -Headers $Headers -Uri $apiUrl -Body $body -Method Post -ContentType ‘application/json’

    Results in:
    Invoke-RestMethod : The remote server returned an error: (400) Bad Request.

  3. Michael Kelly

    Using the same authentication method and header, I’m able to list out all of the sites with the following code:

    $URI = “”
    $WebRequest = Invoke-WebRequest -Headers $headers -Uri $URI
    $Result = ($WebRequest.Content | ConvertFrom-Json).Value

    write-host $result

    That said, I don’t believe its the headers, but perhaps the body?


Leave a Reply

Your email address will not be published. Required fields are marked *