Microsoft Graph API gives you the ability to interact with the continually evolving Azure services through a single endpoint: https://graph.microsoft.com. We are going to connect to Graph with Powershell, OAuth 2.0 and REST.
Registering your App
To interact with Graph we need to register our app. Go to https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade to get started. Login with your account that is associated with your tenant. Add a new App and enter the following details:
- Name > just give it a name
- Application Type > Web-app/-API
- Sign on Url > Doesn’t matter so we go for: http://localhost:8000

Then select you newly created App and goto Required permissions, here we are going to add the Graph API permission. You will need to select different permission depending on what you want to access. You can change this later, so for now we click Add on the top, select Microsoft Graph and in step 2 we just select Read and write access to user profile.

The last step is to create a key, go to Keys and enter a Key Description and set the duration to Never Expires. When you click on Save the value (ClientSecret) will only be displayed once, so write it done when it’s displayed.

Become an ethical hacker that can hack computer systems like black hat hackers and secure them like security experts.
Authentication and Authorization
To access the Graph API we need to get an Access Code. If you are new to working with Rest and Graph API then there are a few things to keep in mind:
- To get an Access Token you need an Authorization Code. The code is only 1 hour valid, but as long as your refresh token is valid, you only need to renew this every 90 days.
- The Access Token, which is used in every request is only valid for 1 hour. You can renew it with the Refresh Token.
- The Refresh Token is valid for 14 days.
So the first step is to get the Authentication code. We use the script below for this. Run the scripts with :
1. GraphAPIGetAuthCode.ps1 -ClientId <clientId> -ClientSecret <clientSecret> -RedirectUrl <redirectUrl>
It will store the Authentication code in a text file at the script root location. This way we can easily access it later.

Thanks to Darren Robinson: https://gist.github.com/darrenjrobinson/b74211f98c507c4acb3cdd81ce205b4f#file-ps2graphapi-ps1
Get the Access and Refresh Token
With the Authentication code we can get the all important Access token and the much needed refresh token. Because the Access token is only 1 hour valid, we need to check it’s age and request a new one with the refresh token if it’s expired.
The script below stores the access and refresh token in text files in the script root location. You can always change it to store it just in variables, but keep in mind, when you close the shell it’s all gone and you need to start again with the Authorization code.
The scripts checks the last modified time of the accesstoken.txt, if it’s older than 1 hour, it will request a new access token with the refresh token. If that fails, it will request a new Authorization code and start from their again.
I use a config.json file to store my ClientId, ClientSecret and RedirectUrl, this way you can easily change it.
Config.json
1. { 2. "AppId": { 3. "ClientId": "fa9d9d34-7a2a-****-****-************", 4. "ClientSecret": "J/WDSKLjE+XC9G0+ASDHUen31/***********=", 5. "RedirectUrl": "https://localhost:8000", 6. "ResourceUrl": "https://graph.microsoft.com" 7. } 8. }
ConnectTo-Graph
1. #----------------------------------------------------------[Declarations]---------------------------------------------------------- 2. 3. #Get the config file 4. $config = Get-Content $PSScriptRoot"\config.json" -Raw | ConvertFrom-Json 5. 6. # Add System Web Assembly to encode ClientSecret 7. Add-Type -AssemblyName System.Web 8. 9. # Encode ClientSecret 10. $clientSecretEncoded = [System.Web.HttpUtility]::UrlEncode($config.AppId.ClientSecret) 11. 12. # Get the accessToken 13. If ((Test-Path -Path $PSScriptRoot"\accessToken.txt") -ne $false) { 14. $accessToken = Get-Content $PSScriptRoot"\accessToken.txt" 15. } 16. 17. #---------------------------------------------------------[Initialisations]-------------------------------------------------------- 18. 19. # Check if the AccessToken is not older then 1 hour 20. If (($accessToken -eq $null) -or ((get-date) - (get-item $PSScriptRoot"\accessToken.txt").LastWriteTime).TotalHours -gt 1) { 21. 22. # Get the refreshToken 23. $refreshToken = Get-Content $PSScriptRoot"\refreshToken.txt" 24. 25. $clientId = $config.AppId.ClientId 26. $clientSecret = $config.AppId.clientSecret 27. $redirectUrl = $config.AppId.RedirectUrl 28. $resourceUrl = $config.AppId.ResourceUrl 29. 30. Try { 31. $refreshBody = "grant_type=refresh_token&redirect_uri=$redirectUrl&client_id=$clientId&client_secret=$clientSecretEncoded&refresh_token=$refreshToken&resource=$resourceUrl" 32. 33. $Authorization = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token ` 34. -Method Post -ContentType "application/x-www-form-urlencoded" ` 35. -Body $refreshBody ` 36. -UseBasicParsing 37. } 38. Catch { 39. $webResponse = $_.Exception.Response 40. } 41. 42. If ($webResponse -ne $null) { 43. # Get Authorization code 44. GraphAPIGetAuthCode.ps1 -ClientId $clientId -ClientSecret $clientSecret -RedirectUrl $redirectUrl 45. 46. $authCode = get-content $PSScriptRoot"\authCode.txt" 47. $body = "grant_type=authorization_code&redirect_uri=$redirectUrl&client_id=$clientId&client_secret=$clientSecretEncoded&code=$authCode&resource=$resourceUrl" 48. 49. $Authorization = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token ` 50. -Method Post -ContentType "application/x-www-form-urlencoded" ` 51. -Body $body ` 52. -UseBasicParsing 53. } 54. 55. # Store refreshToken 56. Set-Content $PSScriptRoot"\refreshToken.txt" $Authorization.refresh_token 57. 58. # Store accessToken 59. $accessToken = $Authorization.access_token 60. Set-Content $PSScriptRoot"\accessToken.txt" $accessToken 61. }
Getting actual date with Invoke-RestMethod from Graph
After all is done we can interact with Graph as followed:
1. Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} ` 2. -Uri https://graph.microsoft.com/v1.0/me ` 3. -Method Get
You can download the scripts here: https://github.com/ruudmens/SysAdminScripts/tree/master/Graph