Public/Export-NLBaselineFromIntune.ps1

<#
.SYNOPSIS
    Exports Intune Device Configuration policies (NLBaseline) to JSON.
.DESCRIPTION
    Lists windows10CustomConfiguration policies with display name prefix "NLBaseline - ",
    exports all OMA settings to JSON (displayName, description, exportedAt, omaSettings) in the workspace Intune\Exports folder.
.PARAMETER PolicyName
    Optional. Export only policies whose display name contains this string.
.EXAMPLE
    Export-NLBaselineFromIntune
#>

function Export-NLBaselineFromIntune {
    [CmdletBinding()]
    param(
        [string]$PolicyName
    )

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

    $connected = Connect-Intune -Config $config
    if (-not $connected) {
        Write-Error "Failed to connect to Microsoft Graph. Check App Registration and API permissions."
        return
    }

    $exportsDir = Join-Path -Path $workspacePath -ChildPath "Intune\Exports"
    if (-not (Test-Path -Path $exportsDir)) {
        New-Item -ItemType Directory -Path $exportsDir -Force | Out-Null
    }

    $configs = @()
    $nextLink = "https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations"
    do {
        $response = Invoke-IntuneGraphRequest -Method GET -Uri $nextLink
        if ($response.value) { $configs += $response.value }
        $nextLink = $response.'@odata.nextLink'
    } while ($nextLink)

    $filtered = $configs | Where-Object {
        $_.'@odata.type' -eq '#microsoft.graph.windows10CustomConfiguration' -and
        $_.displayName -like 'NLBaseline - *'
    }
    if ($PolicyName) {
        $filtered = $filtered | Where-Object { $_.displayName -like "*$PolicyName*" }
    }

    $exported = 0
    foreach ($pc in $filtered) {
        $oma = $pc.omaSettings
        if (-not $oma) { continue }
        $oma = @($oma)
        if ($oma.Count -eq 0) { continue }

        $omaList = [System.Collections.ArrayList]::new()
        foreach ($o in $oma) {
            $entry = @{
                "@odata.type" = $o.'@odata.type'
                omaUri        = $o.omaUri
                value         = $o.value
                displayName   = $o.displayName
                description   = $o.description
            }
            [void]$omaList.Add($entry)
        }

        $name = ($pc.displayName -replace 'NLBaseline - ', '') -replace ' \(Part \d+\)', ''
        $name = $name -replace '[^a-zA-Z0-9_-]', '_'
        if ([string]::IsNullOrEmpty($name)) {
            $name = "Exported_$($pc.id)"
        }
        $outPath = Join-Path -Path $exportsDir -ChildPath "export_${name}_$(Get-Date -Format 'yyyyMMdd_HHmmss').json"
        $exportObj = @{
            displayName = $pc.displayName
            description = $pc.description
            exportedAt  = (Get-Date -Format 'o')
            omaSettings = @($omaList)
        }
        $exportObj | ConvertTo-Json -Depth 10 | Set-Content -Path $outPath -Force
        Write-Host "Exported: $($pc.displayName) -> $outPath ($($omaList.Count) settings)" -ForegroundColor Green
        $exported++
    }

    if ($exported -eq 0) {
        Write-Warning "No NLBaseline policies found to export."
    }
    else {
        Write-Host "Export complete. $exported policy/policies exported to $exportsDir" -ForegroundColor Cyan
    }
}