In this blog post, I will guide you through how to export named locations in AzureAD using PowerShell, as well as how to configure the required API permissions using app registrations in AzureAD.
If your organization has many office locations and branches, you might have numerous IP addresses added to your named locations in Azure AD for use in Conditional Access or impossible travel policies. It can be challenging to obtain all the information about your locations in a convenient format.
Step 1: Create Azure App Registration.
Login to your entra.microsoft.com management portal and navigate to “Applications > App registrations” and click on “New Registration“.
Choose a name for your application that aligns with your naming convention, and leave the other settings as default. After clicking on ‘save,’ you’ll be directed to the overview page for your application. Make sure to take note of the “Application (client) ID” value in the overview section, as it will be utilized in the script variables for establishing a connection.
Step 2: Add required API permissions the the application.
Go to the “API permissions” located in the left-hand menu, and select “Add a permission.” From there, choose “Microsoft Graph.“
As per current Microsoft documentation, the required permissions for fetching “Named Locations” through the Rest API include:
Permission type | Permissions (from least to most privileged) |
---|---|
Delegated (work or school account) | Policy.Read.All |
Delegated (personal Microsoft account) | Not supported. |
Application | Policy.Read.All |
For this example, we’re using the “Application” permission type, although you could also utilize Delegated permissions. However, that won’t be discussed in this guide.
Select “Application Permissions” and search for “Policy.Read.All“. Ensure the permission is selected and click on “Add permissions.” Once you’ve added the necessary permissions, you’ll need to “Grant admin consent” for the application.
Step 3: Create Client Secret
Go to the “Certificates & secrets” in the left pane of your application and click on “New client secret” after generating a new client secret, it’s important that you copy it to a secure place before leaving the window, otherwise it will be hidden. I recommend letting the secret expire after 90 days to ensure key integrity.
Once you have created the client secret, note down the “Value” and proceed to the script. This value is your “Client Secret“
Step 4: Replace variables in the script and run.
At the beginning of the script, you’ll see the variables that need to be modified with the values from your tenant and application. The variables are relatively self-explanatory.
$TenantDomainName = “DOMAIN.ONMICROSOFT.COM”
$ClientID = “YOUR APP REGISTRATION CLIENT ID”
$ClientSecret = “YOUR APP REGISTRATION CLIENT SECRET”
$ExportPath = “C:\Temp\output”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#region - Variables and Azure AD token connection. # - Define variables used in the script. Update values to match your environment. $TenantDomainName = "DOMAIN.ONMICROSOFT.COM" $ClientID = "YOUR APP REGISTRATION CLIENT ID" $ClientSecret = "YOUR APP REGISTRATION CLIENT SECRET" $ExportPath = "C:\Temp\output" #if path does not exist, the script will create it. # - Set the token body as a hash table with the necessary parameters to obtain an access token. $TokenBody = @{ 'grant_type' = 'client_credentials' 'Scope' = "https://graph.microsoft.com/.default" 'client_id' = $ClientId 'client_secret' = $ClientSecret } # - Use the Invoke-RestMethod cmdlet to send a POST request to the Azure AD token endpoint to obtain an access token $TokenConnect = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$($TenantDomainName)/oauth2/v2.0/token" -Body $TokenBody $AccessToken = $TokenConnect.access_token #endregion $NamedLocationsURI = "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" $NamedLocations = Invoke-RestMethod -Headers @{Authorization = "Bearer $($AccessToken)" } -Uri $NamedLocationsURI -Method Get # - Create a report on the named locations. $NamedLocationsReport = foreach ($NamedLocation in $NamedLocations.value) { [PSCustomObject]@{ DisplayName = $NamedLocation.displayName IsTrusted = $NamedLocation.IsTrusted IPranges = ($NamedLocation.ipranges.cidraddress -join ',') CountriesAndRegions = ($NamedLocation.countriesAndRegions -join ',') includeUnknownCountriesAndRegions = $NamedLocation.includeUnknownCountriesAndRegions CreatedDate = $NamedLocation.createdDateTime modifiedDateTime = $NamedLocation.modifiedDateTime } } # Check if the path exists, and create it if it does not exist. If(!(Test-Path -Path $ExportPath)){New-Item -ItemType Directory -Path $ExportPath} # Export the report to a CSV file using UTF8 encoding and ';' delimiter. $NamedLocationsReport | Export-Csv -Path "$($ExportPath)\NamedLocations_Report.csv" -Encoding UTF8 -NoTypeInformation -Delimiter ';' |
Check out this example of how the output would appear after converting the CSV file to a readable format. To convert it effortlessly, you can use my bulk CSV converter script from one of my earlier posts.
Bulk Convert CSV Files to Excel Files Using Powershell
I hope you found this blogpost helpful! If you have any questions, feedback, or just want to connect, drop a comment below and I’ll do my best to get back to you.
It is also possible to use the “AzureAD Powershell Module” to obtain this list.
# – Install-Module -Name AzureADPreview
# – Connect-AzureAD
$namedlocations = Get-AzureADMSNamedLocationPolicy
$ExportPath = “C:\Temp\output”
$NamedLocationsReport = foreach ($NamedLocation in $NamedLocations) {
[PSCustomObject]@{
DisplayName = $NamedLocation.displayName
IsTrusted = $NamedLocation.IsTrusted
IPranges = ($NamedLocation.ipranges.cidraddress -join ‘,’)
CountriesAndRegions = ($NamedLocation.countriesAndRegions -join ‘,’)
includeUnknownCountriesAndRegions = $NamedLocation.includeUnknownCountriesAndRegions
}
}
# Check if the path exists, and create it if it does not exist.
If(!(Test-Path -Path $ExportPath)){New-Item -ItemType Directory -Path $ExportPath}
# Export the report to a CSV file using UTF8 encoding and ‘;’ delimiter.
$NamedLocationsReport | Export-Csv -Path “$($ExportPath)\NamedLocations_Report.csv” -Encoding UTF8 -NoTypeInformation -Delimiter ‘;’
I found this page because Get-AzureADMSNamedLocationPolicy didn’t work for me.
Sadly your script didn’t help much – I did get way more info thank you – but I really only have one policy with lots of countries allowed.
I was hoping to get a list of those countries, and whilst I can get all the country codes, they are of no use to me as I need them in readable format.
(eg ZM YE WF VI VG VE VU UZ UM UY AE UA UG TV TC TM TR TN TT TO TK TG)
@lucashadberg your script from comment is fine but not cover scenario when you have more than one IP under Named Location
Use below one to get all IP ranges from named locations.
# Install-Module -Name AzureADPreview
# Connect-AzureAD
$NamedLocations = Get-AzureADMSNamedLocationPolicy
$ExportPath = “C:\Temp\output”
$NamedLocationsReport = foreach ($NamedLocation in $NamedLocations) {
foreach ($IPRange in $NamedLocation.ipranges) {
[PSCustomObject]@{
DisplayName = $NamedLocation.displayName
IsTrusted = $NamedLocation.IsTrusted
IPrange = $IPRange.cidraddress
CountriesAndRegions = ($NamedLocation.countriesAndRegions -join “,”)
IncludeUnknownCountriesAndRegions = $NamedLocation.includeUnknownCountriesAndRegions
}
}
}
# Check if the path exists, and create it if it does not exist.
if(!(Test-Path -Path $ExportPath)){New-Item -ItemType Directory -Path $ExportPath}
# Export the report to a CSV file using UTF8 encoding and ‘;’ delimiter.
$NamedLocationsReport | Export-Csv -Path “$($ExportPath)\NamedLocations_Report_$(Get-date -f yyyyMMdd-HHmmss).csv” -Encoding UTF8 -NoTypeInformation -Delimiter ‘;’