Use Microsoft Graph API with PowerShell – Part 2

You read the second Part in this Series, where we will take care of the PowerShell Script itself and how Authentication will work. OAUTH2 is the Keyword here, so be as secure as possible.

Part 1 – Authentication and Azure App – Use Microsoft Graph API with PowerShell – Part 1 » TechGuy
Part 2 – Oauth2.0 – Use Microsoft Graph API with PowerShell – Part 2 » TechGuy
Part 3 – First Powershell Script to get a Teams Lis and Walkthrough – Use Microsoft Graph API with PowerShell – Part 3 » TechGuy
Part 4 – many examples – Use Microsoft Graph API with PowerShell – Part 4 » TechGuy

Variables

So first, we will define some variables. At one point, I want to show you different Authentication methods, so not all variables are used in each Authentication case. But to keep it simple, we will define all of them on top.

$User="User@Domain.com" #User to be used for the delegated Permissions
$PW="MyPassword!" #Password

#region auth
# The resource URI
$resource = "https://graph.microsoft.com"
$clientid = "ea00d000-0000-0000-0cbc-fe000d0f0eb0" #Application (client) ID from Azure App registration Page
$clientSecret = "CGxxxExX4TD05x7x-.0HLj0-RgLcc~~md2" #Client Secret from "Certificate $ secrets"
$redirectUri = "http://localhost" # Redirect URL, which was used at App Registration Process
$Tenantid = "d00b0de0-0000-00f0-a000-0fbf0000000" # Directory (tenant) ID also from Azure App registration Page

So with this Information, we can go on to get the Authentication Token, which is used to Run Graph API Commands, so each of the following three methods results in an AuthToken in Variable “tokenResponse.” With this Variable, we can work on the next steps, so it has does not matter which method you use related to the next steps. It’s just related to how you want to use the Automation and what you are trying to archive.

Related to this, you need to choose one of the following methods. Just a hint, these 3 Methods are not reflecting a full list. For example, if you decide to use Cert Atuh instead of Client Secret, you have at least 2 Methods more. So, you see, there are a lot of possibilities to archive this.

Method 1 – Authorization Code Flow

The Method is called “Authorization Code Flow” and the Details are here: Microsoft identity platform and OAuth 2.0 authorization code flow – Microsoft identity platform | Microsoft Docs

This Method will open a Login Page, where you need to Enter User Credentials. This can be used when doing “Delegated Permission.” As there is an active Interaction with you, this isn’t very useful for Automation, caus on each request, User and PW is required.

#region Auth1
#With User Interaction for Delegated Permission
Add-Type -AssemblyName System.Web

Function Get-AuthCode {
    Add-Type -AssemblyName System.Windows.Forms

    $form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width = 440; Height = 640 }
    $web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width = 420; Height = 600; Url = ($url -f ($Scope -join "%20")) }

    $DocComp = {
        $Global:uri = $web.Url.AbsoluteUri        
        if ($Global:uri -match "error=[^&]*|code=[^&]*") { $form.Close() }
    }
    $web.ScriptErrorsSuppressed = $true
    $web.Add_DocumentCompleted($DocComp)
    $form.Controls.Add($web)
    $form.Add_Shown( { $form.Activate() })
    $form.ShowDialog() | Out-Null

    $queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
    $output = @{}
    foreach ($key in $queryOutput.Keys) {
        $output["$key"] = $queryOutput[$key]
    }

    #$output
}

Get-AuthCode
#Extract Access token from the returned URI
$regex = '(?<=code=)(.*)(?=&)'
$authCode = ($uri | Select-string -pattern $regex).Matches[0].Value

Write-output "Received an authCode, $authCode"

$tokenBody = @{  
    Grant_Type    = "authorization_code"  
    Scope         = "https://graph.microsoft.com/.default"  
    Client_Id     = $clientId  
    Client_Secret = $clientSecret
    redirect_uri  = $redirectUri
    code          = $authCode
    ressource     = $resource
}   

$tokenResponse = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token -Method Post -ContentType "application/x-www-form-urlencoded" -Body $tokenBody -ErrorAction STOP

#endregion Auth1

Method 2 – Resource Owner Password Credentials

The Method is called “Resource Owner Password Credentials,” and the Details are here: Sign in with resource owner password credentials grant – Microsoft identity platform | Microsoft Docs

This Method is perfect when Delegated Permission with fully Automation is needed, cause no interaction or Login Prompts are necessary.

But, in this case we have to enable a Setting in our Azure App, please navigate to

  • Azure Portal
  • App Registrations
  • Select your App
  • Authentication
  • Enable “Allow public client flows.”
#region Auth2
#No User Interaction and delegated Permissions, Azure App Setting needed
$tokenBody = @{  
    Grant_Type = "password"  
    Scope      = "user.read%20openid%20profile%20offline_access"  
    Client_Id  = $clientId  
    username   =  $User
    password   = $pw
    resource  = $resource
}   

$tokenResponse = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token -Method Post -ContentType "application/x-www-form-urlencoded" -Body $tokenBody -ErrorAction STOP

#endregion Auth2

Method 3 – Client Credentials Flow

The Method is called “Client Credentials Flow,” and the Details are here: OAuth 2.0 client credentials flow on the Microsoft identity platform | Microsoft Docs

This Method is perfect when Application Permission with fully Automation is needed, cause no interaction or Login Prompts are necessary.

#region Auth3
# No interaction, Application Permission
$tokenBody = @{  
    Grant_Type    = "client_credentials"  
    Scope         = "https://graph.microsoft.com/.default"  
    Client_Id     = $clientId  
    Client_Secret = $clientSecret  
}   

$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$Tenantid/oauth2/v2.0/token" -Method POST -Body $tokenBody  


#endregion Auth3

So, as mentioned on Top, there are several more ways to Authenticate and use Oauth2. More Details are here: OAuth 2.0 and OpenID Connect protocols on Microsoft identity platform – Microsoft identity platform | Microsoft Docs

First GRAPH API Query

Now it’s time for our first Query. Despite what Method you have chosen, the tokenRepsonse Variable is holding our Key to Query against the Microsoft GRAPH API.

We want a list of all Teams in our Tenant, so this require propriate Application Permission, but more on the next Post.

And now it gets a little bit confusing. Microsoft GRAPH API is still a “work in progress,” so some commands are in Beta, some command Names are different from what we expect.

Who does not want to wait? You get a full list of references here: Microsoft Graph REST API v1.0 reference – Microsoft Graph v1.0 | Microsoft Docs

So our Powershell to get a Full List of all Teams look like this

$headers = @{
        "Authorization" = "Bearer $($tokenResponse.access_token)"
        "Content-type"  = "application/json"
    }

$URL = "https://graph.microsoft.com/beta/groups?`$filter=resourceProvisioningOptions/Any(x:x eq 'Team')"  
$AllTeams = (Invoke-RestMethod -Headers $headers -Uri $URL -Method GET).value 

In this case, all Teams are in the Array AllTeams with all Properties.

The Query itself is using the “still” beta Version to get all Groups from Azure and filter with “resourceProvisioningOptions=Team”

Other Command, for example to get all Channels from a Team, look like this. Here we us the “Team” GRAPH API directly.

$headers = @{
        "Authorization" = "Bearer $($tokenResponse.access_token)"
        "Content-type"  = "application/json"
    }
        
$URL = "https://graph.microsoft.com/v1.0/teams/$($Team.id)/channels"  
$AllChannels = (Invoke-RestMethod -Headers $headers -Uri $URL -Method GET).value 

The next post will explain GRAPH API a little bit further and how to get the correct URL and build the Request Body, Stay tuned.

Michael Seidl

15 thoughts on “Use Microsoft Graph API with PowerShell – Part 2”

  1. Pingback: Use Microsoft Graph API with PowerShell – Part 4 » TechGuy

  2. Pingback: Use Microsoft Graph API with PowerShell – Part 3 » TechGuy

  3. Pingback: Paging in Microsoft Graph REST API » TechGuy

  4. Pingback: Send Mail with PowerShell and Microsoft Graph API » TechGuy

  5. Pingback: Assign Windows 365 License with PowerShell and MS GRAPH API » TechGuy

  6. Pingback: Use Microsoft Graph API with PowerShell - Part 1 - TechGuy

  7. Pingback: Create Microsoft ToDo Task with PowerShell and Microsoft GRAPH API - TechGuy

  8. Pingback: Enable Lost Mode for Intune Device with PowerShell and Microsoft Graph API - TechGuy

  9. Pingback: Create Microsoft Team with PowerShell and MS Graph API - TechGuy

  10. Pingback: Get all your Azure Enterprise Apps with Owner and Usage Count - TechGuy

  11. Pingback: Deploy Windows 365 via Powershell - NielsKok.Tech

  12. I am running authentication in VSC , with method 1 authentication I get PS7 pop up with blank window, anyone else facing same issue

  13. More update, I’ve tested the authentication method1 in different ways , I still get blank pop-up, there is no place to type in credential, anyone having same issue

  14. Pingback: Draft Mail with PowerShell and Microsoft Graph API - TechGuy

Leave a Comment

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

*