Get all assigned Intune policies and apps per Azure AD group

IMPORTANT NOTICE.

A new updated article on this topic has been published here:
https://timmyit.com/2023/10/09/get-all-assigned-intune-policies-and-apps-from-a-microsoft-entra-group/

The new article covers using the new Microsoft.Graph Powershell SDK instead of the old Intune Powershell SDK that has not been updated since 2019. I recommend you take a look at the newer article.


During MMS JAZZ Edition in New Orleans a couple of weeks ago me and the amazing Sandy Zeng did a presentation on using the Intune Powershell SDK and in this demo packed session we showed off a script that were able to find assigned policies and apps from AAD groups.

https://mmsjazz.sched.com/event/Rmdh/intune-graph-api-ftw

More info about MMS:

https://mmsmoa.com/

Little bit of a back story to this script. One of the most frustating things we’ve came a cross when working with Intune and AAD is the lack of capability to go to an AAD group and see what kind of Intune assignments has been targeted to that group. What you have to do instead is to go to each policy or app and see which group it’s assigned to, this can be a nightmare if you have a lot of different policies and apps assigned to multiple groups.

In the sample script below we have one section for getting information for all the Applications thats been assigned and then we have one section for Device Compliance, Device Configuration, Device Configuration Powershell scripts and Administrative templates.

The one thing that might be confusing when looking throug the script is the fact that not all policies even tho they are in the same blade and pane in the Intune portal they haven’t one common propertyname.

So for example, Device Configuration policies and Administrative templates are different and when we use the Intune Powershell SDK and the Get-IntuneDeviceConfigurationPolicy we won’t get any Administrative templates or powershell scripts. I haven’t been able to find any specific cmdlet for those in the 1907 SDK version so thats why we need to do a Invoke-MSGraphRequest to be able to get those policies.

Note. You need to have the Intune Powershell module installed to use the script.
https://www.powershellgallery.com/packages/Microsoft.Graph.Intune/6.1907.1.0

Sample script

# Connect and change schema 
Connect-MSGraph -ForceInteractive
Update-MSGraphEnvironment -SchemaVersion beta
Connect-MSGraph

# Which AAD group do we want to check against
$groupName = "All-Windows"

#$Groups = Get-AADGroup | Get-MSGraphAllPages
$Group = Get-AADGroup -Filter "displayname eq '$GroupName'"

#### Config Don't change

Write-host "AAD Group Name: $($Group.displayName)" -ForegroundColor Green

# Apps
$AllAssignedApps = Get-IntuneMobileApp -Filter "isAssigned eq true" -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Apps found: $($AllAssignedApps.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllAssignedApps) {

Write-host $Config.displayName -ForegroundColor Yellow

}


# Device Compliance
$AllDeviceCompliance = Get-IntuneDeviceCompliancePolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Device Compliance policies found: $($AllDeviceCompliance.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllDeviceCompliance) {

Write-host $Config.displayName -ForegroundColor Yellow

}


# Device Configuration
$AllDeviceConfig = Get-IntuneDeviceConfigurationPolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Device Configurations found: $($AllDeviceConfig.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllDeviceConfig) {

Write-host $Config.displayName -ForegroundColor Yellow

}

# Device Configuration Powershell Scripts 
$Resource = "deviceManagement/deviceManagementScripts"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=groupAssignments"
$DMS = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
$AllDeviceConfigScripts = $DMS.value | Where-Object {$_.groupassignments -match $Group.id}
Write-host "Number of Device Configurations Powershell Scripts found: $($AllDeviceConfigScripts.DisplayName.Count)" -ForegroundColor cyan

Foreach ($Config in $AllDeviceConfigScripts) {

Write-host $Config.displayName -ForegroundColor Yellow

}



# Administrative templates
$Resource = "deviceManagement/groupPolicyConfigurations"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments" 
$ADMT = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
$AllADMT = $ADMT.value | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Device Administrative Templates found: $($AllADMT.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllADMT) {

Write-host $Config.displayName -ForegroundColor Yellow

}



The result of running script will be output to the screen using Write-host and give you information on which group did it look at and what kind of policy or app did it find and out put the name of it.

Running the sample script on all AAD groups

If you instead want to run the script against all of your Azure AD groups you can simply do this by just changing the $Group variable and then add a foreach loop. If you have a lot of AAD groups it can take a while for the script to run.

# Connect and change schema 
Connect-MSGraph -ForceInteractive
Update-MSGraphEnvironment -SchemaVersion beta
Connect-MSGraph

$Groups = Get-AADGroup | Get-MSGraphAllPages

#### Config 
Foreach ($Group in $Groups) {
Write-host "AAD Group Name: $($Group.displayName)" -ForegroundColor Green

# Apps
$AllAssignedApps = Get-IntuneMobileApp -Filter "isAssigned eq true" -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Apps found: $($AllAssignedApps.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllAssignedApps) {

Write-host $Config.displayName -ForegroundColor Yellow

}


# Device Compliance
$AllDeviceCompliance = Get-IntuneDeviceCompliancePolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Device Compliance policies found: $($AllDeviceCompliance.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllDeviceCompliance) {

Write-host $Config.displayName -ForegroundColor Yellow

}


# Device Configuration
$AllDeviceConfig = Get-IntuneDeviceConfigurationPolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Device Configurations found: $($AllDeviceConfig.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllDeviceConfig) {

Write-host $Config.displayName -ForegroundColor Yellow

}

# Device Configuration Powershell Scripts 
$Resource = "deviceManagement/deviceManagementScripts"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=groupAssignments"
$DMS = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
$AllDeviceConfigScripts = $DMS.value | Where-Object {$_.groupassignments -match $Group.id}
Write-host "Number of Device Configurations Powershell Scripts found: $($AllDeviceConfigScripts.DisplayName.Count)" -ForegroundColor cyan

Foreach ($Config in $AllDeviceConfigScripts) {

Write-host $Config.displayName -ForegroundColor Yellow

}



# Administrative templates
$Resource = "deviceManagement/groupPolicyConfigurations"
$graphApiVersion = "Beta"
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments" 
$ADMT = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
$AllADMT = $ADMT.value | Where-Object {$_.assignments -match $Group.id}
Write-host "Number of Device Administrative Templates found: $($AllADMT.DisplayName.Count)" -ForegroundColor cyan
Foreach ($Config in $AllADMT) {

Write-host $Config.displayName -ForegroundColor Yellow

}

}

Thats it for this time, leave any comments below and don’t forget to follow me on twitter @Timmyitdotcom

You can also find me blogging over at http://blog.ctglobalservices.com/

61 comments

  1. Exactly what I needed after inheriting an existing Intune deployment that 3 other IT providers have been administering over the past 3 years… Thanks!

  2. When I run Get-IntuneMobileApp I dont’t get “assignments”property. Any ideas why?
    Thanks!

    1. change line 17. its backwards. need to -expand property before selecting it

      $AllAssignedApps = Get-IntuneMobileApp -Expand assignments | Select id, displayName, lastModifiedDateTime, assignments | Where-Object {$_.assignments -match $Group.id}

  3. Please correct me if I’m wrong, but to my understanding “Get-AADGroup” is not a real command. What you should be using is Get-AzureADGroup ?

  4. Great resource and learning aid to GraphAPI for Intune.

    There is however an error in the # Device Configuration Powershell Scripts section in both scripts.

    $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.assignments -match $Group.id}

    should be

    $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.groupAssignments -match $Group.id}

  5. You say “If you have a lot of AAD groups it can take a while for the script to run.” You can speed this up significantly by running:

    $AllAssignedApps = Get-IntuneMobileApp -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments
    $AllDeviceCompliance = Get-IntuneDeviceCompliancePolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments
    $AllDeviceConfig = Get-IntuneDeviceConfigurationPolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments

    ..outside of the main loop, and:

    $AssignedApps = $AllAssignedApps | Where-Object {$_.assignments -match $Group.id}
    $DeviceCompliance = $AllDeviceCompliance | Where-Object {$_.assignments -match $Group.id}
    $DeviceConfig = $AllDeviceConfig | Where-Object {$_.assignments -match $Group.id}

    ..inside it.

  6. Echoing the previous comment made for gathering assigned PowerShell scripts.

    $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.assignments -match $Group.id}

    should be

    $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.groupAssignments -match $Group.id}

    you can verify by looking at $DMS.Value … there’s no “assignments” property.

  7. great script , but it doesn’t list the ” settings catalog ” profiles type deployed

    1. +1 Can you please update the script to search settings catalog as well?

  8. Here is what I added to the script get the settings catalogs:

    # Settings Catalogs
    $Resource = “deviceManagement/configurationPolicies”
    $graphApiVersion = “Beta”
    $uri = “https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments”
    $SC = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
    $AllSC = $SC.value | Where-Object {$_.assignments -match $Group.id}
    Write-host “Number of Device Settings Catalogs found: $($AllSC.Name.Count)” -ForegroundColor cyan

    Foreach ($Config in $AllSC) {

    Write-host $Config.Name -ForegroundColor Yellow

    }

  9. Thank you! This is great as is and an awesome jumping off point to customize and learn!

  10. I would like to try this script. Does anyone have a version that combines the improvements from chaozkreator and the section for Settings Catalogue at GitHub or another location? Unfortunately I cannot access the script at the location chaozkreator provided.

    Thank you all for your help!

    1. # Fixed scripts
      # Added group members
      # Added Settings Catalogs

      # Connect and change schema
      Connect-MSGraph -ForceInteractive
      Update-MSGraphEnvironment -SchemaVersion beta
      Connect-MSGraph

      # All Intune groups in AAD
      $Groups = Get-AADGroup | Get-MSGraphAllPages | Where {($_.displayName -like “NL-*” -or $_.displayName -like “*Intune*”)}

      #### Config
      Foreach ($Group in $Groups) {
      Write-host “AAD Group Name: $($Group.displayName)” -ForegroundColor Green

      # Members
      $AllAssignedUsers = (Get-AADGroupMember -groupId $Group.id) | Select-Object -Property displayName
      Write-host ” Number of Users found: $($AllAssignedUsers.DisplayName.Count)” -ForegroundColor cyan
      Foreach ($User in $AllAssignedUsers) {

      Write-host ” “, $User.DisplayName -ForegroundColor Gray

      }

      # Apps
      $AllAssignedApps = Get-IntuneMobileApp -Filter “isAssigned eq true” -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
      Write-host ” Number of Apps found: $($AllAssignedApps.DisplayName.Count)” -ForegroundColor cyan
      Foreach ($Config in $AllAssignedApps) {

      Write-host ” “, $Config.displayName -ForegroundColor Yellow

      }

      # Device Compliance
      $AllDeviceCompliance = Get-IntuneDeviceCompliancePolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
      Write-host ” Number of Device Compliance policies found: $($AllDeviceCompliance.DisplayName.Count)” -ForegroundColor cyan
      Foreach ($Config in $AllDeviceCompliance) {

      Write-host ” “, $Config.displayName -ForegroundColor Yellow

      }

      # Device Configuration
      $AllDeviceConfig = Get-IntuneDeviceConfigurationPolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id}
      Write-host ” Number of Device Configurations found: $($AllDeviceConfig.DisplayName.Count)” -ForegroundColor cyan
      Foreach ($Config in $AllDeviceConfig) {

      Write-host ” “, $Config.displayName -ForegroundColor Yellow

      }

      # Device Configuration Powershell Scripts
      $Resource = “deviceManagement/deviceManagementScripts”
      $graphApiVersion = “Beta”
      $uri = “https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=groupAssignments”
      $DMS = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
      $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.groupAssignments -match $Group.id}
      Write-host ” Number of Device Configurations Powershell Scripts found: $($AllDeviceConfigScripts.DisplayName.Count)” -ForegroundColor cyan

      Foreach ($Config in $AllDeviceConfigScripts) {

      Write-host ” “, $Config.displayName -ForegroundColor Yellow

      }

      # Settings Catalogs
      $Resource = “deviceManagement/configurationPolicies”
      $graphApiVersion = “Beta”
      $uri = “https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments”
      $SC = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
      $AllSC = $SC.value | Where-Object {$_.assignments -match $Group.id}
      Write-host “ Number of Device Settings Catalogs found: $($AllSC.Name.Count)” -ForegroundColor cyan

      Foreach ($Config in $AllSC) {

      Write-host ” “, $Config.Name -ForegroundColor Yellow

      }

      # Administrative templates
      $Resource = “deviceManagement/groupPolicyConfigurations”
      $graphApiVersion = “Beta”
      $uri = “https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments”
      $ADMT = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
      $AllADMT = $ADMT.value | Where-Object {$_.assignments -match $Group.id}
      Write-host ” Number of Device Administrative Templates found: $($AllADMT.DisplayName.Count)” -ForegroundColor cyan
      Foreach ($Config in $AllADMT) {

      Write-host ” “, $Config.displayName -ForegroundColor Yellow

      }

      }

  11. Hi, great tool! Thanks

    Sharing my modification

    ##################### select groups by containing text

    # All Intune groups in AAD
    $Groups = Get-AADGroup | Get-MSGraphAllPages | Where {($_.displayName -like “NL-*” -or $_.displayName -like “*Intune*”)}

    ###################### new section listing members of the group

    # members
    $AllAssignedUsers = (Get-AADGroupMember -groupId $Group.id) | Select-Object -Property displayName
    Write-host ” Number of Users found: $($AllAssignedUsers.DisplayName.Count)” -ForegroundColor cyan
    Foreach ($User in $AllAssignedUsers)
    {
    Write-host ” “, $User.DisplayName -ForegroundColor Gray
    }

    ############################################################################

  12. You guys are the best.
    Had a call with MS re this yesterday and they had nothing!!
    Thank the Lord for community

  13. Trying to use this (looks helpful) but I am unsure how to make it work. I placed the code into a .ps1 file and tried to execute it but even after allowing the script to run it still fails and does not even attempt to prompt me to connect to the online services. I am use MFA.

  14. For some reason I don’t see the powershell scripts. Result show 0 but I have some assigned to the group?

  15. Love it….. is there a way to do the following I tried to decipher the PS code but was unsuccessful.
    1. Get any security policies: Antivirus, Firewall, Encryption ect.
    2. Instead of scanning a security Group scan a device by name?

  16. hey guys. how about displaying the Proactive Remediation scripts? do you have any idea how to do it?

    1. This is what I am using and seems to work well. Rest of the script and output is the same as other areas.

      # Proactive Remediation
      $Resource = “deviceManagement/deviceHealthScripts”
      $graphApiVersion = “Beta”
      $uri = “https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments”
      $Proactive = Invoke-MSGraphRequest -HttpMethod GET -Url $uri
      $AllProactive = $Proactive.value | Where-Object {$_.assignments -match $Group.id}

  17. Your original script is fantastic. Thank you!!
    Our environment has thousands of AAD groups so it’s a lot to weed through. I’ve used some of the tweaks that others have made to improve the script in the following ways:
    1. Faster as it only does a single API query run for all groups and uses a for-each to process the data from the array.
    2. Added Settings Catalogs to the script
    3. My own addition of a conditional for outputting data from each group, as I’m not interesting in knowing if a group has 0 assigned policies and apps. Literally thousands! 🙂

    https://pastebin.com/Taz6KFtk

    1. ^ This way I only get AAD groups which have Intune policies, apps etc

  18. Great script! Thank you so much for sharing!
    Is there a way to add if the app is deployed as “required” or “available”?

  19. Microsoft must have changed something recently, because listing of apps through “$AllAssignedApps = Get-IntuneMobileApp -Expand assignments | Select id, displayName, lastModifiedDateTime, assignments” does not work anymore. It was working maybe 2 weeks ago. Now, it seems that the property “assignments” is no longer present in the application attributes, that are retrieved from Graph API and it returns 0 apps for all groups.
    How do you tackle that?

    1. I found that one too.
      This C# app need registration in azure app’s on your tenant, if you can’t “read” this language very well you don’t know what it does. So security wise don’t just trust it. Make sure with someone that knows C# pretty good the app is safe and doesn’t open any backdoors or something.

  20. Number of Device Configurations Powershell Scripts found: 0

    But group in question definitely has PS scripts assigned…

  21. FYI theres a typo in the scripts part:

    $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.assignments -match $Group.id}

    should be:

    $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.groupassignments -match $Group.id}

    Could have been something Microsoft have changed though as I know it was written a few years ago

  22. Hi
    I have over 1000 Apps so the script doesnt list any apps assigned to groups. I believe its due to the script not including paging and i think some data for additional pages go into odata.nextlink and so the script needs modification to take into account large numbers. Would be amazing if you could modify this script. Thanks

  23. Hello,
    I use this script a lot, but I just found an inconsistency, what makes me wonder if I have missed any assignments in the past.

    I have a user group where I have applied two configuration policies to.
    – set desktopbackground and lockscreen image
    – set edge to open a new specified tab
    Both of them are applied and work,
    When I run the script it only shows me the “set desktop background and lockscreen image” has been applied. The policy about edge is not mentioned.

    Any ideas?
    Thanks

    1. Its most likely that those 2 policies are using different Graph API resources. Some settings and policies uses different resources in the backend tho from the UI they are configured in the same place. I would need to get some more info on the settings and how you configured them to be able to test it myself. What OS are they for ? And are they from the Settings catalog or Templates ?

  24. Hi all, has anyone re-written the original script for Powershell 7.0+ yet? Love the idea of this, but need it updated for PS 7.

  25. This is an awesome script!
    Any chance there’s a way to add endpoint security policies as well?

  26. Thank you for this script. I tried to put all outputs into an excel with export-excel but failed. Does someone know how to modify the script to get the output as an excel?

    1. Any specific reason why you want to use export-excel ? What if you try, export-csv and open the file with excel. Or out-file and save it as any other format ?

      1. I have to send this as a report to another departement and they need it as a formatted excel file.the reason is that they have other scripts for automation processes that grab information from certain colums.

  27. Hey All, I’m able to connect to the tenant but then I get a “Get-MSGraphNextPage: Not authenticated. Please use the “Connect-MSGraph” command to authenticate”. arguement. Any thoughts?

  28. Great script! Couldn’t work out why some proactive remediation scripts weren’t showing, then realised they’re assigned to ‘All Users’ or ‘All Devices’. So, in the assignments I’m seeing two groups with IDs starting ‘acacacac…’ and ‘adadadad…’ but they don’t show in the group list! Am i on the right track?

Leave a Reply to 86turimsoCancel reply