How to leverage Microsoft APIs for Automation
Nick Ross · · Video and write-up
If you are looking to run automations against a single Microsoft tenant, its likely you would want to do so in a headless fashion. Headless, meaning you do not need to sit in front of a terminal window to authenticate. In this case, you want some service to run that is automatically authenticating and running Microsoft graph APIs to perform your automations. In other cases, you may want to create PowerShell scripts that tap into the Graph API directly vs using graph cmdlets as there are many API calls today that do not have subsequent cmdlets created.
If you are an MSP looking to run automations across the tenants you manage in Partner Cetner, check out my other article here: My Automations Break with GDAP: The Fix! – (tminus365.com) (opens in new tab)
In this article, I am going to show you how to leverage a service principal (aka App Registration) in Entra ID in order to be able to call Microsoft graph APIs and run automations in your tenant.
Creating a New Service Principal (App Registration)
The first step is creating a new service principal in Entra ID so that we have an identity that is going to be mapped to the API calls we will make in the future.
If you want to create the service principal with PowerShell, check out this script: Secure-App-Model/Create-App-Registration at main · msp4msps/Secure-App-Model (github.com) (opens in new tab)
*Note that if you leverage this script, you will still need to grant the permissions to the tenant as outlined in step 8 below.
- In the Entra ID Admin Center (opens in new tab), go to Applications>App Registrations>+New Registration

2. Provide a display name (I recommend that this name have no spaces). Add A redirect URI of https://localhost:8400 and click Register

3. On the next screen, record the Application ID and Directory ID

4. Click into Certificates and Secrets > + New Secret

5. Add a Description and Expiration date

6. Record your Secret Value (Note: You will not be able to access it again after leaving this page)

7. Next Click on API Permissions. Here we can add the necessary API permissions we will want to leverage against this tenant. You can leverage the Microsoft Graph API documentation (opens in new tab) to see which permissions are required for each API Call

Ex. Permissions:

8. After permissions are added, you will need to grant consent for your tenant (Note: you need to be a Global Admin in order to perform this action)

Getting a Refresh Token
A refresh token can be leveraged to get access tokens for authentication headers we want to make to call Microsoft Graph APIs. The refresh token is good for 90 days when generated and should be stored in a very safe location.
Use the following PowerShell Script to generate an Access Token and RefreshToken. Replace the variables at the top with the Application registration variables you recorded earlier.
# Define your application (client) ID, secret, redirect URI, and tenant ID
$clientID = "YOUR_CLIENT_ID"
$clientSecret = "YOUR_CLIENT_SECRET"
$tenantID = "YOUR_TENANT_ID"
$redirectUri = "http://localhost:8400"
$scope = "https://graph.microsoft.com/.default"
# Step 1: Open the browser for user to authenticate and grant permissions
$authUrl = "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/authorize?client_id=$clientID&response_type=code&redirect_uri=$redirectUri&response_mode=query&scope=https://graph.microsoft.com/.default"
Start-Process $authUrl
# Manual step: After the user authenticates, they will be redirected to the provided redirectUri with the authorization code in the query string.
# Capture this code manually.
$authorizationCode = Read-Host "Please enter the authorization code from the URL"
# Step 3: Exchange the authorization code for tokens
$body = "grant_type=authorization_code&client_id=$clientID&client_secret=$clientSecret&code=$authorizationCode&redirect_uri=$redirectUri&scope=$scope"
$headers = @{ 'Content-Type' = 'application/x-www-form-urlencoded' }
$tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$response = Invoke-RestMethod -Method POST -Uri $tokenEndpoint -Body $body -Headers $headers
$accessToken = $response.access_token
$refreshToken = $response.refresh_token
# Output the tokens
Write-Host -ForegroundColor Green "Access token is" $accessToken
Write-Host -ForegroundColor Blue "Refresh token is"$refreshTokenWhen you get prompted to enter an authorization code, grab the parameter from the URL:

As a best practice, copy the entire string and paste it in notepad. Only grab the code parameter and not the session state

The output will provide you an Access Token and RefreshToken. Store the RefreshToken in a safe location

Using the RefreshToken to get a new AccessToken
Your AccessToken is only going to be good for an hour so you will need to leverage another script to get a new AccessToken
function Get-AccessToken {
param (
[Parameter(Mandatory=$true)]
[string]$clientID,
[Parameter(Mandatory=$true)]
[string]$clientSecret,
[Parameter(Mandatory=$true)]
[string]$tenantID = "common", # Your tenantID
[Parameter(Mandatory=$true)]
[string]$refreshToken, # Your refreshToken
[string]$scope = "https://graph.microsoft.com/.default" # Default scope for Microsoft Graph
)
# Token endpoint
$tokenUrl = "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token"
# Prepare the request body
$body = @{
client_id = $clientID
scope = $scope
client_secret = $clientSecret
grant_type = "refresh_token"
refresh_token = $refreshToken
}
# Request the token
$response = Invoke-RestMethod -Method Post -Uri $tokenUrl -ContentType "application/x-www-form-urlencoded" -Body $body
# Return the access token
return $response.access_token
}Leveraging the Access Token to call Graph APIs
The AccessToken is what we can pass into our Graph API call request headers in order to properly authenticate. Here is a sample script that requires an AccessToken to run. It leverages two Graph API endpoints to generate a License Report for the tenant:
License Report PowerShell (opens in new tab)
Output:

Conclusion
Now that you have the fundamentals, the only thing you need to do now is making sure that your scripts/automations are able to get an AccessToken by having the correct permissions set on the App Registration for the API calls you are trying to make.
See how your Microsoft 365 tenant measures up in about a minute.
CloudCapsule scans 300+ security controls, shows what to fix first, and keeps watching for drift after you fix it. Whether you manage one tenant or fifty, it’s the complete Microsoft 365 security workflow.
No credit card required. Results in about a minute.
Keep reading
Automating Vendor Onboarding Request
Are you looking to streamline vendor onboarding requests in your organization? In this post, I’ll walk you through an end-to-end automation built in Power Automate that allows users to submit vendor onboarding requests, routes them through approval in Microsoft Teams, and—if approved—adds the software to a central inventory, notifies procurement, and even opens a ticket […]
Automate User Offboarding in Microsoft 365 | Full Tutorial
In a previous post, I showed you how to automate user onboarding via a Microsoft Form and Power Automate flow. Today we are shifting the focus to user offboarding. When managing employee offboarding, it’s crucial to ensure the process is both efficient and secure. The manual tasks, from revoking user access to transferring email permissions, […]
Automate User Onboarding with HaloPSA and Microsoft 365 | Full Tutorial
In last weeks post, I showed you how to use Microsoft Forms and Power Automate to automate employee onboardings across customers. This week, I am going to show you how to do this in HaloPSA leveraging the self-service portal customers can use as a front end. We will be using a webhook in Halo to […]



