Managing Microsoft Intune environments often becomes complex as configurations, applications, and policies grow over time. This is especially true when working with multiple environments—for example, a production Autopilot setup and a separate test environment.
One common challenge is understanding exactly what is assigned to a specific Azure AD group and replicating that configuration elsewhere.
In this article, we’ll walk through a practical PowerShell script that allows you to extract all Intune assignments linked to a specific Azure Active Directory group. This is extremely useful for auditing, documentation, and environment replication.
Why This Script Is Useful
In real-world scenarios, you might have:
- A production Autopilot environment with a dynamic Azure AD group (based on device tags)
- A need to create a test or staging environment
- The requirement to replicate all assignments (apps, policies, scripts, etc.)
Manually recreating these assignments is time-consuming and error-prone.
With this script, you can:
- Export all assignments tied to a group
- Compare configurations between environments (e.g., using Notepad++)
- Quickly rebuild or mirror an environment
What the Script Does
The script connects to Microsoft Graph and retrieves all Intune-related assignments for a given Azure AD group, including:
- Device Configuration policies
- Settings Catalog policies
- Administrative Templates
- Compliance Policies
- Applications
- PowerShell Scripts
- Remediation Scripts
- Autopilot Profiles
- Enrollment Status Page (ESP)
- Security Baselines
It outputs the results into a structured log file, clearly indicating:
+Included assignments-Excluded assignments
How It Works
1. Configuration
You simply define the Azure AD group name:
$aadGroupName = ""
The script will automatically generate a log file based on the group name.
2. Microsoft Graph Connection
The script uses the Microsoft Graph PowerShell module and connects with the required permissions:
Connect-MgGraph -Scopes `
DeviceManagementConfiguration.Read.All, `
DeviceManagementApps.Read.All, `
DeviceManagementScripts.Read.All
3. Group Lookup
It retrieves the Azure AD group using its display name:
4. Assignment Extraction
The core logic iterates through all Intune workloads and checks assignments against the selected group.
It supports both:
- Legacy assignment model (groupAssignments)
- Modern assignment model (used by Settings Catalog and newer policies)
5. Output
The script logs everything into a .txt file, grouped by category, making it easy to:
- Read
- Compare
- Share
Example Use Case: Cloning an Autopilot Environment
Imagine you have:
- A production Azure AD dynamic group targeting devices with a specific Autopilot tag
- Multiple policies, apps, and configurations assigned to it
Now you want to create a test environment.
Without the Script:
You would need to manually:
- Identify every assignment
- Recreate each one
- Risk missing configurations
With the Script:
- Run the script against the production group
- Export all assignments
- Use the output as a reference
- Recreate or automate assignments for the test group
You can even compare outputs from different environments using tools like Notepad++.
The Script
Here is the full script:
# =================== CONFIGURATION ===================
$aadGroupName = ""
$sanitizedGroupName = ($aadGroupName -replace '[\\/:*?"<>|]', '_')
$logFile = Join-Path -Path $PSScriptRoot -ChildPath "$sanitizedGroupName.txt"
# =================== FUNCTIONS ===================
function Write-Entry {
param($topic, $value)
Write-Host $topic -NoNewline -ForegroundColor White
Write-Host ": " -NoNewline
Write-Host $value -ForegroundColor Yellow
}
function Get-GraphCollectionPaged {
param([Parameter(Mandatory)][string]$Endpoint)
$items = @()
$uri = "https://graph.microsoft.com/beta/$Endpoint"
do {
$resp = Invoke-MgGraphRequest -Uri $uri -Method GET
if ($resp.value) { $items += $resp.value }
$uri = $resp.'@odata.nextLink'
} while ($uri)
return $items
}
function Get-GraphSingle {
param([Parameter(Mandatory)][string]$Endpoint)
Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/beta/$Endpoint" -Method GET
}
function Get-GroupPerName {
param($groupName)
$groups = Get-GraphCollectionPaged -Endpoint "groups?`$filter=displayName eq '$groupName'"
if (-not $groups) { return $null }
return $groups | Select-Object -First 1
}
function Get-Topic {
param($headline, $groupId, $uri, $type, $assignType)
Write-Host ""
Write-Host $headline -ForegroundColor Yellow
Write-Host "------------------------------"
$found = Get-GroupAssignments $groupId $uri $type $assignType
if (-not $found) {
Write-Host "No Assignment" -ForegroundColor Green
}
Write-Host "------------------------------"
}
function Get-GroupAssignments {
param($groupId, $uri, $type, $assignType)
$hasAssignment = $false
$items = Get-GraphCollectionPaged -Endpoint "$uri/$type"
foreach ($item in $items) {
$name = $item.displayName ?? $item.name ?? $item.id
$assignments = (Get-GraphSingle `
-Endpoint "$uri/$type/$($item.id)/$assignType").value
foreach ($assignment in $assignments) {
# ========= DEVICE CONFIGURATION (legacy)
if ($assignType -eq "groupAssignments") {
if ($assignment.targetGroupId -eq $groupId -and -not $assignment.excludeGroup) {
Write-Host "+ $name"
$hasAssignment = $true
}
elseif ($assignment.targetGroupId -eq $groupId -and $assignment.excludeGroup) {
Write-Host "- $name"
$hasAssignment = $true
}
continue
}
# ========= MODERN MODEL (including Settings Catalog)
$target = $assignment.target
if (-not $target) { continue }
$t = $target.'@odata.type'
$tg = $target.groupId
if ($t -eq '#microsoft.graph.groupAssignmentTarget' -and $tg -eq $groupId) {
Write-Host "+ $name"
$hasAssignment = $true
}
elseif ($t -eq '#microsoft.graph.exclusionGroupAssignmentTarget' -and $tg -eq $groupId) {
Write-Host "- $name"
$hasAssignment = $true
}
}
}
return $hasAssignment
}
# =================== START ===================
Import-Module Microsoft.Graph.Authentication -ErrorAction SilentlyContinue
Connect-MgGraph -Scopes `
DeviceManagementConfiguration.Read.All, `
DeviceManagementApps.Read.All, `
DeviceManagementScripts.Read.All
$group = Get-GroupPerName $aadGroupName
if (-not $group) {
Write-Host "Group '$aadGroupName' not found" -ForegroundColor Red
exit
}
Start-Transcript -Path $logFile -Force
Write-Host "------------------------------"
Write-Host "Group Info" -ForegroundColor Yellow
Write-Host "------------------------------"
Write-Entry "Name" $group.displayName
Write-Entry "Id" $group.id
Write-Host "------------------------------"
Get-Topic "Device Configuration" $group.id "deviceManagement" "deviceConfigurations" "groupAssignments"
Get-Topic "Settings Catalog" $group.id "deviceManagement" "configurationPolicies" "assignments"
Get-Topic "Administrative Templates" $group.id "deviceManagement" "groupPolicyConfigurations" "assignments"
Get-Topic "Device Compliance Policies" $group.id "deviceManagement" "deviceCompliancePolicies" "assignments"
Get-Topic "Apps" $group.id "deviceAppManagement" "mobileApps" "assignments"
Get-Topic "Scripts" $group.id "deviceManagement" "deviceManagementScripts" "assignments"
Get-Topic "Remediation Scripts" $group.id "deviceManagement" "deviceHealthScripts" "assignments"
Get-Topic "Autopilot Profiles" $group.id "deviceManagement" "windowsAutopilotDeploymentProfiles" "assignments"
Get-Topic "Enrollment Status Page" $group.id "deviceManagement" "deviceEnrollmentConfigurations" "assignments"
Get-Topic "Security Baselines" $group.id "deviceManagement" "intents" "assignments"
Stop-Transcript
Final Thoughts
This script gives you a clear and structured view of all Intune assignments tied to a specific Azure AD group. Whether you’re auditing, troubleshooting, or replicating environments, it can save a significant amount of time.
If you regularly work with Autopilot or multiple Intune environments, this becomes an essential tool in your toolkit.