Public/Update-NLBaselineDeployments.ps1

<#
.SYNOPSIS
    Updates existing NLBaseline policy assignments based on ring configuration
.DESCRIPTION
    Updates assignments for existing NLBaseline policies without redeploying them
.PARAMETER DryRun
    Show what would be updated without actually updating
.EXAMPLE
    Update-NLBaselineDeployments -DryRun
    Update-NLBaselineDeployments
#>

function Update-NLBaselineDeployments {
    [CmdletBinding()]
    param(
        [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
    }

    # Load ring configuration
    $deploymentPath = Join-Path -Path $workspacePath -ChildPath "Deployment"
    $ringConfigPath = Join-Path -Path $deploymentPath -ChildPath "ring-configuration.json"
    
    if (-not (Test-Path -Path $ringConfigPath)) {
        Write-Error "Ring configuration not found at: $ringConfigPath. Create it first using Deployment Management menu."
        return
    }

    try {
        $ringConfig = Get-Content -Path $ringConfigPath -Raw | ConvertFrom-Json
    }
    catch {
        Write-Error "Failed to parse ring configuration: $_"
        return
    }

    Write-Host "`nUpdating NLBaseline Policy Assignments`n" -ForegroundColor Cyan
    if ($DryRun) {
        Write-Host "[DRY RUN MODE - No changes will be made]" -ForegroundColor Yellow
    }

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

    # Process all rings
    $rings = @("Ring0", "Ring1", "Ring2")
    foreach ($ringName in $rings) {
        if (-not $ringConfig.$ringName) {
            continue
        }

        $ringData = $ringConfig.$ringName
        
        # Get assignments
        $assignments = @()
        if ($ringData.Assignments) {
            foreach ($assignment in $ringData.Assignments) {
                if ($assignment -eq "AllDevices") {
                    $assignments += @{
                        Type = "AllDevices"
                        Target = "AllDevices"
                    }
                }
                else {
                    $assignments += @{
                        Type = "Group"
                        Target = $assignment
                    }
                }
            }
        }

        if ($assignments.Count -eq 0) {
            continue
        }

        Write-Host "`n=== Updating $ringName ===" -ForegroundColor Cyan

        if (-not $DryRun) {
            try {
                # Get all NLBaseline policies
                try {
                    $policiesResponse = Invoke-IntuneGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations"
                    $policies = $policiesResponse.value | Where-Object { $_.displayName -like "NLBaseline - *" }
                    
                    # Handle pagination
                    while ($policiesResponse.'@odata.nextLink') {
                        $policiesResponse = Invoke-IntuneGraphRequest -Method GET -Uri $policiesResponse.'@odata.nextLink'
                        $policies += $policiesResponse.value | Where-Object { $_.displayName -like "NLBaseline - *" }
                    }
                }
                catch {
                    Write-Warning "Could not retrieve device configuration policies: $_"
                    $policies = @()
                }

                try {
                    $complianceResponse = Invoke-IntuneGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/deviceCompliancePolicies"
                    $compliancePolicies = $complianceResponse.value | Where-Object { $_.displayName -like "NLBaseline - *" }
                    
                    # Handle pagination
                    while ($complianceResponse.'@odata.nextLink') {
                        $complianceResponse = Invoke-IntuneGraphRequest -Method GET -Uri $complianceResponse.'@odata.nextLink'
                        $compliancePolicies += $complianceResponse.value | Where-Object { $_.displayName -like "NLBaseline - *" }
                    }
                }
                catch {
                    Write-Warning "Could not retrieve compliance policies: $_"
                    $compliancePolicies = @()
                }

                # Update device configuration policies
                foreach ($policy in $policies) {
                    foreach ($assignment in $assignments) {
                        try {
                            Assign-IntunePolicyToGroup -PolicyId $policy.Id -PolicyType "DeviceConfiguration" -Assignment $assignment -DryRun:$DryRun
                        }
                        catch {
                            Write-Warning "Failed to assign policy $($policy.DisplayName): $_"
                        }
                    }
                }

                # Update compliance policies
                foreach ($policy in $compliancePolicies) {
                    foreach ($assignment in $assignments) {
                        try {
                            Assign-IntunePolicyToGroup -PolicyId $policy.Id -PolicyType "DeviceCompliance" -Assignment $assignment -DryRun:$DryRun
                        }
                        catch {
                            Write-Warning "Failed to assign compliance policy $($policy.DisplayName): $_"
                        }
                    }
                }
            }
            catch {
                Write-Error "Error updating assignments: $_"
            }
        }
        else {
            Write-Host "[DRY RUN] Would update assignments for all NLBaseline policies" -ForegroundColor Cyan
        }
    }

    Write-Host "`nUpdate completed!" -ForegroundColor Green
}