Friday, 5 January 2018

How to Connect Microsoft Graph API using PowerShell

In this post I am going to explain how to consume Microsoft Graph endpoints in Powershell and provide sample query to fetch current user information from Azure AD. To call Microsoft Graph API, we must first acquire an access token from Azure Active Directory (Azure AD), we can get access token either after registering new Azure AD application or by using the apps that was pre-registered by Microsoft (for ex: Well Known PowerShell App Id).

Steps to register a Native Azure Application (ClientId):

  1. Login to Azure Portal
  2. Navigate to "Azure Active Directory" > "App Registrations"
  3. Click "New Application Registration"
  4. Give a friendly name for your application, select application type as "Native", and enter a redirect URL in the format urn:foo (ex: "urn:ietf:wg:oauth:2.0:oob") and create the app.
  5. Click on the App > Settings > Required Permissions
  6. Click Add (+) > Select an API > choose the "Microsoft Graph" API and click Select.
  7. Grant the required permissions for the App (ex: "Read and write all users' full profiles", "Read and write all groups").
  8. Go to Settings > Properties > Copy the Application ID and use that id for ClientId parameter in the below script.
  9. Go to Settings > Redirect URIs > Copy the Redirect Uri and use that for the RedirectUri parameter in the below script.
We are going to acquire access token by using the Active Directory Authentication Library (ADAL). To use ADAL library we need to install Azure AD PowerShell Module. If your main OS is Windows 10 or if you have PowerShellGet installed, you can run the following command to install the Azure AD PowerShell module.
Install-Module AzureAD -SkipPublisherCheck -AllowClobber -Force

Function - GetAccessToken

The below powershell function will use the Well Known Powershell Client Id (1950a258-227b-4e31-a9cf-717495945fc2) if you have not passed the ClientId parameter.
Function GetAccessToken {
    param (
        [Parameter(Position=0, Mandatory=$false)]
        [string] $ClientId,
        [Parameter(Position=1, Mandatory=$false)]
        [string] $RedirectUri,
        [Parameter(Position=2, Mandatory=$false)] 
        [string] $Office365Username, 
        [Parameter(Position=3, Mandatory=$false)]
        [string] $Office365Password    
      )
    # Set ADAL (Microsoft.IdentityModel.Clients.ActiveDirectory.dll) assembly path from Azure AD module location
    try {
    $AADModule = Import-Module -Name AzureAD -ErrorAction Stop -PassThru
    }
    catch {
    throw 'The AzureAD PowerShell module not installed'
    }
    $adalPath = Join-Path $AADModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
    $adalformPath = Join-Path $AADModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll"
    [System.Reflection.Assembly]::LoadFrom($adalPath) | Out-Null
    [System.Reflection.Assembly]::LoadFrom($adalformPath) | Out-Null   

    # If client not proivded, we are setting the id of an Azure AD app which is pre-registered by Microsoft
    if([string]::IsNullOrEmpty($ClientId) -eq $true)
    {    
    # This is a well known and pre-registered Azure AD client id of PowerShell client. 
    $ClientId = "1950a258-227b-4e31-a9cf-717495945fc2" 
    $RedirectUri = "urn:ietf:wg:oauth:2.0:oob"
    }
    elseIf ([string]::IsNullOrEmpty($RedirectUri) -eq $true)
    {
      throw "The RedirectUri not provided"
    }
    $resourceURI = "https://graph.microsoft.com"
    $authority = "https://login.microsoftonline.com/common"
    $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
     
    #Acquire token without user interaction
    if (([string]::IsNullOrEmpty($Office365Username) -eq $false) -and ([string]::IsNullOrEmpty($Office365Password) -eq $false))
    {
    $SecurePassword = ConvertTo-SecureString -AsPlainText $Office365Password -Force
    #Build Azure AD credentials object
    $AADCredential = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential" -ArgumentList $Office365Username,$SecurePassword
    # Get token without login prompts.
    $authResult = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($authContext, $resourceURI,$ClientId, $AADCredential)
    $accessToken = $authResult.Result.AccessToken
    }
    else
    {
    # Get token by prompting login window.
    $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Always"
    $authResult = $authContext.AcquireTokenAsync($resourceURI, $ClientID, $RedirectUri, $platformParameters)
    $accessToken = $authResult.Result.AccessToken
    }

    return $accessToken
}

Get Access Token :

The below command gets required access token with login prompts.
$accessToken = GetAccessToken
Get token by passing the parameters ClientId and RedirectUri: Here we have used the id of Azure Active Directory PowerShell app which is used in Azure AD powershell module.
$accessToken = GetAccessToken -ClientId '1b730954-1685-4b74-9bfd-dac224a7b894' -RedirectUri 'urn:ietf:wg:oauth:2.0:oob'
Get access token by passing credentials without login prompts:
$accessToken = GetAccessToken -Office365Username "admin@tenant.onmicrosoft.com" -Office365Password "admin_pwd"

Connect and Fetch data from Azure AD using Rest API :

Once you get the required access token you can easily query graph api using Invoke-RestMethod cmdlet by passing access token.
Example 1: The below command gets the current user profile details.

$apiUrl = "https://graph.microsoft.com/v1.0/me"
$myPrfoile = Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} -Uri $apiUrl -Method Get
Example 2: The below command gets all the Azure AD user details.
$apiUrl = "https://graph.microsoft.com/v1.0/users"
$users = Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} -Uri $apiUrl -Method Get

Advertisements
Advertisements

No comments:

Post a Comment