Support tip: Leveraging PowerShell to view and manage Microsoft Intune Assignment filters

This post has been republished via RSS; it originally appeared at: New blog articles in Microsoft Community Hub.

By: Gowdhaman K – Product Manager 2 | Microsoft Intune

 

Assignment filters in Intune allow you to narrow the assignment scope of policies. For example, you can create an assignment filter that includes only devices that are enrolled in Intune, run Windows 10, and have a specific hardware model. You can then assign a configuration profile or an app to All devices with this filter in include mode, and only the devices that match the criteria will receive the assignment. This way, you can ensure that your assignments are relevant and appropriate for your devices and users. Further, you can use the Associated Assignments tab in each assignment filter to review the associated assignments.

 

Each tenant can create and use up to 200 assignment filters; for some organizations, this limit might be quickly reached. To help IT admins manage them efficiently on a periodic basis, you can leverage PowerShell and Microsoft Graph API to create a report that will generate all assignment filters along with the rule and associated assignments.

 

Important: From a support perspective, Microsoft fully supports Intune and its ability to deploy shell scripts to macOS. However, Microsoft does not support the scripts themselves, even if they are on our GitHub repository. They are provided for example only. You are responsible for anything that they may do within your environment. Always test!

 

The sample script, provided below, exports the data in HTML format for review and corresponding CSVs to manipulate. The script has $ReportFolder parameter (with default value of “C:\Windows\temp”) where you will find three files on every execution.

 

A screen capture of the three files generated, a CSV for Associated assignments, a CSV for the Summary, and an HTML view of the generated report.A screen capture of the three files generated, a CSV for Associated assignments, a CSV for the Summary, and an HTML view of the generated report.

 

The report will have a summary table of all assignment filters in the tenant with filter type, platform, rule, and associated assignments count along with a few other common fields. A second table will list all associated assignments details for each filter with payload id, payload name, payload type and intent.

 

A screen capture of the generated assignment filters summary report.A screen capture of the generated assignment filters summary report.

 

Note: In this sample script, we use delegated permissions. If you want to run the script unattended in an automation tool, modify the script to leverage a client app registration along with a client secret – see Authentication module cmdlets in Microsoft Graph PowerShell for details on how to do this.

 

The script requires Microsoft Graph PowerShell modules. You can install these using the commands below:

 

 

Install-Module Microsoft.Graph Install-Module Microsoft.Graph.Beta

 

 

 

Refer to Install the Microsoft Graph PowerShell SDK documentation for more info.

 

Sample script

 

 

Param ( $ReportFolder = “C:\Windows\Temp” ) $Head = "<style>" $Head +="BODY{background-color:#CCCCCC;font-family:Calibri,sans-serif; font-size: small;}" $Head +="TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse; width: 98%;}" $Head +="TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#293956;color:white;padding: 5px; font-weight: bold;text-align:left;}" $Head +="TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#F0F0F0; padding: 2px;}" $Head +="</style>" $Now = Get-Date -Format "dd-MM-yyyy-HH-mm-ss" $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew() #Connect to Microsoft Graph using delegated permissions Write-Output "Connecting Microsoft Graph..." Connect-MgGraph -scopes Group.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementServiceConfig.Read.All, DeviceManagementApps.Read.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementApps.Read.All #Get all Assigment Filters $AssignmentFilters = Get-MgBetaDeviceManagementAssignmentFilter -All #Get all Intune Payloads in the tenant $AllPayloads = @() $Workloads = ` "https://graph.microsoft.com/beta/deviceManagement/deviceCompliancePolicies", "https://graph.microsoft.com/beta/deviceManagement/configurationPolicies", "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps", "https://graph.microsoft.com/beta/deviceAppManagement/targetedManagedAppConfigurations", "https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts", "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles", "https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts", "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations", "https://graph.microsoft.com/beta/deviceManagement/groupPolicyConfigurations", "https://graph.microsoft.com/beta/deviceAppManagement/mobileAppConfigurations", "https://graph.microsoft.com/beta/deviceAppManagement/iosManagedAppProtections", "https://graph.microsoft.com/beta/deviceAppManagement/androidManagedAppProtections", "https://graph.microsoft.com/beta/deviceAppManagement/windowsManagedAppProtections", "https://graph.microsoft.com/beta/deviceAppManagement/mdmWindowsInformationProtectionPolicies" $c = 1 foreach ($Workload in $Workloads){ Write-Progress -Activity "Getting all configurations in the tenant.." -Status "Processing $Workload" -PercentComplete $($c*100/$($Workloads.count)) $uri = $Workload $AllPayloads += (Invoke-MgGraphRequest -Method GET -Uri $uri).Value $c++ } #Initialize few variables $AFResults = @() $PSObject = @() $Set = 1 #Loop all Assignment Filters to get payload information. Currently JSON batching supports only 20 requests at a time. So breaking down the total Assignment Filters by set of 20 each and getting the Payload Information and storing the output in $AFResults array. Write-Output "Getting Payload Information of all Assignment Filters..." For ($n = 1; $n -le $AssignmentFilters.count; $n++){ Write-Progress -Activity "Getting Payload Information of all Assignment Filters..." -Status "Processing $n out of $AssignmentFilters.count" -PercentComplete $($n*100/$AssignmentFilters.count) $id = $n - 1 $AssignmentFilterId = $AssignmentFilters[$id].id $PSObject += [PSCustomObject]@{ id = "$id" method = "GET" url = "deviceManagement/assignmentFilters/$($AssignmentFilterId)/payloads" } if (($n -eq $($Set*20)) -or ($n -eq $AssignmentFilters.count)){ $BatchRequestBody = [PSCustomObject]@{requests = $PSObject } $JSONRequests = $BatchRequestBody | ConvertTo-Json -Depth 4 $AFResults += Invoke-MgGraphRequest -Method POST -Uri 'https://graph.microsoft.com/beta/$batch' -Body $JSONRequests -ContentType 'application/json' -ErrorAction Stop $PSObject = @() $Set ++ } } #Create Assignment Filter Summary Report Write-Output "Creating Assignment Filter Summary Report..." $Filters = $AssociatedAssignments = @() For ($n = 1; $n -le $AssignmentFilters.count; $n++){ Write-Progress -Activity "Creating Assignment Filters Summary Report..." -Status "Processing $n out of $AssignmentFilters.count" -PercentComplete $($n*100/$AssignmentFilters.count) $id = $n - 1 $Assignments = ($AFResults.responses | where {$_.id -eq $id}).body.value $AssignmentsCount = $Assignments.count $Filters += [PSCustomObject]@{ Id = $AssignmentFilters[$id].id ManagementType = $AssignmentFilters[$id].AssignmentFilterManagementType DisplayName = $AssignmentFilters[$id].DisplayName Description = $AssignmentFilters[$id].Description CreatedDateTime = $AssignmentFilters[$id].CreatedDateTime LastModifiedDateTime = $AssignmentFilters[$id].LastModifiedDateTime Platform = $AssignmentFilters[$id].Platform RoleScopeTags = [string]$AssignmentFilters[$id].RoleScopeTags -replace " ","," Rule = $AssignmentFilters[$id].Rule AssociatedAssignmentsCount = $AssignmentsCount } If ($AssignmentsCount -gt 0) { Foreach ($Assignment in $Assignments){ $PayloadName = (($AllPayloads | where {$_.id -eq $($Assignment.payloadId)})|select -Unique displayname).displayname If (!($PayloadName)){ $PayloadName = (($AllPayloads | where {$_.id -eq $($Assignment.payloadId)})|select -Unique name).name } $AssociatedAssignments += [PSCustomObject]@{ Id = $AssignmentFilters[$id].id ManagementType = $AssignmentFilters[$id].AssignmentFilterManagementType DisplayName = $AssignmentFilters[$id].DisplayName GroupId = $Assignment.groupId PayloadId = $Assignment.payloadId PayloadName = $PayloadName PayloadType = $Assignment.payloadType IntentType = $Assignment.assignmentFilterType } } } } $ReportOutput += "<h2>Assignment Filters Summary</h2>" $ReportOutput += $Filters | ConvertTo-Html -Fragment $Filters | ConvertTo-Csv -NoTypeInformation > $ReportFolder\AssignmentFilters_Summary_$($Now).csv $ReportOutput += "<h2>Assignment Filters Associated Assignments Summary</h2>" $ReportOutput += $AssociatedAssignments | ConvertTo-Html -Fragment $AssociatedAssignments | ConvertTo-Csv -NoTypeInformation > $ReportFolder\AssignmentFilters_AssociatedAssignments_$($Now).csv ConvertTo-HTML -head $Head -body "$ReportOutput" | Out-File $ReportFolder\AssignmentFilters_Summary_Report_$($Now).htm Invoke-Item $ReportFolder\AssignmentFilters_Summary_Report_$($Now).htm $Stopwatch.Stop() Write-Output "Time Taken for the script execution with batching:`n" $Stopwatch.Elapsed

 

 

 

If you have any questions leave a comment below or reach out to us on X @IntuneSuppTeam! For more sample scripts, check out the Microsoft Intune GitHub repository.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.