Public/TenantConfiguration/Baseline/Add-DeviceEnrollmentConfiguration.ps1

function Add-DeviceEnrollmentConfiguration {
    param(
        [Parameter(Mandatory)]
        [string]$TenantId,
        [bool]$Hybrid = $false
    )

    try {
        Connect-CustomerGraph -CustomerTenantId $TenantId

        $MgContext = Get-MgContext
        if ($MgContext.Scopes -notcontains "Policy.ReadWrite.MobilityManagement") {
            Write-Host "The current application does not have the required scopes to update device enrollment configuration." -ForegroundColor Yellow
            Write-Host "Re-creating application consent, please wait.."
            Set-SAMConsent -CustomerTenantId $TenantId
            Disconnect-MgGraph | Out-Null
            Connect-CustomerGraph -CustomerTenantId $TenantId
        }

        <#
        This ensures that all users are able to enroll in Intune.
        #>


        $MobileDeviceManagementPolicy = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/policies/mobileDeviceManagementPolicies/0000000a-0000-0000-c000-000000000000")
        if ($MobileDeviceManagementPolicy.appliesTo -ne "all") {
            $MDMParams = @{
                "appliesTo" = "all"
            }
            Invoke-GraphRequest -Method PATCH -Uri "https://graph.microsoft.com/beta/policies/mobileDeviceManagementPolicies/0000000a-0000-0000-c000-000000000000" -Body $MDMParams
            Write-Host "Set MDM user scope to 'all'" -ForegroundColor Green
        }
        else {
            Write-Host "MDM user scope is already set to 'all', not updating.." -ForegroundColor Yellow
        }
    

        $DeviceEnrollmentConfigurations = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceEnrollmentConfigurations").value
        
        # Windows Hello for Business
        $DeviceEnrollmentConfigurationsFiles = Get-ChildItem -Path "$PSScriptRoot\DeviceEnrollmentConfigurations" -Filter *.json
        foreach ($DeviceEnrollmentConfigurationsFile in $DeviceEnrollmentConfigurationsFiles) {
            $DeviceEnrollmentConfiguration = Get-Content -Path $DeviceEnrollmentConfigurationsFile.FullName | ConvertFrom-Json -AsHashtable -Depth 100
            
            if ($DeviceEnrollmentConfiguration.Id -like "*_DefaultWindowsHelloForBusiness") {
                $DeviceEnrollmentConfigurationId = ($DeviceEnrollmentConfigurations | Where-Object { $_.Id -like "*_DefaultWindowsHelloForBusiness" }).Id
                Update-MgDeviceManagementDeviceEnrollmentConfiguration -DeviceEnrollmentConfigurationId $DeviceEnrollmentConfigurationId -AdditionalProperties $DeviceEnrollmentConfiguration.AdditionalProperties
                Write-Host "Updated Windows Hello for Business Enrollment Configuration" -ForegroundColor Green
            }
        }

        # Windows Autopilot
        $WindowsAutopilotDeploymentProfiles = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles").value

        $WindowsAutopilotDeploymentProfileFiles = Get-ChildItem -Path "$PSScriptRoot\WindowsAutopilotDeploymentProfiles" -Filter *.json
        $WindowsAutopilotDeploymentProfileFilesParsed = New-Object System.Collections.ArrayList

        foreach ($WindowsAutopilotDeploymentProfileFile in $WindowsAutopilotDeploymentProfileFiles) {
            $WindowsAutopilotDeploymentProfile = Get-Content -Path $WindowsAutopilotDeploymentProfileFile.FullName | ConvertFrom-Json -AsHashtable -Depth 100
            $WindowsAutopilotDeploymentProfileFilesParsed.Add($WindowsAutopilotDeploymentProfile) | Out-Null
        }

        # Select the Windows Autopilot deployment profiles to be added using Out-ConsoleGridView showing only displayName and description, but the resulting object should contain all properties
        $SelectedWindowsAutopilotDeploymentProfiles = $WindowsAutopilotDeploymentProfileFilesParsed | Select-Object displayName, description | Out-ConsoleGridView -Title "Windows Autopilot Deployment Profiles to be added"
        $SelectedWindowsAutopilotDeploymentProfilesArray = @()
        $SelectedWindowsAutopilotDeploymentProfilesArray = $WindowsAutopilotDeploymentProfileFilesParsed | Where-Object { $_.displayName -in $SelectedWindowsAutopilotDeploymentProfiles.displayName }

        foreach ($SelectedWindowsAutopilotDeploymentProfile in $SelectedWindowsAutopilotDeploymentProfilesArray) {
            if ($WindowsAutopilotDeploymentProfiles.displayName -contains $SelectedWindowsAutopilotDeploymentProfile.displayName) {
                Write-Host "Windows Autopilot deployment profile '$($SelectedWindowsAutopilotDeploymentProfile.displayName)' already exists, not creating.." -ForegroundColor Yellow
            }
            else {
                Write-Host "Creating Windows Autopilot deployment profile '$($SelectedWindowsAutopilotDeploymentProfile.displayName)'.."
                $CreatedProfile = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles" -Body $SelectedWindowsAutopilotDeploymentProfile
                Write-Host "Created Windows Autopilot deployment profile '$($CreatedProfile.displayName)'." -ForegroundColor Green
                
                # Check if the profile contains a "target" property, if so, assign the profile to the target - if the target is a group create the group if it does not exist
                if ($SelectedWindowsAutopilotDeploymentProfile.target -ne $null) {
                    $TargetType = $SelectedWindowsAutopilotDeploymentProfile.target."@odata.type"
                    switch ($TargetType) {
                        "#microsoft.graph.groupAssignmentTarget" {
                            $Group = Get-MgGroup -Filter "displayName eq '$($SelectedWindowsAutopilotDeploymentProfile.target.groupId)'"
                            if ($Group -eq $null) {
                                Write-Host "Group '$($SelectedWindowsAutopilotDeploymentProfile.target.groupId)' does not exist, creating.." -ForegroundColor Yellow
                                $Group = New-MgGroup -DisplayName $SelectedWindowsAutopilotDeploymentProfile.target.groupId -MailEnabled:$false -MailNickname $SelectedWindowsAutopilotDeploymentProfile.target.groupId -SecurityEnabled:$true
                                Write-Host "Created group '$($SelectedWindowsAutopilotDeploymentProfile.target.groupId)'." -ForegroundColor Green
                            }
                            $SelectedWindowsAutopilotDeploymentProfile.target.groupId = $Group.Id
                        }
                    }
                    $Target = @{
                        target = $SelectedWindowsAutopilotDeploymentProfile.target
                    }
                    $AssignedProfile = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/$($CreatedProfile.id)/assignments" -Body $Target
                    Write-Host "Assigned Windows Autopilot deployment profile '$($CreatedProfile.displayName)' to $($TargetType)." -ForegroundColor Green
                }
            }
        }


        # Windows Autopilot Enrollment Status Page
        $EnrollmentStatusPageFiles = Get-ChildItem -Path "$PSScriptRoot\EnrollmentStatusPages" -Filter *.json
        $EnrollmentStatusPageFilesParsed = New-Object System.Collections.ArrayList

        foreach ($EnrollmentStatusPageFile in $EnrollmentStatusPageFiles) {
            $EnrollmentStatusPage = Get-Content -Path $EnrollmentStatusPageFile.FullName | ConvertFrom-Json -AsHashtable -Depth 100
            $EnrollmentStatusPageFilesParsed.Add($EnrollmentStatusPage) | Out-Null
        }

        # Select the Windows Autopilot deployment profiles to be added using Out-ConsoleGridView showing only displayName and description, but the resulting object should contain all properties
        $SelectedEnrollmentStatusPages = $EnrollmentStatusPageFilesParsed | Select-Object displayName, description | Out-ConsoleGridView -Title "Windows Autopilot Deployment Profiles to be added"
        $SelectedEnrollmentStatusPagesArray = @()
        $SelectedEnrollmentStatusPagesArray = $EnrollmentStatusPageFilesParsed | Where-Object { $_.displayName -in $SelectedEnrollmentStatusPages.displayName }




        foreach ($SelectedEnrollmentStatusPage in $SelectedEnrollmentStatusPagesArray) {
            if ($DeviceEnrollmentConfigurations.displayName -contains $SelectedEnrollmentStatusPage.displayName) {
                Write-Host "Enrollment status page '$($EnrollmentStatusPage.displayName)' already exists, not creating.." -ForegroundColor Yellow
            }
            else {
                # If enrollmentConfigurationAssignments property exists, copy it to a variable and remove it from the object
                $EnrollmentConfigurationAssignments = $SelectedEnrollmentStatusPage.enrollmentConfigurationAssignments
                $SelectedEnrollmentStatusPage.Remove("enrollmentConfigurationAssignments")


                $CreatedEnrollmentStatusPage = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceEnrollmentConfigurations" -Body $SelectedEnrollmentStatusPage
                Write-Host "Created enrollment status page '$($CreatedEnrollmentStatusPage.displayName)'." -ForegroundColor Green

                # If enrollmentConfigurationAssignments property exists, assign the enrollment status page to the target - if the target is a group create the group if it does not exist
                if ($EnrollmentConfigurationAssignments -ne $null) {
                    $TargetType = $EnrollmentConfigurationAssignments.target."@odata.type"
                    switch ($TargetType) {
                        "#microsoft.graph.groupAssignmentTarget" {
                            $Group = Get-MgGroup -Filter "displayName eq '$($EnrollmentConfigurationAssignments.target.groupId)'"
                            if ($Group -eq $null) {
                                Write-Host "Group '$($EnrollmentConfigurationAssignments.target.groupId)' does not exist, creating.." -ForegroundColor Yellow
                                $Group = New-MgGroup -DisplayName $EnrollmentConfigurationAssignments.target.groupId -MailEnabled:$false -MailNickname $EnrollmentConfigurationAssignments.target.groupId -SecurityEnabled:$true
                                Write-Host "Created group '$($EnrollmentConfigurationAssignments.target.groupId)'." -ForegroundColor Green
                            }
                            $EnrollmentConfigurationAssignments.target.groupId = $Group.Id
                        }
                    }
                    $EnrollmentConfigurationAssignments = @{
                        enrollmentConfigurationAssignments = @($EnrollmentConfigurationAssignments)
                    }
                    $AssignedEnrollmentStatusPage = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceEnrollmentConfigurations/$($CreatedEnrollmentStatusPage.id)/assign" -Body $EnrollmentConfigurationAssignments
                    Write-Host "Assigned enrollment status page '$($CreatedEnrollmentStatusPage.displayName)'." -ForegroundColor Green
                }
            }
        }

    }
    catch {
        throw "Failed to update Device enrollment configuration: $_"
    }
}