This post contains a quick example on how to utilize the new namedLocation Graph REST API endpoints to populate conditional access sites.
For simplicity, the script utilizes the access token from the Graph Explorer, rather than it’s own application registration.
First, go to the Graph Explorer, and click “Sign in with Microsoft” in the left menu.
Sign in with a global administrator account, and when you get back to the Graph Explorer, click “Modify permissions”.
Add a checkbox by the “Policy.ReadWrite.ConditionalAccess” permission, and accept the consent screen.
When back at the Graph Explorer the second time, look in the url, and you should find it contains #access_token=xxx. This is the access token that we will use. Copy the url and paste it when prompted by the below script. Please note that the token is only valid for 1 hour.
Second, download the following excel template and populate it. You will see that you can have multiple lines with the same name, with different IP addresses (this will create a location with multiple IP addresses). IPv6 is also supported, as currently not working in the GUI.
$url = Read-Host "Paste Graph Explorer url" $excelFile = "~\Desktop\LocIP.xlsx" # Extract access token and create header $accessToken = ($url -split "access_token=" | select -Index 1) -split "&" | select -first 1 $headers = @{"Authorization" = "Bearer $accessToken"} # Get existing named locations $_namedLocationsAzureAD = Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/conditionalAccess/namedLocations" -Headers $headers $namedLocationsAzureAD = $_namedLocationsAzureAD.value | foreach{[PSCustomObject]@{id = $_.id; displayName=$_.displayName; isTrusted = $_.isTrusted; ipRanges = @($_.ipranges.cidraddress)}} # Get locations form excel $namedLocationsExcel = @{} Import-Excel -Path $excelFile | ? Location | Foreach { $IP = $_.IP if($IP -notlike "*/*" -and $IP -like "*.*") { Write-Verbose "Changed $IP to $IP/32" -Verbose $IP = $IP + "/32" } elseif($IP -notlike "*/*" -and $IP -like "*:*") { Write-Verbose "Changed $IP to $IP/128" -Verbose $IP = $IP + "/128" } $namedLocationsExcel[$_.Location] += @($IP) } # Work in each named location in Excel $namedLocationsExcel.Keys | Foreach { Write-Verbose -Message "Working on location $($_) from Excel" -Verbose $Body = @{ "@odata.type" = "#microsoft.graph.ipNamedLocation" displayName = $_ isTrusted = $true ipRanges = @($namedLocationsExcel[$_] | Foreach { if($_ -like "*.*") { @{ "@odata.type" = "#microsoft.graph.iPv4CidrRange" cidrAddress = $_ } } else { @{ "@odata.type" = "#microsoft.graph.iPv6CidrRange" cidrAddress = $_ } } }) } | ConvertTo-Json -Depth 4 # $Body $existingLocation = $namedLocationsAzureAD | ? displayName -eq $_ if($existingLocation) { $key = $_ if(($existingLocation.ipRanges | where{$_ -notin $namedLocationsExcel[$key]}) -or ($namedLocationsExcel[$key] | where{$_ -notin $existingLocation.ipRanges})) { Write-Verbose "Location $($_) has wrong subnets -> updating" -Verbose Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/conditionalAccess/namedLocations/$($existingLocation.id)" -Headers $headers -Method Patch -Body $Body -ContentType "application/json" | Out-Null } } else { Write-Verbose "Location $($_) does not exist -> creating" -Verbose Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/conditionalAccess/namedLocations" -Headers $headers -Method Post -Body $Body -ContentType "application/json" | Out-Null } }