Public/Import-MultiPlatformComplianceToIntune.ps1

<#
.SYNOPSIS
    Imports multi-platform Compliance Policies to Intune (iOS, macOS, Android).
.DESCRIPTION
    Creates secure compliance policies for iOS, macOS, and Android platforms.
    Note: Linux compliance policies are not supported by Microsoft Graph API.
.EXAMPLE
    Import-MultiPlatformComplianceToIntune -Platform iOS
#>

function Import-MultiPlatformComplianceToIntune {
    [CmdletBinding()]
    param(
        [ValidateSet('iOS', 'macOS', 'Android', 'All')]
        [string]$Platform = 'All',
        [switch]$DryRun
    )

    $ErrorActionPreference = "Stop"
    $workspacePath = Get-WorkspacePath
    if (-not $workspacePath) {
        Write-Error "Workspace not configured. Run Initialize-NLBaseline first."
        return
    }

    $config = Get-Config -WorkspacePath $workspacePath
    if (-not $config -or [string]::IsNullOrEmpty($config.AppRegistration.ClientId) -or [string]::IsNullOrEmpty($config.AppRegistration.ClientSecret) -or [string]::IsNullOrEmpty($config.AppRegistration.TenantId)) {
        Write-Error "App Registration not configured in config.json."
        return
    }

    Write-Host "`nImporting Multi-Platform Compliance Policies to Intune`n" -ForegroundColor Cyan

    if (-not $DryRun) {
        $connected = Connect-Intune -Config $config
        if (-not $connected) {
            Write-Error "Failed to connect to Microsoft Graph."
            return
        }
    }

    $policies = @()

    if ($Platform -eq 'iOS' -or $Platform -eq 'All') {
        $policies += @{
            Platform = 'iOS'
            Body = @{
                "@odata.type" = "#microsoft.graph.iosCompliancePolicy"
                displayName = "NLBaseline - iOS Compliance Policy"
                description = "Secure iOS compliance policy for Dutch Baseline"
                passwordRequired = $true
                passwordBlockSimple = $true
                passwordMinimumLength = 8
                passwordMinimumCharacterSetCount = 3
                passwordRequiredType = "alphanumeric"
                passwordExpirationDays = 90
                passwordPreviousPasswordBlockCount = 5
                passwordMinutesOfInactivityBeforeLock = 5
                passwordRequiredToUnlockFromIdle = $true
                osMinimumVersion = "15.0"
                osMaximumVersion = $null
                securityBlockJailbrokenDevices = $true
                deviceThreatProtectionEnabled = $true
                deviceThreatProtectionRequiredSecurityLevel = "secured"
                advancedThreatProtectionRequiredSecurityLevel = "secured"
                storageRequireEncryption = $true
                restrictedApps = @()
                managedEmailProfileRequired = $false
                scheduledActionsForRule = @(
                    @{
                        "@odata.type" = "#microsoft.graph.deviceComplianceScheduledActionForRule"
                        ruleName = "NonComplianceDeviceEviction"
                        scheduledActionConfigurations = @(
                            @{
                                "@odata.type" = "#microsoft.graph.deviceComplianceActionItem"
                                actionType = "block"
                                gracePeriodHours = 24
                                notificationTemplateId = $null
                            }
                        )
                    }
                )
            }
        }
    }

    if ($Platform -eq 'macOS' -or $Platform -eq 'All') {
        $policies += @{
            Platform = 'macOS'
            Body = @{
                "@odata.type" = "#microsoft.graph.macOSCompliancePolicy"
                displayName = "NLBaseline - macOS Compliance Policy"
                description = "Secure macOS compliance policy for Dutch Baseline"
                passwordRequired = $true
                passwordBlockSimple = $true
                passwordMinimumLength = 8
                passwordMinimumCharacterSetCount = 3
                passwordRequiredType = "alphanumeric"
                passwordExpirationDays = 90
                passwordPreviousPasswordBlockCount = 5
                passwordMinutesOfInactivityBeforeLock = 15
                passwordRequiredToUnlockFromIdle = $true
                osMinimumVersion = "12.0"
                osMaximumVersion = $null
                systemIntegrityProtectionEnabled = $true
                deviceThreatProtectionEnabled = $true
                deviceThreatProtectionRequiredSecurityLevel = "secured"
                storageRequireEncryption = $true
                firewallEnabled = $true
                firewallBlockAllIncoming = $false
                firewallEnableStealthMode = $true
                scheduledActionsForRule = @(
                    @{
                        "@odata.type" = "#microsoft.graph.deviceComplianceScheduledActionForRule"
                        ruleName = "NonComplianceDeviceEviction"
                        scheduledActionConfigurations = @(
                            @{
                                "@odata.type" = "#microsoft.graph.deviceComplianceActionItem"
                                actionType = "block"
                                gracePeriodHours = 24
                                notificationTemplateId = $null
                            }
                        )
                    }
                )
            }
        }
    }

    # Linux compliance policy is not supported by Microsoft Graph API
    # Skip Linux completely - Microsoft Graph doesn't support linuxCompliancePolicy
    # Note: Linux is skipped automatically when Platform='All' since we don't add it to $policies

    if ($Platform -eq 'Android' -or $Platform -eq 'All') {
        $policies += @{
            Platform = 'Android'
            Body = @{
                "@odata.type" = "#microsoft.graph.androidCompliancePolicy"
                displayName = "NLBaseline - Android Compliance Policy"
                description = "Secure Android compliance policy for Dutch Baseline"
                passwordRequired = $true
                passwordBlockSimple = $true
                passwordMinimumLength = 8
                passwordMinimumCharacterSetCount = 3
                passwordRequiredType = "deviceDefault"
                passwordExpirationDays = 90
                passwordPreviousPasswordBlockCount = 5
                passwordMinutesOfInactivityBeforeLock = 5
                passwordRequiredToUnlockFromIdle = $true
                osMinimumVersion = "8.0"
                osMaximumVersion = $null
                securityRequireJailbreakOrRoot = $false
                securityRequireSafetyNetAttestationBasicIntegrity = $true
                securityRequireSafetyNetAttestationCertifiedDevice = $true
                securityRequireGooglePlayServices = $true
                securityRequireUpToDateSecurityProviders = $true
                securityRequireCompanyPortalAppIntegrity = $true
                deviceThreatProtectionEnabled = $true
                deviceThreatProtectionRequiredSecurityLevel = "secured"
                storageRequireEncryption = $true
                securityRequireIntuneAppIntegrity = $true
                scheduledActionsForRule = @(
                    @{
                        "@odata.type" = "#microsoft.graph.deviceComplianceScheduledActionForRule"
                        ruleName = "NonComplianceDeviceEviction"
                        scheduledActionConfigurations = @(
                            @{
                                "@odata.type" = "#microsoft.graph.deviceComplianceActionItem"
                                actionType = "block"
                                gracePeriodHours = 24
                                notificationTemplateId = $null
                            }
                        )
                    }
                )
            }
        }
    }

    $created = @()
    $failed = @()

    foreach ($pol in $policies) {
        if ($DryRun) {
            Write-Host "[DryRun] Would create: $($pol.Platform) Compliance Policy" -ForegroundColor Cyan
            $created += $pol.Platform
            continue
        }

        try {
            # Check if policy with same displayName already exists and remove it
            $policyDisplayName = $pol.Body.displayName
            $removed = Remove-IntunePolicyByDisplayName -DisplayName $policyDisplayName -PolicyType "Compliance"
            if ($removed) {
                Write-Host "Removed existing policy: $policyDisplayName" -ForegroundColor Yellow
            }

            $res = Invoke-IntuneGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/deviceManagement/deviceCompliancePolicies" -Body ($pol.Body | ConvertTo-Json -Depth 20)
            $created += $pol.Platform
            Write-Host "Created: $($pol.Platform) Compliance Policy (id: $($res.id))" -ForegroundColor Green
        }
        catch {
            $failed += "$($pol.Platform): $_"
            Write-Warning "Failed to create $($pol.Platform) Compliance Policy: $_"
        }
    }

    Write-Host "`nImport complete. Created: $($created.Count), Failed: $($failed.Count)" -ForegroundColor Cyan
}