Intune Enterprise App Management – Bulk add applications using Graph

There have been plenty of posts covering the new Enterprise App Management functionality in the Intune suite, but I’ve now had a chance to look at what’s going on within the API and more importantly, how I can automate it!

This didn’t make the cut-off for my book, but if there is a second edition, I’ll be sure to include it!

You can find my full bulk deployment script on GitHub here:

https://github.com/andrew-s-taylor/public/blob/main/Powershell%20Scripts/Intune/bulk-add-win32-enterprise-apps.ps1

Now, let’s see what’s actually happening

When selecting an app, it is grabbing everything available with a GET request against this URL:

https://graph.microsoft.com/beta/deviceAppManagement/mobileAppCatalogPackages?$apply=groupby((productId,productName,publisher))

This retrieves an array of values with all of the currently available applications. The key value here is:

productId

Once we have this, we can then find the versions available for the application with another GET request to this URL:

https://graph.microsoft.com/beta/deviceAppManagement/mobileAppCatalogPackages?$filter=productId eq '$selectedappid'

In my script I am grabbing the first value which is the latest version, but you could also send this to an out-gridview to give a choice. My code is:

$selectedversion = $appdetails | Select-Object -First 1

In the returned array, we simply need the ID which is all we have to pass through to the next step.

We now have our app details so we need to convert this to JSON to use with the mobileapps request. To do this we send a request to a new URL including our version ID:

https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/convertMobileAppCatalogPackageToMobileApp(versionId='$versionid')

It’s important here to note that the returned content will give a 400 error if you send it straight through as you need to remove some values first (@odata.context, id, largeIcon, createdDateTime, lastModifiedDateTime, owner, notes, size).

To do this, I am retrieving the data into a PowerShell object and then removing those values:

$converted = (Invoke-MgGraphRequest -uri $converturi -Method GET -OutputType PSObject) | Select-Object * -ExcludeProperty "@odata.context", id, largeIcon, createdDateTime, lastModifiedDateTime, owner, notes, size

The interesting thing to note in the output is the new odata.type:

"@odata.type": "#microsoft.graph.win32CatalogApp"

This tells Graph to sort the package itself rather than expecting an upload.

We then simply convert our output to JSON and send the request:

$posturi = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps"

$convertedjson = $converted | ConvertTo-Json

Invoke-MgGraphRequest -Method POST -Uri $posturi -Body $convertedjson -ContentType "application/json"

Hopefully this new functionality now makes sense, happy automating!

If you want to learn more about Intune automation, be sure to check out my book in the sidebar 🙂

Leave a Comment