Public/Import-CompliancePolicyToIntune.ps1

<#
.SYNOPSIS
    Imports Compliance Policy to Intune.
.DESCRIPTION
    Creates Windows 10 Compliance Policy based on NLBaseline requirements.
    Use -RequireDeviceHealthAttestation and -RequireVBSHardening for stricter DHA/VBS.
.PARAMETER RequireDeviceHealthAttestation
    Enable Early Launch Anti-Malware (ELAM) in compliance. Part of Device Health Attestation.
.PARAMETER RequireVBSHardening
    Require VBS, Memory Integrity (HVCI), and optional Kernel DMA Protection. Some devices may be incompatible.
.PARAMETER OsMinimumVersion
    Minimum OS version for compliance (e.g. 10.0.22621.3880). Default Windows 11 22H2.
.EXAMPLE
    Import-CompliancePolicyToIntune
    Import-CompliancePolicyToIntune -RequireDeviceHealthAttestation -RequireVBSHardening -DryRun
    Import-CompliancePolicyToIntune -OsMinimumVersion "10.0.26100.0"
#>

function Import-CompliancePolicyToIntune {
    [CmdletBinding()]
    param(
        [switch]$DryRun,
        [switch]$RequireDeviceHealthAttestation,
        [switch]$RequireVBSHardening,
        [string]$OsMinimumVersion = "10.0.22621.3880"
    )

    $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
    }

    $elam = $RequireDeviceHealthAttestation.IsPresent
    $vbs = $RequireVBSHardening.IsPresent
    $memInt = $vbs
    $kernelDma = $vbs

    Write-Host "`nImporting Compliance Policy to Intune`n" -ForegroundColor Cyan
    if ($elam) { Write-Host "RequireDeviceHealthAttestation (ELAM): enabled" -ForegroundColor Gray }
    if ($vbs) { Write-Host "RequireVBSHardening (VBS, HVCI, Kernel DMA): enabled" -ForegroundColor Gray }

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

    $body = @{
        "@odata.type" = "#microsoft.graph.windows10CompliancePolicy"
        displayName = "NLBaseline - Compliance Policy"
        description = "Compliance policy for Dutch Baseline for Secure Cloud"
        passwordRequired = $false
        passwordBlockSimple = $false
        passwordRequiredToUnlockFromIdle = $false
        passwordMinutesOfInactivityBeforeLock = $null
        passwordExpirationDays = $null
        passwordMinimumLength = $null
        passwordMinimumCharacterSetCount = $null
        passwordRequiredType = "deviceDefault"
        passwordPreviousPasswordBlockCount = $null
        requireHealthyDeviceReport = $false
        osMinimumVersion = $OsMinimumVersion
        osMaximumVersion = $null
        mobileOsMinimumVersion = $null
        mobileOsMaximumVersion = $null
        earlyLaunchAntiMalwareDriverEnabled = $elam
        bitLockerEnabled = $true
        secureBootEnabled = $true
        codeIntegrityEnabled = $true
        memoryIntegrityEnabled = $memInt
        kernelDmaProtectionEnabled = $kernelDma
        virtualizationBasedSecurityEnabled = $vbs
        firmwareProtectionEnabled = $false
        storageRequireEncryption = $true
        activeFirewallRequired = $true
        defenderEnabled = $true
        defenderVersion = "4.18.24050.7"
        signatureOutOfDate = $true
        rtpEnabled = $true
        antivirusRequired = $true
        antiSpywareRequired = $true
        deviceThreatProtectionEnabled = $false
        deviceThreatProtectionRequiredSecurityLevel = "unavailable"
        configurationManagerComplianceRequired = $false
        tpmRequired = $true
        deviceCompliancePolicyScript = $null
        validOperatingSystemBuildRanges = @()
        scheduledActionsForRule = @(
            @{
                "@odata.type" = "#microsoft.graph.deviceComplianceScheduledActionForRule"
                ruleName = "NonComplianceDeviceEviction"
                scheduledActionConfigurations = @(
                    @{
                        "@odata.type" = "#microsoft.graph.deviceComplianceActionItem"
                        actionType = "block"
                        gracePeriodHours = 24
                        notificationTemplateId = $null
                    }
                )
            }
        )
    }

    if ($DryRun) {
        Write-Host "[DryRun] Would create Compliance Policy (ELAM=$elam, VBS=$vbs)" -ForegroundColor Cyan
        return
    }

    try {
        # Check if policy with same displayName already exists and remove it
        $policyDisplayName = $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 ($body | ConvertTo-Json -Depth 20)
        Write-Host "Created Compliance Policy: $($res.displayName) (id: $($res.id))" -ForegroundColor Green
    }
    catch {
        Write-Error "Failed to create Compliance Policy: $_"
    }
}