How to create PowerShell script to automate tasks in Intune

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.

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 finde more informations here.

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 help you to generate PowerShell code based on the SDK. You can find the Graph Explorer here.

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 this lines in the script to install 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 Principle:
# 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:\LocalMachine\My\$CertThumbprint
Connect-MgGraph -ClientId "YOUR_APP_ID" -TenantId "YOUR_TENANT_ID" -Certificate $Cert

Invoke-WebRequest

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

  • Using Service Principle
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 build in network trace tool from your browser and the other one it to use graph X-Ray from merill.

Graph X-Ray

Let me show how this work. Lets start with Graph X-Ray. The first thing what you have to do is to install the Chrome/Edge extension form the store. Once this is done you can open Intune and execute the transaction for which you search the endpoint. But bevor you do this open the developer tools form the Browser via F12 and select Graph X-Ray.

  • Run the transaction and you the powerShell script will be generated. You can also Save the command as script:

All this 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 search the command. Once this is done you will find the call in the Network trace.

When you click on this request you find also 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.

Intune Graph documentation and graph explorer

But there is also an third way it is to use the Intune graph documentation. In this documentation almost all calls are listed and explained. Also from here you find all necessary informations. But you can also use t he graph explorer there is an large ressource 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 localy on your PC via PowerShell IME or via VisualStudio Code. This helps for one time execution for e.g. generating an report. If you want to run the script on a scheduled base the easiest way is to run the Script in a Azure Automation Runbook. Here I wrote a lot of blog with examples.

Where can I found example scripts?

You can find countless examples and git hub repositories with Intune Graph PowerShell scripts. The best source is the official Microsoft Intune Graph repository on Github. But it is also worth to take an look at this repositories:

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

Below you can find two example how you can print all devices:

Without SDK (Service Principle)

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.

3 thoughts on “How to create PowerShell script to automate tasks in Intune

Comments are closed.