Private/New-DefaultNamedLocations.ps1
|
function New-DefaultNamedLocations { <# .SYNOPSIS Create default named locations for Conditional Access .DESCRIPTION Creates default named locations including trusted countries and blocked countries #> [CmdletBinding()] param() try { # Check if connected, if not connect using app registration $context = Get-MgContext -ErrorAction SilentlyContinue if (-not $context -or -not $context.TenantId) { Write-Host "Not connected to Microsoft 365. Connecting..." -ForegroundColor Yellow Write-Host "" $connection = Connect-NLBaselineCA if (-not $connection) { Write-Error "Cannot connect to Microsoft 365. Please check your configuration." return } $context = Get-MgContext } Write-Host "Creating default named locations..." -ForegroundColor Yellow # Trusted countries (EU + trusted partners) $trustedCountries = @( "NL", "BE", "DE", "FR", "GB", "IE", "DK", "SE", "NO", "FI", "AT", "CH", "LU", "ES", "PT", "IT", "GR", "PL", "CZ", "SK", "US", "CA", "AU", "NZ" ) $trustedLocationName = "Trusted Countries - EU and Partners" # Check if location exists using REST API fallback $existingTrusted = $null try { $existingTrusted = Get-MgIdentityConditionalAccessNamedLocation -Filter "DisplayName eq '$trustedLocationName'" -Top 1 -ErrorAction SilentlyContinue } catch { # Use REST API fallback $invokeCmd = Get-Command Invoke-MgGraphRequest -ErrorAction SilentlyContinue if ($invokeCmd) { $allLocations = Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" -ErrorAction Stop $existingTrusted = $allLocations.value | Where-Object { $_.displayName -eq $trustedLocationName } | Select-Object -First 1 } } if (-not $existingTrusted) { Write-Host " Creating: $trustedLocationName" -ForegroundColor Yellow $params = @{ "@odata.type" = "#microsoft.graph.countryNamedLocation" displayName = $trustedLocationName countriesAndRegions = $trustedCountries includeUnknownCountriesAndRegions = $false } try { $trustedLocation = New-MgIdentityConditionalAccessNamedLocation -BodyParameter $params -ErrorAction Stop Write-Host " Created: $trustedLocationName (ID: $($trustedLocation.Id))" -ForegroundColor Green } catch { # Use REST API fallback - ensure correct JSON structure $invokeCmd = Get-Command Invoke-MgGraphRequest -ErrorAction SilentlyContinue if ($invokeCmd) { # Build JSON body with correct property names (camelCase for REST API) $body = @{ "@odata.type" = "#microsoft.graph.countryNamedLocation" displayName = $trustedLocationName countriesAndRegions = $trustedCountries includeUnknownCountriesAndRegions = $false } | ConvertTo-Json -Depth 5 $trustedLocation = Invoke-MgGraphRequest -Method POST ` -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" ` -Body $body ` -ContentType "application/json" ` -ErrorAction Stop Write-Host " Created: $trustedLocationName (ID: $($trustedLocation.id))" -ForegroundColor Green } else { throw "Cannot create named location: $_" } } } else { Write-Host " Already exists: $trustedLocationName" -ForegroundColor Gray } # Blocked countries (high-risk) $blockedCountries = @( "CN", "RU", "KP", "IR", "SY", "CU", "SD", "VE" ) $blockedLocationName = "Blocked Countries - High Risk" # Check if location exists using REST API fallback $existingBlocked = $null try { $existingBlocked = Get-MgIdentityConditionalAccessNamedLocation -Filter "DisplayName eq '$blockedLocationName'" -Top 1 -ErrorAction SilentlyContinue } catch { # Use REST API fallback $invokeCmd = Get-Command Invoke-MgGraphRequest -ErrorAction SilentlyContinue if ($invokeCmd) { if (-not $allLocations) { $allLocations = Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" -ErrorAction Stop } $existingBlocked = $allLocations.value | Where-Object { $_.displayName -eq $blockedLocationName } | Select-Object -First 1 } } if (-not $existingBlocked) { Write-Host " Creating: $blockedLocationName" -ForegroundColor Yellow $params = @{ "@odata.type" = "#microsoft.graph.countryNamedLocation" displayName = $blockedLocationName countriesAndRegions = $blockedCountries includeUnknownCountriesAndRegions = $false } try { $blockedLocation = New-MgIdentityConditionalAccessNamedLocation -BodyParameter $params -ErrorAction Stop Write-Host " Created: $blockedLocationName (ID: $($blockedLocation.Id))" -ForegroundColor Green } catch { # Use REST API fallback - ensure correct JSON structure $invokeCmd = Get-Command Invoke-MgGraphRequest -ErrorAction SilentlyContinue if ($invokeCmd) { # Build JSON body with correct property names (camelCase for REST API) $body = @{ "@odata.type" = "#microsoft.graph.countryNamedLocation" displayName = $blockedLocationName countriesAndRegions = $blockedCountries includeUnknownCountriesAndRegions = $false } | ConvertTo-Json -Depth 5 $blockedLocation = Invoke-MgGraphRequest -Method POST ` -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" ` -Body $body ` -ContentType "application/json" ` -ErrorAction Stop Write-Host " Created: $blockedLocationName (ID: $($blockedLocation.id))" -ForegroundColor Green } else { throw "Cannot create named location: $_" } } } else { Write-Host " Already exists: $blockedLocationName" -ForegroundColor Gray } Write-Host "Default named locations created." -ForegroundColor Green } catch { Write-Error "Failed to create named locations: $_" } } |