Populating Azure AD named and trusted locations using Graph

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”. Screenshot_9.png

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s