Automate Intune Tasks with PowerShell and Microsoft Graph

Automate Intune Tasks with PowerShell and Microsoft Graph

Most have heard the term Microsoft Graph API before. Ms Graph is an interface from MS for accessing and controlling a variety of Microsoft cloud services. In this blog post I will go into more detail on how you can use Graph in conjunction with Intune, what your options are and how it all works. I’ll also give you script examples in this blog that you can use directly.

PowerShell script for automating Intune tasks with Graph API

Different Possibilities

To run Microsoft Graph API calls via PowerShell, you can use the following options:

  • Microsoft Graph REST API : This is the simplest method, where you can use Invoke-RestMethod or Invoke-WebRequest to make HTTP requests to the Microsoft Graph API endpoint.
  • Microsoft Graph SDK – This is a client library that makes it easier to call Microsoft Graph API by wrapping the REST API. You can use the Microsoft Graph SDK in PowerShell by installing the Microsoft.Graph package via Install-Module Microsoft.Graph. You can find more information in the GitHub repository.

How to test graph call

To test graph calls you can use the Microsoft Graph Explorer, which is a web-based tool for making Microsoft Graph API calls and testing the API without writing any code. You can use the Graph Explorer to experiment with the API and try out different queries and operations. The graph explorer also helps you to generate PowerShell code based on the SDK. You can find the Graph Explorer in this guide.

PowerShell script for Microsoft Intune automation

How to install the Graph SDK

Before you can use the graph SDK you have to install the Graph Intune Module on your system. You can use these lines in the script to install the module if it is not already on the system.

$moduleName = "Microsoft.Graph.Intune"
if (-not (Get-Module-ListAvailable -Name $moduleName)) {
    try {
        Install-Module-Name $moduleName -Scope CurrentUser -Repository PSGallery -Force
    }catch {
        Write-Error "Failed to install $moduleName"
        Exit
    }
}
Import-Module $moduleName

How to authenticate

PowerShell SDK

When you use the PowerShell SDK the authentication is really easy. You have to run the following command at the beginning of your script:

  • With user auth:
Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All"
  • Using Service Principal:
# Certificate Thumbprint:
Connect-MgGraph -ClientId "YOUR_APP_ID" -TenantId "YOUR_TENANT_ID" -CertificateThumbprint "YOUR_CERT_THUMBPRINT"

# Certificate name:
Connect-MgGraph -ClientId "YOUR_APP_ID" -TenantId "YOUR_TENANT_ID" -CertificateName "YOUR_CERT_SUBJECT"

# Select a certificate:
$Cert = Get-ChildItem Cert:LocalMachineMy$CertThumbprint
Connect-MgGraph -ClientId "YOUR_APP_ID" -TenantId "YOUR_TENANT_ID" -Certificate $Cert

Invoke-WebRequest

With the Invoke-WebRequest method, you do not need to install a module on the system. Here you can find an example of how you can authenticate with a service principal:

  • Using Service Principal
function Get-AuthHeader{
    param (
        [parameter(Mandatory=$true)]$tenantId,
        [parameter(Mandatory=$true)]$clientId,
        [parameter(Mandatory=$true)]$clientSecret
       )
    
    $authBody=@{
        client_id=$clientId
        client_secret=$clientSecret
        scope="https://graph.microsoft.com/.default"
        grant_type="client_credentials"
    }

    $uri="https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
    $accessToken=Invoke-WebRequest -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $authBody -Method Post -ErrorAction Stop -UseBasicParsing
    $accessToken=$accessToken.content | ConvertFrom-Json

    $authHeader = @{
        'Content-Type'='application/json'
        'Authorization'="Bearer " + $accessToken.access_token
        'ExpiresOn'=$accessToken.expires_in
    }
    
    return $authHeader
}

# Add values for tenantId, clientId and clientSecret
$tenantId = ''
$clientId = ''
$clientSecret = ''

# Authentication
$global:authToken = Get-AuthHeader -tenantId $tenantId -clientId $clientId -clientSecret $clientSecret

How to get the Graph Endpoint URL

Also here we have two possibilities. One is to use the built-in network trace tool from your browser and the other is to use graph X-Ray from merill.

Graph X-Ray

Let me show how this works. Let’s start with Graph X-Ray. The first thing you have to do is install the Chrome/Edge extension from the store. Once this is done, you can open Intune and execute the transaction for which you are searching the endpoint. But before you do this, open the developer tools from the browser via F12 and select Graph X-Ray.

PowerShell script for automating Microsoft Intune tasks
  • Run the transaction and the PowerShell script will be generated. You can also save the command as a script:

All these calls are based on the Graph SDK.

Network Monitor

This approach is really similar. You also have to open the Developer tools via F12 and navigate to Network. Also here, simulate the action for which you are searching the command. Once this is done you will find the call in the Network trace.

When you click on this request, you also find some more details. This can be really helpful for HTTP POSTs to see the needed body or if you want to see the response content.

Automate Intune Tasks with PowerShell and Microsoft Graph
Automate Intune Tasks with PowerShell and Microsoft Graph

Intune Graph documentation and graph explorer

But there is also a third way, which is to use the Intune graph documentation. In this documentation almost all calls are listed and explained. Also from here you can find all necessary information. You can also use the graph explorer; there is a large resource catalogue where you can also find almost all Intune graph calls.

How to run the script

There are different ways to run a PowerShell script. The easiest way is to run the script locally on your PC via PowerShell ISE or via Visual Studio Code. This helps for one-time execution, e.g., generating a report. If you want to run the script on a scheduled basis, the easiest way is to run the script in an Azure Automation Runbook. Here I wrote a lot of blogs with examples.

Where can I find example scripts?

You can find countless examples and GitHub repositories with Intune Graph PowerShell scripts. The best source is the official Microsoft Intune Graph repository on GitHub. It is also worth taking a look at these repositories:

This is only a snippet of a lot of great repositories.

Below you can find two examples of how you can print all devices:

Without SDK (Service Principal)

function Get-AuthHeader{
    param (
        [parameter(Mandatory=$true)]$tenantId,
        [parameter(Mandatory=$true)]$clientId,
        [parameter(Mandatory=$true)]$clientSecret
       )
    
    $authBody=@{
        client_id=$clientId
        client_secret=$clientSecret
        scope="https://graph.microsoft.com/.default"
        grant_type="client_credentials"
    }

    $uri="https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
    $accessToken=Invoke-WebRequest -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $authBody -Method Post -ErrorAction Stop -UseBasicParsing
    $accessToken=$accessToken.content | ConvertFrom-Json

    $authHeader = @{
        'Content-Type'='application/json'
        'Authorization'="Bearer " + $accessToken.access_token
        'ExpiresOn'=$accessToken.expires_in
    }
    
    return $authHeader
}

# Add values for tenantId, clientId and clientSecret
$tenantId = ''
$clientId = ''
$clientSecret = ''

# Authentication
$global:authToken = Get-AuthHeader -tenantId $tenantId -clientId $clientId -clientSecret $clientSecret


# Call the Intune Graph API to retrieve a list of devices
$devicesUrl = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices"
$devicesResponse = Invoke-RestMethod -Uri $devicesUrl -Headers $global:authToken
$devices = $devicesResponse.value

# Print the device names
foreach ($device in $devices) {
    Write-Host $device.deviceName
}

With SDK (User Auth)

$moduleName = "Microsoft.Graph.Intune"
if (-not (Get-Module-ListAvailable -Name $moduleName)) {
    try {
        Install-Module-Name $moduleName -Scope CurrentUser -Repository PSGallery -Force
    }catch {
        Write-Error "Failed to install $moduleName"
        Exit
    }
}
Import-Module $moduleName

# Authenticate
Connect-MgGraph


# Get all managed devices
$devices = Get-MgDeviceManagementManagedDevice

# Print the device names
$devices | ForEach-Object {
    Write-Output $_.DisplayName
}

Graph 1.0 vs beta

Graph 1.0 is the stable version of Microsoft Graph and is intended for production use. Graph 1.0 has a stable schema, which means that the APIs and endpoints are predictable and remain stable over time. This makes it a reliable choice for developers who want to build production applications with Microsoft Graph.

On the other hand, Graph Beta is the pre-release version of Microsoft Graph, and it is subject to change. It offers new features and functionality that have not yet been released to Graph 1.0. However, because it is a beta release, it is not recommended for production use. Graph Beta may contain bugs and breaking changes that could cause compatibility issues for applications built using it. Developers who choose to use Graph Beta should be aware that they may need to update their code frequently as new changes are made.

In summary, the key difference between Microsoft Graph 1.0 and Graph Beta is stability. Graph 1.0 is a stable and reliable choice for production applications, while Graph Beta offers new features and functionality that are subject to change and may not be suitable for production use. Developers should carefully consider their needs and use cases when choosing between the two versions of Microsoft Graph.

2 thoughts on “Automate Intune Tasks with PowerShell and Microsoft Graph

Comments are closed.