Get all assigned Intune policies and apps from a Microsoft Entra group

Almost 4 years ago, back in 2019 I wrote an article on how to Get all assigned Intune policies and apps from an Azure AD group with the help of the Intune powershell SDK. https://timmyit.com/2019/12/04/get-all-assigned-intune-policies-and-apps-per-azure-ad-group/

This has become one of the most popular articles on my site and the reason for that is that Microsoft still to this day haven’t introduced any native way in the Intune or Entra ID to get a good overview of what’s been assigned to a specific group. What has changed since then is the introduction of the the Microsoft Graph PowerShell SDK

https://learn.microsoft.com/en-us/graph/sdks/sdks-overview

which replaces the old but still functional Intune Powershell SDK.
https://github.com/microsoft/Intune-PowerShell-SDK

In this article I will provide a example script with the new Microsoft Graph PowerShell SDK and there are a few changes compared to the old one.

Script

The script now uses the new Microsoft.Graph SDK instead of the older Intune powershell SDK which has been deprecated and not updated since 2019.

From the new SDK we will be using 2 modules, Microsoft.Graph.DeviceManagement and Microsoft.Graph.Groups and some of the dependencies that gets installed during the process.

Note.
I’m using Visual Studio Code ( https://code.visualstudio.com/ )with the Powershell extension installed for all my testing.

Before we jump in to the actual script it self I want to highlight some of my findings during this time when I tried to “translate” the old script to the new SDK. I also want to mention that this script is meant to be an inspiration and example on how to do this and not “this is the only way to do this”. The goal was to have a script that easy to understand and that fulfills a purpose. That being said there are many ways of expanding on this script to make it more efficient, to handle more policies, to add logging functionality or create reports based on the information.

  • Cmdlets can fool you

    I found that in a few instances when using the cmdlets available for example Get-MgDeviceAppManagementMobileApp did not retrieve all of the Android apps I expected it to find. The same thing happened with Get-MgDeviceManagementDeviceConfiguration where it did not get all the expected Device configurations. This meant I had to create my own logic for it and use Invoke-MgGraphRequest which is fine since now I can more control over what actually happens.
  • Not all policies are the same

    By this I mean for example Device Configuration policies. Though in the Intune UI they look the same and you find them in the same place in the UI they might not be the same in Graph. Take Device Configurations profiles for example. These policies can be different resource types, which means from Graph API perspective they are different but for an Admin they look the same way in UI. This is important to understand when it comes to finding policies and where to look when working with Graph.

    Example of Device Configuration policies different resource types:
    ConfigurationPolicies
    DeviceConfigurations
    GroupPolicyConfigurations
    mobileAppConfigurations
    resourcesAccessProfiles

    Finding all the different resources types is often done by testing, testing and testing.

Get-IntuneAssignmentsforEntraIDGroup

The script is also available on Github

https://github.com/timmyit/Intune/blob/master/Get-IntuneAssignmentsforEntraIDGroup

Install-Module -Name Microsoft.Graph.DeviceManagement -Force -AllowClobber
Install-Module -Name Microsoft.Graph.Groups -Force -AllowClobber
Import-Module -Name Microsoft.Graph.Groups
Import-Module -Name Microsoft.Graph.DeviceManagement

Connect-MgGraph -scopes Group.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementServiceConfig.Read.All, DeviceManagementApps.Read.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementConfiguration.ReadWrite.All, DeviceManagementApps.ReadWrite.All,DeviceManagementScripts.Read.All


### Get Azure AD Group
$groupName = "All-Windows"


$Group = Get-MgGroup -Filter "DisplayName eq '$groupName'"
### Device Compliance Policy

$Resource = "deviceManagement/deviceCompliancePolicies"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments"
$AllDCPId = (Invoke-MgGraphRequest -Method GET -Uri $uri).Value | Where-Object {$_.assignments.target.groupId -match $Group.id}

Write-host "The following Device Compliance Policies has been assigned to: $($Group.DisplayName)" -ForegroundColor Cyan

foreach ($DCPId in $AllDCPId) {

  Write-host "$($DCPId.DisplayName)" -ForegroundColor Yellow
}
 # Applications 

$Resource = "deviceAppManagement/mobileApps"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments"
$Apps = (Invoke-MgGraphRequest -Method GET -Uri $uri).Value | Where-Object {$_.assignments.target.groupId -match $Group.id}

Write-host "Following Apps has been assigned to: $($Group.DisplayName)" -ForegroundColor cyan
 
foreach ($App in $Apps) {

  Write-host "$($App.DisplayName)" -ForegroundColor Yellow
  

}

 # Application Configurations (App Configs)


$Resource = "deviceAppManagement/targetedManagedAppConfigurations"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments"
$AppConfigs = (Invoke-MgGraphRequest -Method GET -Uri $uri).Value | Where-Object {$_.assignments.target.groupId -match $Group.id}

Write-host "Following App Configuration has been assigned to: $($Group.DisplayName)" -ForegroundColor cyan
 
foreach ($AppConfig in $AppConfigs) {

  Write-host "$($AppConfig.DisplayName)" -ForegroundColor Yellow
  

}

## App protection policies


$AppProtURIs = @{
    iosManagedAppProtections = "https://graph.microsoft.com/beta/deviceAppManagement/iosManagedAppProtections?`$expand=Assignments"
    androidManagedAppProtections = "https://graph.microsoft.com/beta/deviceAppManagement/androidManagedAppProtections?`$expand=Assignments"
    windowsManagedAppProtections = "https://graph.microsoft.com/beta/deviceAppManagement/windowsManagedAppProtections?`$expand=Assignments"
    mdmWindowsInformationProtectionPolicies = "https://graph.microsoft.com/beta/deviceAppManagement/mdmWindowsInformationProtectionPolicies?`$expand=Assignments"
  }


$graphApiVersion = "Beta"

$AllAppProt = $null
foreach ($url in $AppProtURIs.GetEnumerator()) {


 $AllAppProt = (Invoke-MgGraphRequest -Method GET -Uri $url.value).Value | Where-Object {$_.assignments.target.groupId -match $Group.id} -ErrorAction SilentlyContinue
  Write-host "Following App Protection / "$($url.name)" has been assigned to: $($Group.DisplayName)" -ForegroundColor cyan
  foreach ($AppProt in $AllAppProt) {

    Write-host "$($AppProt.DisplayName)" -ForegroundColor Yellow
     
  }
  } 

# Device Configuration

$DCURIs = @{
    ConfigurationPolicies = "https://graph.microsoft.com/beta/deviceManagement/configurationPolicies?`$expand=Assignments"
    DeviceConfigurations = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations?`$expand=Assignments"
    GroupPolicyConfigurations = "https://graph.microsoft.com/beta/deviceManagement/groupPolicyConfigurations?`$expand=Assignments"
    mobileAppConfigurations = "https://graph.microsoft.com/beta/deviceAppManagement/mobileAppConfigurations?`$expand=Assignments"
  }
  
$AllDC = $null
foreach ($url in $DCURIs.GetEnumerator()) {


  $AllDC = (Invoke-MgGraphRequest -Method GET -Uri $url.value).Value | Where-Object {$_.assignments.target.groupId -match $Group.id} -ErrorAction SilentlyContinue
  Write-host "Following Device Configuration / "$($url.name)" has been assigned to: $($Group.DisplayName)" -ForegroundColor cyan
  foreach ($DCs in $AllDC) {

    #If statement because ConfigurationPolicies does not contain DisplayName. 
      if ($($DCs.displayName -ne $null)) { 
      
      Write-host "$($DCs.DisplayName)" -ForegroundColor Yellow
      } 
      else {
        Write-host "$($DCs.Name)" -ForegroundColor Yellow
      } 
  }
  } 

### Remediation scripts 

$uri = "https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts"
$REMSC = Invoke-MgGraphRequest -Method GET -Uri $uri
$AllREMSC = $REMSC.value 
Write-host "Following Remediation Script has been assigned to: $($Group.DisplayName)" -ForegroundColor cyan
 
foreach ($Script in $AllREMSC) {

$SCRIPTAS = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts/$($Script.Id)/assignments").value 

  if ($SCRIPTAS.target.groupId -match $Group.Id) {
  Write-host "$($Script.DisplayName)" -ForegroundColor Yellow
  }

}


### Platform Scrips / Device Management 

$Resource = "deviceManagement/deviceManagementScripts"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts"
$PSSC = Invoke-MgGraphRequest -Method GET -Uri $uri
$AllPSSC = $PSSC.value
Write-host "Following Platform Scripts / Device Management scripts has been assigned to: $($Group.DisplayName)" -ForegroundColor cyan

foreach ($Script in $AllPSSC) {
  
$SCRIPTAS = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts/$($Script.Id)/assignments").value 

  if ($SCRIPTAS.target.groupId -match $Group.Id) {
  Write-host "$($Script.DisplayName)" -ForegroundColor Yellow
  }

}

### Windows Autopilot profiles

$Resource = "deviceManagement/windowsAutopilotDeploymentProfiles"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments"
$Response = Invoke-MgGraphRequest -Method GET -Uri $uri
$AllObjects = $Response.value
Write-host "Following Autopilot Profiles has been assigned to: $($Group.DisplayName)" -ForegroundColor cyan

foreach ($Script in $AllObjects) {
  
$APProfile = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/$($Script.Id)/assignments").value 

  if ($APProfile.target.groupId -match $Group.Id) {
  Write-host "$($Script.DisplayName)" -ForegroundColor Yellow
  }

}

Disconnect-Graph

Using the script

Copy the script in to you favorite terminal.

Install-Module does what it says, installs 2 Modules and dependencies like Microsoft.Graph.Authentication
and Import-module just imports it so you can use it.

Connect-MgGraph is used for authentication, we add Scopes to tell the Application in Azure ( Microsoft Graph Command Line Tools” what permissions we want. If you haven’t approved these permissions before you will be prompted to do so and you will require sufficient permissions in Entra ID to be able to do that.

Side note.

All the permissions that have been granted can be reviewed under Enterprise Applications under entra.microsoft.com -> Identity -> Enterprise Applications -> Microsoft Graph Command Line Tools

Once you have been authenticated you can specify the group name in the script. Specify the name of the group you want to check for:

And run the rest of the script. It will give you output in the terminal.

That’s it for this time, Don’t forget to follow me on X (twitter) @timmyitdotcom or connect with me on LinkedIn

18 comments

  1. Hey Timmy! Briliant script, very usefull and thank you for this.

    What’s the simplest way to list all policies and apps assigned to “All Devices” and “All Users” ?
    I’ve tried pasting “All Devices” but the output was false. It has listed the apps and policies, but it was not real assignment.

    1. Looking for “#microsoft.graph.allDevicesAssignmentTarget” as the assignment worked for me.

      Apps:
      $Resource = “deviceAppManagement/mobileApps”
      $graphApiVersion = “Beta”
      $uri = “https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments”
      $AppsAssignedToAllDevices = (Invoke-MgGraphRequest -Method GET -Uri $uri).Value | Where-Object {
      # Check if any of the assignments is targeted to all devices
      $_.assignments.target.’@odata.type’ -eq “#microsoft.graph.allDevicesAssignmentTarget”
      }

      Write-host “The following Apps have been assigned to all devices:” -ForegroundColor Cyan

      foreach ($App in $AppsAssignedToAllDevices) {
      Write-host “$($App.DisplayName)” -ForegroundColor Yellow
      }

  2. Hey Timmy,
    Thank you for this great script! Really superb work done here..

    In relation to output of this script, is there a way to automate assignment of a new group to all the policies and apps where the existing groups was identified to be assigned?

  3. I came across your script when looking for how to use graph to get Intune info for a my own script. I’m finding that deviceAppManagement/mobileApps appears to be returning almost twice as many apps than I have defined in Intune. A large number of these apps I’ve never heard of (e.g. “Achievers” ?). I can’t see anything obvious from the properties to explain why these “additional” apps are being returned (I wondered if they had been flagged as “deleted”).

    Any idea why this might be the case? I expected to see the same list of apps as in the Intune portal.

  4. This is excellent for clearing up old groups with confidence. Is it possible to include a check for security baseline assignments?

  5. Thanks for sharing! I have a few comments about the script:

    – DeviceManagementApps.Read.All is called twice in Connect-MgGraph.
    – Are the DeviceManagementConfiguration.ReadWrite.All and DeviceManagementApps.ReadWrite.All rights necessary? Or are the Read.All rights sufficient? Only get commands are used in the script.

  6. I was about to start creating this script and I see it is already made! Awesome! Thanks for sharing with the community.

  7. Hi Timmy,
    Thanks its working nice as usual.

    Perhaps you could add a check that stops the script if the group does not exist.
    $Group = Get-MgGroup -Filter “DisplayName eq ‘$groupName'”

    # check if group is found
    if ($Group -eq $null) {
    write-host “Group does not exist”
    exit 0
    }

    and this part finds Assigned WindowsFeatureUpdate profiles (graph beta api), i was missing this.
    # Device Configuration beta (Wietse)

    $DCBetaURIs = @{`
    windowsFeatureUpdateProfiles = “https://graph.microsoft.com/beta/deviceManagement/windowsFeatureUpdateProfiles?`$expand=Assignments”

    }

    $AllBetaDC = $null
    foreach ($url in $DCBetaURIs.GetEnumerator()) {

    $AllBetaDC = (Invoke-MgGraphRequest -Method GET -Uri $url.value).Value | Where-Object {$_.assignments.target.groupId -match $Group.id}
    Write-host “Following Device Configuration / “$($url.name)” has been assigned to: $($Group.DisplayName)” -ForegroundColor cyan
    foreach ($betaDCs in $AllBetaDC) {

    #If statement because ConfigurationPolicies does not contain DisplayName.
    if ($($betaDCs.displayName -ne $null)) {

    Write-host “$($betaDCs.DisplayName)” -ForegroundColor Yellow
    }
    else {
    Write-host “$($betaDCs.Name)” -ForegroundColor Yellow
    }
    }
    }

    greetings.

    1. these could also be added to de DeviceConfiguration, perhaps thats better.
      windowsFeatureUpdateProfiles = “https://graph.microsoft.com/beta/deviceManagement/windowsFeatureUpdateProfiles?`$expand=Assignments”
      windowsQualityUpdateProfiles = “https://graph.microsoft.com/beta/deviceManagement/windowsQualityUpdateProfiles?$expand=Assignments”
      windowsDriverUpdateProfiles = “https://graph.microsoft.com/beta/deviceManagement/windowsDriverUpdateProfiles?$expand=Assignments”

  8. Thank you so much for this script. It is working wonderfully for me as of 9/4/2025

  9. Most of the script is working great!
    But,
    deviceHealthScripts and deviceManagementScripts are both giving 403 Forbidden errors, which is strange because the correct permissions for these have been set when we connect.

    1. You are correct, its due to missing permissions during authentication. Could be that Microsoft changed the permissions needed. But once adding the scope DeviceManagementScripts.Read.All it works fine. I will update the script to have those permissions as well in the connect-mggraph call.

Leave a Reply to VQCancel reply