Dit regelen configureert voorwaardelijke toegang geo blocking via Microsoft Intune apparaat configuratie beleid of compliance policies om Windows endpoints te beveiligen volgens security best practices.
Vereisten
m365
Implementatie
Gebruik PowerShell-script conditional-access-geo-blocking.ps1 (functie Invoke-Monitoring) – Monitoren.
monitoring
Gebruik PowerShell-script conditional-access-geo-blocking.ps1 (functie Invoke-Monitoring) – Controleren.
Remediatie
Gebruik PowerShell-script conditional-access-geo-blocking.ps1 (functie Invoke-Remediation) – Herstellen.
Compliance en Auditing
Beleid documentatie
Compliance & Frameworks
CIS M365: Control 18.9.19.2 (L1) - CIS Security Benchmark aanbevelingen
BIO: 16.01 - BIO Baseline Informatiebeveiliging Overheid - 16.01 - Gebeurtenissen logging en audittrails
ISO 27001:2022: A.12.4.1 - ISO 27001:2022 - Gebeurtenissen logging en audittrails
Automation
Gebruik het onderstaande PowerShell script om deze security control te monitoren en te implementeren. Het script bevat functies voor zowel monitoring (-Monitoring) als remediation (-Remediation).
PowerShell
<#
.SYNOPSIS
Conditional Access - Geographic Blocking
.DESCRIPTION
Implements geo-blocking via Conditional Access to block access from specific countries.
Helps prevent unauthorized access from high-risk locations.
.NOTES
Filename: conditional-access-geo-blocking.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.PARAMETER BlockedCountries
Array of ISO 3166 country codes to block (e.g., @("RU","CN","KP"))
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Monitoring
Check if geo-blocking policies exist
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Remediation -BlockedCountries @("RU","CN","KP")
Create policy blocking Russia, China, North Korea
#>#Requires -Version 5.1#Requires -Modules Microsoft.Graph
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[switch]$Monitoring,
[Parameter(Mandatory = $false)]
[switch]$Remediation,
[switch]$Revert,
[switch]$WhatIf,
[Parameter(Mandatory = $false)]
[string[]]$BlockedCountries = @("RU", "CN", "KP", "IR", "SY")
)
$ErrorActionPreference = 'Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Conditional Access - Geographic Blocking" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
function Invoke-Revert {
Write-Host "`nReverting configuration..." -ForegroundColor Cyan
try {
if ($WhatIf) {
Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow
return
}
# Revert implementation - requires manual implementation per controlWrite-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <#
.SYNOPSIS
Conditional Access - Geographic Blocking
.DESCRIPTION
Implements geo-blocking via Conditional Access to block access from specific countries.
Helps prevent unauthorized access from high-risk locations.
.NOTES
Filename: conditional-access-geo-blocking.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.PARAMETER BlockedCountries
Array of ISO 3166 country codes to block (e.g., @("RU","CN","KP"))
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Monitoring
Check if geo-blocking policies exist
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Remediation -BlockedCountries @("RU","CN","KP")
Create policy blocking Russia, China, North Korea
#>#Requires -Version 5.1#Requires -Modules Microsoft.Graph
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[switch]$Monitoring,
[Parameter(Mandatory=$false)]
[switch]$Remediation,
[switch]$Revert,
[switch]$WhatIf,
[Parameter(Mandatory=$false)]
[string[]]$BlockedCountries = @("RU", "CN", "KP", "IR", "SY")
)
$ErrorActionPreference = 'Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Conditional Access - Geographic Blocking" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.Read.All" -ErrorAction Stop -NoWelcome
Write-Host "Checking for geo-blocking policies..." -ForegroundColor Gray
$policies = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies"
$result = @{
isCompliant = $false
geoBlockingPolicies = 0
policyNames = @()
blockedCountries = @()
}
foreach ($policy in $policies.value) {
if ($policy.state -ne 'enabled') { continue }
# Check if policy blocks based on locationif ($policy.conditions.locations.excludedLocations) {
$hasCountryBlocking = $policy.grantControls.builtInControls -contains 'block'
if ($hasCountryBlocking) {
$result.geoBlockingPolicies++
$result.policyNames += $policy.displayName
$result.isCompliant = $trueWrite-Host " [OK] GEO-BLOCKING POLICY: $($policy.displayName)" -ForegroundColor Green
}
}
}
Write-Host "`n Geo-blocking policies found: $($result.geoBlockingPolicies)" -ForegroundColor $(
if ($result.geoBlockingPolicies -gt 0) { 'Green' } else { 'Yellow' }
)
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT - Geo-blocking is configured" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n⚠️ NO GEO-BLOCKING FOUND" -ForegroundColor Yellow
Write-Host "Consider blocking high-risk countries" -ForegroundColor Cyan
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess" -ErrorAction Stop -NoWelcome
Write-Host "Creating geo-blocking policy..." -ForegroundColor Gray
Write-Host "Countries to block: $($BlockedCountries -join ', ')" -ForegroundColor Yellow
# Get named locations firstWrite-Host "Getting existing named locations..." -ForegroundColor Gray
$namedLocations = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations"
# Create named location for blocked countries if not exists$blockedLocationName = "Blocked Countries - High Risk"
$existingLocation = $namedLocations.value | Where-Object { $_.displayName -eq $blockedLocationName }
if (-not $existingLocation) {
Write-Host "Creating named location for blocked countries..." -ForegroundColor Gray
$locationBody = @{
"@odata.type" = "#microsoft.graph.countryNamedLocation"
displayName = $blockedLocationName
countriesAndRegions = $BlockedCountries
includeUnknownCountriesAndRegions = $false
}
$newLocation = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" `
-Body ($locationBody | ConvertTo-Json -Depth 10)
$locationId = $newLocation.id
}
else {
$locationId = $existingLocation.id
Write-Host "Using existing named location: $($existingLocation.id)" -ForegroundColor Cyan
}
# Create Conditional Access policyWrite-Host "Creating Conditional Access policy..." -ForegroundColor Gray
$policyBody = @{
displayName = "Block Access from High-Risk Countries - Nederlandse Baseline"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
excludeUsers = @()
}
applications = @{
includeApplications = @("All")
}
locations = @{
includeLocations = @($locationId)
}
}
grantControls = @{
operator = "OR"
builtInControls = @("block")
}
}
$newPolicy = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
-Body ($policyBody | ConvertTo-Json -Depth 10)
Write-Host "`n[OK] Geo-blocking policy created" -ForegroundColor Green
Write-Host "Policy: $($newPolicy.displayName)" -ForegroundColor Cyan
Write-Host "⚠️ In REPORT-ONLY mode - review impact before enabling!" -ForegroundColor Yellow
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
Write-Host "Error Details: $($_.Exception.Message)" -ForegroundColor Red
exit 2
}
}
try {
if ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Usage:" -ForegroundColor Yellow
Write-Host " -Monitoring Check for geo-blocking policies" -ForegroundColor Gray
Write-Host " -Remediation Create geo-blocking policy" -ForegroundColor Gray
Write-Host " -BlockedCountries @('..') Specify countries to block (ISO codes)" -ForegroundColor Gray
}
}
catch {
throw
}
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.Read.All" -ErrorAction Stop -NoWelcome
Write-Host "Checking for geo-blocking policies..." -ForegroundColor Gray
$policies = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies"
$result = @{
isCompliant = $false
geoBlockingPolicies = 0
policyNames = @()
blockedCountries = @()
}
foreach ($policy in $policies.value) {
if ($policy.state -ne 'enabled') { continue }
# Check if policy blocks based on locationif ($policy.conditions.locations.excludedLocations) {
$hasCountryBlocking = $policy.grantControls.builtInControls -contains 'block'
if ($hasCountryBlocking) {
$result.geoBlockingPolicies++
$result.policyNames += $policy.displayName
$result.isCompliant = $trueWrite-Host " [OK] GEO-BLOCKING POLICY: $($policy.displayName)" -ForegroundColor Green
}
}
}
Write-Host "`n Geo-blocking policies found: $($result.geoBlockingPolicies)" -ForegroundColor $(
if ($result.geoBlockingPolicies -gt 0) { 'Green' } else { 'Yellow' }
)
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT - Geo-blocking is configured" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n⚠️ NO GEO-BLOCKING FOUND" -ForegroundColor Yellow
Write-Host "Consider blocking high-risk countries" -ForegroundColor Cyan
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
function Invoke-Revert {
Write-Host "`nReverting configuration..." -ForegroundColor Cyan
try {
if ($WhatIf) {
Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow
return
}
# Revert implementation - requires manual implementation per controlWrite-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <#
.SYNOPSIS
Conditional Access - Geographic Blocking
.DESCRIPTION
Implements geo-blocking via Conditional Access to block access from specific countries.
Helps prevent unauthorized access from high-risk locations.
.NOTES
Filename: conditional-access-geo-blocking.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.PARAMETER BlockedCountries
Array of ISO 3166 country codes to block (e.g., @("RU","CN","KP"))
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Monitoring
Check if geo-blocking policies exist
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Remediation -BlockedCountries @("RU","CN","KP")
Create policy blocking Russia, China, North Korea
#>#Requires -Version 5.1#Requires -Modules Microsoft.Graph
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[switch]$Monitoring,
[Parameter(Mandatory=$false)]
[switch]$Remediation,
[switch]$Revert,
[switch]$WhatIf,
[Parameter(Mandatory=$false)]
[string[]]$BlockedCountries = @("RU", "CN", "KP", "IR", "SY")
)
$ErrorActionPreference = 'Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Conditional Access - Geographic Blocking" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.Read.All" -ErrorAction Stop -NoWelcome
Write-Host "Checking for geo-blocking policies..." -ForegroundColor Gray
$policies = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies"
$result = @{
isCompliant = $false
geoBlockingPolicies = 0
policyNames = @()
blockedCountries = @()
}
foreach ($policy in $policies.value) {
if ($policy.state -ne 'enabled') { continue }
# Check if policy blocks based on locationif ($policy.conditions.locations.excludedLocations) {
$hasCountryBlocking = $policy.grantControls.builtInControls -contains 'block'
if ($hasCountryBlocking) {
$result.geoBlockingPolicies++
$result.policyNames += $policy.displayName
$result.isCompliant = $trueWrite-Host " [OK] GEO-BLOCKING POLICY: $($policy.displayName)" -ForegroundColor Green
}
}
}
Write-Host "`n Geo-blocking policies found: $($result.geoBlockingPolicies)" -ForegroundColor $(
if ($result.geoBlockingPolicies -gt 0) { 'Green' } else { 'Yellow' }
)
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT - Geo-blocking is configured" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n⚠️ NO GEO-BLOCKING FOUND" -ForegroundColor Yellow
Write-Host "Consider blocking high-risk countries" -ForegroundColor Cyan
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess" -ErrorAction Stop -NoWelcome
Write-Host "Creating geo-blocking policy..." -ForegroundColor Gray
Write-Host "Countries to block: $($BlockedCountries -join ', ')" -ForegroundColor Yellow
# Get named locations firstWrite-Host "Getting existing named locations..." -ForegroundColor Gray
$namedLocations = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations"
# Create named location for blocked countries if not exists$blockedLocationName = "Blocked Countries - High Risk"
$existingLocation = $namedLocations.value | Where-Object { $_.displayName -eq $blockedLocationName }
if (-not $existingLocation) {
Write-Host "Creating named location for blocked countries..." -ForegroundColor Gray
$locationBody = @{
"@odata.type" = "#microsoft.graph.countryNamedLocation"
displayName = $blockedLocationName
countriesAndRegions = $BlockedCountries
includeUnknownCountriesAndRegions = $false
}
$newLocation = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" `
-Body ($locationBody | ConvertTo-Json -Depth 10)
$locationId = $newLocation.id
}
else {
$locationId = $existingLocation.id
Write-Host "Using existing named location: $($existingLocation.id)" -ForegroundColor Cyan
}
# Create Conditional Access policyWrite-Host "Creating Conditional Access policy..." -ForegroundColor Gray
$policyBody = @{
displayName = "Block Access from High-Risk Countries - Nederlandse Baseline"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
excludeUsers = @()
}
applications = @{
includeApplications = @("All")
}
locations = @{
includeLocations = @($locationId)
}
}
grantControls = @{
operator = "OR"
builtInControls = @("block")
}
}
$newPolicy = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
-Body ($policyBody | ConvertTo-Json -Depth 10)
Write-Host "`n[OK] Geo-blocking policy created" -ForegroundColor Green
Write-Host "Policy: $($newPolicy.displayName)" -ForegroundColor Cyan
Write-Host "⚠️ In REPORT-ONLY mode - review impact before enabling!" -ForegroundColor Yellow
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
Write-Host "Error Details: $($_.Exception.Message)" -ForegroundColor Red
exit 2
}
}
try {
if ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Usage:" -ForegroundColor Yellow
Write-Host " -Monitoring Check for geo-blocking policies" -ForegroundColor Gray
Write-Host " -Remediation Create geo-blocking policy" -ForegroundColor Gray
Write-Host " -BlockedCountries @('..') Specify countries to block (ISO codes)" -ForegroundColor Gray
}
}
catch {
throw
}
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess" -ErrorAction Stop -NoWelcome
Write-Host "Creating geo-blocking policy..." -ForegroundColor Gray
Write-Host "Countries to block: $($BlockedCountries -join ', ')" -ForegroundColor Yellow
# Get named locations firstWrite-Host "Getting existing named locations..." -ForegroundColor Gray
$namedLocations = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations"
# Create named location for blocked countries if not exists$blockedLocationName = "Blocked Countries - High Risk"
$existingLocation = $namedLocations.value | Where-Object { $_.displayName -eq $blockedLocationName }
if (-not $existingLocation) {
Write-Host "Creating named location for blocked countries..." -ForegroundColor Gray
$locationBody = @{
"@odata.type" = "#microsoft.graph.countryNamedLocation"
displayName = $blockedLocationName
countriesAndRegions = $BlockedCountries
includeUnknownCountriesAndRegions = $false
}
$newLocation = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" `
-Body ($locationBody | ConvertTo-Json -Depth 10)
$locationId = $newLocation.id
}
else {
$locationId = $existingLocation.id
Write-Host "Using existing named location: $($existingLocation.id)" -ForegroundColor Cyan
}
# Create Conditional Access policyWrite-Host "Creating Conditional Access policy..." -ForegroundColor Gray
$policyBody = @{
displayName = "Block Access from High-Risk Countries - Nederlandse Baseline"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
excludeUsers = @()
}
applications = @{
includeApplications = @("All")
}
locations = @{
includeLocations = @($locationId)
}
}
grantControls = @{
operator = "OR"
builtInControls = @("block")
}
}
$newPolicy = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
-Body ($policyBody | ConvertTo-Json -Depth 10)
Write-Host "`n[OK] Geo-blocking policy created" -ForegroundColor Green
Write-Host "Policy: $($newPolicy.displayName)" -ForegroundColor Cyan
Write-Host "⚠️ In REPORT-ONLY mode - review impact before enabling!" -ForegroundColor Yellow
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
Write-Host "Error Details: $($_.Exception.Message)" -ForegroundColor Red
exit 2
}
}
function Invoke-Revert {
Write-Host "`nReverting configuration..." -ForegroundColor Cyan
try {
if ($WhatIf) {
Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow
return
}
# Revert implementation - requires manual implementation per controlWrite-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <#
.SYNOPSIS
Conditional Access - Geographic Blocking
.DESCRIPTION
Implements geo-blocking via Conditional Access to block access from specific countries.
Helps prevent unauthorized access from high-risk locations.
.NOTES
Filename: conditional-access-geo-blocking.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.PARAMETER BlockedCountries
Array of ISO 3166 country codes to block (e.g., @("RU","CN","KP"))
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Monitoring
Check if geo-blocking policies exist
.EXAMPLE
.\conditional-access-geo-blocking.ps1 -Remediation -BlockedCountries @("RU","CN","KP")
Create policy blocking Russia, China, North Korea
#>#Requires -Version 5.1#Requires -Modules Microsoft.Graph
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[switch]$Monitoring,
[Parameter(Mandatory=$false)]
[switch]$Remediation,
[switch]$Revert,
[switch]$WhatIf,
[Parameter(Mandatory=$false)]
[string[]]$BlockedCountries = @("RU", "CN", "KP", "IR", "SY")
)
$ErrorActionPreference = 'Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Conditional Access - Geographic Blocking" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.Read.All" -ErrorAction Stop -NoWelcome
Write-Host "Checking for geo-blocking policies..." -ForegroundColor Gray
$policies = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies"
$result = @{
isCompliant = $false
geoBlockingPolicies = 0
policyNames = @()
blockedCountries = @()
}
foreach ($policy in $policies.value) {
if ($policy.state -ne 'enabled') { continue }
# Check if policy blocks based on locationif ($policy.conditions.locations.excludedLocations) {
$hasCountryBlocking = $policy.grantControls.builtInControls -contains 'block'
if ($hasCountryBlocking) {
$result.geoBlockingPolicies++
$result.policyNames += $policy.displayName
$result.isCompliant = $trueWrite-Host " [OK] GEO-BLOCKING POLICY: $($policy.displayName)" -ForegroundColor Green
}
}
}
Write-Host "`n Geo-blocking policies found: $($result.geoBlockingPolicies)" -ForegroundColor $(
if ($result.geoBlockingPolicies -gt 0) { 'Green' } else { 'Yellow' }
)
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT - Geo-blocking is configured" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n⚠️ NO GEO-BLOCKING FOUND" -ForegroundColor Yellow
Write-Host "Consider blocking high-risk countries" -ForegroundColor Cyan
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Gray
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess" -ErrorAction Stop -NoWelcome
Write-Host "Creating geo-blocking policy..." -ForegroundColor Gray
Write-Host "Countries to block: $($BlockedCountries -join ', ')" -ForegroundColor Yellow
# Get named locations firstWrite-Host "Getting existing named locations..." -ForegroundColor Gray
$namedLocations = Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations"
# Create named location for blocked countries if not exists$blockedLocationName = "Blocked Countries - High Risk"
$existingLocation = $namedLocations.value | Where-Object { $_.displayName -eq $blockedLocationName }
if (-not $existingLocation) {
Write-Host "Creating named location for blocked countries..." -ForegroundColor Gray
$locationBody = @{
"@odata.type" = "#microsoft.graph.countryNamedLocation"
displayName = $blockedLocationName
countriesAndRegions = $BlockedCountries
includeUnknownCountriesAndRegions = $false
}
$newLocation = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" `
-Body ($locationBody | ConvertTo-Json -Depth 10)
$locationId = $newLocation.id
}
else {
$locationId = $existingLocation.id
Write-Host "Using existing named location: $($existingLocation.id)" -ForegroundColor Cyan
}
# Create Conditional Access policyWrite-Host "Creating Conditional Access policy..." -ForegroundColor Gray
$policyBody = @{
displayName = "Block Access from High-Risk Countries - Nederlandse Baseline"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
excludeUsers = @()
}
applications = @{
includeApplications = @("All")
}
locations = @{
includeLocations = @($locationId)
}
}
grantControls = @{
operator = "OR"
builtInControls = @("block")
}
}
$newPolicy = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
-Body ($policyBody | ConvertTo-Json -Depth 10)
Write-Host "`n[OK] Geo-blocking policy created" -ForegroundColor Green
Write-Host "Policy: $($newPolicy.displayName)" -ForegroundColor Cyan
Write-Host "⚠️ In REPORT-ONLY mode - review impact before enabling!" -ForegroundColor Yellow
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
Write-Host "Error Details: $($_.Exception.Message)" -ForegroundColor Red
exit 2
}
}
try {
if ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Usage:" -ForegroundColor Yellow
Write-Host " -Monitoring Check for geo-blocking policies" -ForegroundColor Gray
Write-Host " -Remediation Create geo-blocking policy" -ForegroundColor Gray
Write-Host " -BlockedCountries @('..') Specify countries to block (ISO codes)" -ForegroundColor Gray
}
}
catch {
throw
}
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
if ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Usage:" -ForegroundColor Yellow
Write-Host " -Monitoring Check for geo-blocking policies" -ForegroundColor Gray
Write-Host " -Remediation Create geo-blocking policy" -ForegroundColor Gray
Write-Host " -BlockedCountries @('..') Specify countries to block (ISO codes)" -ForegroundColor Gray
}
}
catch {
throw
}
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}