Public/Set-NSPConditionalAccessHomeCountryGroup.ps1

function Set-NSPConditionalAccessHomeCountryGroup {
    <#
    .SYNOPSIS
        Records permanent home countries for existing groups, offline, for the next reviewed deployment.
    .DESCRIPTION
        HomeCountry remains the default for everyone else. Each entry has a stable two-digit key,
        a name, one or more countries, and existing group IDs (synced and cloud companions can
        share an entry). Supply the complete set on an update. No membership or tenant changes.
        New home policies start report-only. Promote the policy, then re-plan to exempt its groups
        from the default baseline. Travel takes over only while its own policy is enforced.
        Put each person in one home entry; multiple home policies intersect, rather than combine.
    .EXAMPLE
        Set-NSPConditionalAccessHomeCountryGroup -TenantProfile $profilePath -Key '01' -Name 'Japan-based users' -Country US,JP -GroupId $groupId
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][string]$TenantProfile,
        [Parameter(Mandatory)][ValidatePattern('^\d{2}$')][string]$Key,
        [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$Name,
        [Parameter(Mandatory)][ValidateNotNullOrEmpty()][ValidatePattern('^[A-Za-z]{2}$')][string[]]$Country,
        [Parameter(Mandatory)][ValidateNotNullOrEmpty()][guid[]]$GroupId,
        [string[]]$GroupLabel = @()
    )
    if (@($GroupId | Where-Object { $_ -eq [guid]::Empty }).Count) { throw 'An empty group ID is not allowed.' }
    $content = Get-Content -LiteralPath $TenantProfile -Raw | ConvertFrom-Json
    if (-not $content.PSObject.Properties['HomeCountryGroups']) { $content | Add-Member -NotePropertyName HomeCountryGroups -NotePropertyValue ([pscustomobject]@{}) }
    $previous = $content.HomeCountryGroups.PSObject.Properties[$Key]
    if ($previous -and $previous.Value.RetireRequested) { throw 'This home country group is retiring. Finish its retirement before configuring it again.' }
    if ($previous -and ((@($previous.Value.Ids | Sort-Object) -join ',') -ne (@($GroupId | ForEach-Object { $_.ToString() } | Sort-Object) -join ','))) {
        throw 'Changing bound groups needs retirement first, so the old baseline exemptions are removed safely.'
    }
    $entry = [pscustomobject]@{
        Name = $Name
        Countries = @($Country | ForEach-Object { $_.ToUpperInvariant() } | Select-Object -Unique)
        Ids = @($GroupId | ForEach-Object { $_.ToString() } | Select-Object -Unique)
        Labels = @($GroupLabel)
        RetireRequested = $false
    }
    $content.HomeCountryGroups | Add-Member -MemberType NoteProperty -Name $Key -Value $entry -Force
    $null = @(Get-NSPConditionalAccessHomeCountryEntry $content)
    if ($PSCmdlet.ShouldProcess($TenantProfile, "Set home countries for $Name ($Key)")) { Save-NSPConditionalAccessJson $content -Path $TenantProfile }
    Get-NSPConditionalAccessHomeCountryGroup $content | Where-Object Key -eq $Key
}