Generated with AI

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:

  1. Run the script against the production group
  2. Export all assignments
  3. Use the output as a reference
  4. 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.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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