Microsoft recently announced that developers should switch focus from Azure Ad graph to Microsoft Graph considering the plans are to work hard to close the gab between the two products – here

The Modern desktop management word fosters automation more than ever. Operations on tenant like maintenance or replication will become more and more familiar.

In this post you will learn how to use unattended Microsoft Graph API calls with PowerShell. Below are the high-level steps we will discuss

  • Register native AAD application with application secret
  • Grant permissions and administrative consent
  • Create access token and access Microsoft Graph
  1. Register Native AAD application.

We will register the application using PowerShell commands. As seen below, we need a client secret, an application name and redirect URIs


#client Secret is the application password . You can cenerate this as long as you dont have
# special characters like + or / that can prevent correct authentication 
$client_secret = "2Uban4QXXXXXqg6mcXdpXXXXXzsTPPixJf6kXgcml3E="
#you canuse any valid URL here
$homePage = ""
$appIdURI = ""
$logoutURI = ""

#We create the application secret valid for one year starting today
$keyId = (New-Guid).ToString();
$applicationSecret = New-Object Microsoft.Open.AzureAD.Model.PasswordCredential($null, $today.addyears(1), $keyId, $today, $client_secret)
# We create the AAD aplication 
$AADApplication = New-AzureADApplication -DisplayName $applicationName `
        -HomePage $homePage `
        -ReplyUrls $homePage `
        -IdentifierUris $appIdURI `
        -LogoutUrl $logoutURI `
        -PasswordCredentials $applicationSecret

# We create a service principal for our application application 
$servicePrincipal = New-AzureADServicePrincipal -AppId $AADApplication.AppId

Once you execute the code, the BlogGrapApp will be created. Make sure you make a note of your application ID, tenant ID and client secret ( password ). We will use them later.


2. Let’s validate in portal that the application was created

  • Go to Azure Active Directory -> App registration (preview).
  • In the new blade you should see the newly created application
  • Click on the new application
  • Validate the following: 1. Display Name,  2. Application ID,  3. Tenant ID, 4. URI and 5. Service principal

Now is time to add some permissions.

  • Click on View API permissions -> + Add a permission
  • In the newly open blade click Microsoft Graph
  • Click Delgated permissions

Let’s pause for a while, list down what we want to do with our script and see what permissions we want. In this post I like to address mobile applications up to the content file we uploaded when created an application. Make sure you have an MSI application already upload to your tenant. In my case I have Google Chrome.

Let’s check the Microsoft Graph reference website for mobile aps  –here

To list mobile apps we need one of the following DeviceManagementApps.ReadWrite.All, DeviceManagementApps.Read.All

  • Let’s add them, along with Directory. Read All
  • Once you selected them click add permissions.
  • In the newly opened blade click Grant admin Consent , then yes

Now you should have all set for final part – see Microsoft Graph API calls in action

3. Let’s create the PowerShell script to call the Graph

Remember we took a note of the app id, tenant id and secret we used  when creating the application? Now is the time to use them. Let’s define the parameters

# Define parameters for Microsoft Graph access token retrieval
    $client_id = "8e7501fb-e1d5-4f73-ab40-xxxxxxxxxxx"
    $client_secret = "2Uban4QXXXXXqg6mcXdpXXXXXzsTPPixJf6kXgcml3E="
    $tenant_id = "your tenant ID-4349-8a55-6xxxx611e668"

    $resource = ""
    $authority = "$tenant_id"
    $tokenEndpointUri = "$authority/oauth2/token"
#make sure you add your admin and password below.
# I dont not recommend using admin and password in clear text, but this is a demo tenant
    $UserForDelegatedPermissions="admin@your tenant"
    $Password="your admin pass" 

Use the below script to create the access token we will use when calling Graph API. For more reference check this link

$content = "grant_type=password&client_id=$client_id&client_secret=$client_secret&username=$UserForDelegatedPermissions&password=$Password&resource=$resource";
$response = Invoke-RestMethod -Uri $tokenEndpointUri -Body $content -Method Post -UseBasicParsing
$access_token = $response.access_token

In case you receive an error, you need to replace $content with the following value

$content = “grant_type=password&client_id=$client_id&client_secret=$client_secret&username=$UserForDelegatedPermissions&password=$Password&resource=$resource”;

You can now check the access token . you will get something like this ( my output was truncated)

It is time to put the token to good use. According to the Microsoft Graph repository, to list all the mobile apps you need to access   GET /deviceAppManagement/mobileApps

$testcallapps = ""

$apps = Invoke-RestMethod   -Uri $testcallapps  -Headers @{"Authorization" = "Bearer $access_token"}   -ContentType "application/json"  -Method GET 

The $apps.value variable should have all the apps

Let’s dig deeper and see if we can get access to one of the MSI files we uploaded to the tenant. In my case I have previously created Chrome application as LOB Application.

To check for the application, I use

($apps.value | ?{ $_.displayname -like "Google*"}).id 

With the ID we got, we can check how many content versions we have

$testCallUri1 = "" 
$body1 = Invoke-RestMethod   -Uri $testCallUri1  -Headers @{"Authorization" = "Bearer $access_token"}   -ContentType "application/json"  -Method GET   

In my case we have only 1 version

So, “Google Chrome” has only one version content. Next level is to query the files included in the version. Let’s modify the URI to query for the files included in version “1” of Google Chrome LOB Application 

$testCallUri1 = "" 
$body1 = Invoke-RestMethod   -Uri $testCallUri1  -Headers @{"Authorization" = "Bearer $access_token"}   -ContentType "application/json"  -Method GET     

The query says the file name GoogleChromeStandaloneEnterprise.msi has one id associated. Using this ID we can get to the file URI that we can download

But, for that we need to modify again the URI to add the file id

$testCallUri1 = "" 
$body1 = Invoke-RestMethod   -Uri $testCallUri1  -Headers @{"Authorization" = "Bearer $access_token"}   -ContentType "application/json"  -Method GET  

Evirka!!!! We have the URI to the application. We can download it


Microsoft Graph is an etremely powerfull product when it comes to automating your Microsoft 365activities. Kowing this product will be key for a succesful admin.

In this post you learned how to create a Azure native app, how to add the necessary rights and how to query for specific information using Microsoft Graph API unattended calls