Fetch Data from Microsoft Graph with PowerShell (Paging Support)

I just got back from today’s running session in a cold and wintry Sweden. Some refreshing air helped me to think about what I want this blog to become. I have a lot of ideas for upcoming posts and to make that possible I need to put some building blocks in place first. That’s what this post is, a building block.

I know that there are many guides on the web explaining how to fetch data from Microsoft Graph with PowerShell. I decided to write my own function anyway since I will refer to it in my future blog posts about Graph. This function supports paging which means that it will fetch the full result even if Graph divides it into multiple pages.

You can authenticate to Graph with your user account (delegated permissions) or as an Azure AD application (application permissions).

This function uses a registered Web/API application in Azure AD. I will first show you how to register such an application in Azure AD. After that you’ll find the PowerShell function itself and lastly an example on how to execute it.

Register an Application in Azure AD

For our PowerShell function to be able to connect to Graph and retrieve the data we must first register an application in Azure AD and grant it permissions to read the required data. We will do this in the Azure Portal (portal.azure.com).

Go to Azure Active Directory > App Registrations and Create a new application registration and fill in the form like this.

Graph1

Note the application ID. We will use this later when we run the function.

Graph2

Open the properties of the new app and click on Keys. Create a new key by entering a Description and then click Save.

Note the key that will show up under Value (you can only see the key this one time so make sure you save it somewhere).

Graph3

Click on Required permissions and then on Add.

Graph4

Chose Microsoft Graph under API.

Graph5

Select the permissions required for your script. In this example we select the Read all users full profiles permission.

Graph6

Grant the permissions that we added by clicking Grant Permissions. This must be done by an administrator so if you don’t have administrative permissions in Azure AD you have to ask an administrator to grant the permissions instead.

Graph7

The application is now registered and have the required permissions. Let’s do some PowerShell.

The PowerShell Function (Get-GraphApiResult)

The following function is used to fetch the data. There are four mandatory parameters. We must specify the client ID which is the applications ID that we noted earlier, we must specify the application secret which we also saved, we must specify the tenant name in CUSTOMERNAME.onmicrosoft.com format and we must specify the Graph URI that we would like to fetch data from.

You can use the Microsoft Graph Explorer to explore Graph and its possibilities: https://developer.microsoft.com/en-us/graph/graph-explorer

This is the function:

function Get-GraphApiResult {

    param (
        [parameter(Mandatory = $true)]
        $ClientID,

        [parameter(Mandatory = $true)]
        $ClientSecret,

        [parameter(Mandatory = $true)]
        $TenantName,

        [parameter(Mandatory = $true)]
        $Uri
    )


    # Graph API URLs.
    $LoginUrl = "https://login.microsoft.com"
    $RresourceUrl = "https://graph.microsoft.com"
    

    # Compose REST request.
    $Body = @{ grant_type = "client_credentials"; resource = $RresourceUrl; client_id = $ClientID; client_secret = $ClientSecret }
    $OAuth = Invoke-RestMethod -Method Post -Uri $LoginUrl/$TenantName/oauth2/token?api-version=1.0 -Body $Body
    

    # Check if authentication was successfull.
    if ($OAuth.access_token) {
        # Format headers.
        $HeaderParams = @{
            'Content-Type'  = "application\json"
            'Authorization' = "$($OAuth.token_type) $($OAuth.access_token)"
        }


        # Create an empty array to store the result.
        $QueryResults = @()


        # Invoke REST method and fetch data until there are no pages left.
        do {
            $Results = Invoke-RestMethod -Headers $HeaderParams -Uri $Uri -UseBasicParsing -Method "GET" -ContentType "application/json"

            if ($Results.value) {
                $QueryResults += $Results.value
            } else {
                $QueryResults += $Results
            }

            $uri = $Results.'@odata.nextlink'
        } until (!($uri))


        # Return the result.
        $QueryResults
    }
    else {
        Write-Error "No Access Token"
    }
}

Run the Function

When our function is loaded in PowerShell we can execute it like this.

Get-GraphApiResult -ClientID "95ee00e4-7d5c-4d31-b1d5-5329656dbb90" -ClientSecret "idrfVWrbCkqPgKOHCQILGAqWM1uggslg/HqV6URJbW4=" -TenantName "COMPANYNAME.onmicrosoft.com" -Uri "https://graph.microsoft.com/v1.0/users"

In our example we will fetch all users from Azure AD with https://graph.microsoft.com/v1.0/users

Conclusion

And it’s as simple as that. The function fetches the Graph result and converts it from JSON to PowerShell objects which can be managed and formatted like any other PowerShell objects (Select-Object, Format-Table, etc).

I hope this basic, but yet important guide, helped you!