• Contact Us

    We will get back to you as soon as possible.

  • We do not collect personal information except to the extent you provide that information to use through email, your web browser or through our contact forms. We will not share, sell or otherwise provide non-public information to others without your consent.


  • We do not collect personal information except to the extent you provide that information to use through email, your web browser or through our contact forms. We will not share, sell or otherwise provide non-public information to others without your consent.

Security First – Implement Azure Geo-Fencing
Published on May 27, 2021

Geo-Fencing with Usage Location

Defining Geo-Fencing, coupled with either Active Directory (AD) and/or Azure AD user usage location significantly increases one’s security posture.  For examples, using Conditional Access, businesses can define one or multiple Geo-Fencing policies.  Geo-fencing policies ONLY allow trusted users to login from defined locations or countries.  In summary, attempts to login outside one’s defined Geo-Fence will be met with a swift hard denial.

Where To Start?

The first area to confront is defining usage location for users.  Simply stated, this means understanding where employees operate.  You might have, for instance, two types of employees.  One type perhaps operates exclusively within a single country whereas another operates across multiple. In creating a comprehensive plan, this may require taking a step back to understand where employees actually operate or work from.

What’s the purpose of this Usage Location?  

This is a country code assigned, or populated, for users. Usage Location is 100% definable (attribute value). Usage Location is assigned to either a hybrid or cloud user object (further covered below).  A Usage Location informs the cloud (more specifically Azure AD or Office 365) where that individual is centrally located.  It also says where they operates from.   Simple huh?  But why is this important?  Well, continue reading…


Important Note:

Usage Location is very different than preferred data location (PDL).

Usage Location can be assigned manually or automatically.  More on this coming shortly.

One perhaps may wonder what value ought to be assigned to those operating across geographical zones (US, UK, Japan, etc.).  The rule of thumb is to assign the value of their HOME location. Assign the country value where they primarily operate or reside within.

Defining Your Fencing Scopes

The next step is to create one (or perhaps several) geo-groups for each of your geographical zones.  These new geo-groups will be incorporated to define THE SCOPE of your Geo-Fencing policies. Take for instances you have employees living and working within the US, UK, etc.. Start minimally by creating a geo-group for each.

The recommended (best) method to automate and maintain these geo-groups is use Azure’s Dynamic Groups. Create your dynamic geo-groups. Filter your query on usage location (see example).  Rinse and repeat for each geographical zone.  These Dynamic geo-groups will automate membership and (as a bonus) minimize your operational costs.

Once created, you’ll now incorporate and use these geo-groups to define scopes for your new geo-fencing CA policies.

Dynamic Group Filter

Geo-Fence - Usage Scope


Example how to setup dynamic group filtering for Portugal users. Rule Syntax:

(user.usageLocation -eq “PT”) and (user.userType -eq “Member”

Dynamic Geo-Group Filter
Azure – CA Include – Geolocation – US (user.usageLocation -eq “US”) and (user.userType -eq “Member”
Azure – CA Include – Geolocation – UK (user.usageLocation -eq “GB”) and (user.userType -eq “Member”
Azure – CA Include – Geolocation – Portugal (user.usageLocation -eq “PT”) and (user.userType -eq “Member”

Geo Fencing CA Policy

Here is where all this comes together (Usage Location, Geo-groups, etc.)

The next step is to create your Geo-Fencing Conditional Access Policy (or commonly referred to as CA Policies). Depending on your business scenarios, this could require one or more geo-fencing CA Policy.

Ensure to develop an approach and test plan.  You of course will want to validate your CA policies are properly functioning within an isolated lab environment.  They need to function as you anticipate.  Use your “What If” tool to prove-out assumptions. Also, prior to enabling, validate results by configuring your CA Policy for report only mode.  Ensure to also define an exclusion group for your break glass accounts.  This will help determine whether there are any issues requiring attention.  Above all, a thorough test plan will prevent heart ache.

This so far represent the more basic steps for creating Geo-Fencing CA Policies.


Here is an example of a Geo-Fencing CA Policy created for Portugal users.

CA Policy: Acme – Users – Geofence Portugal

    • Conditional Access Policy Basic Settings:
      • Assignment >
        • Include: Users and Group: Azure – CA Include – Geolocation – Portugal ← Scope
        • Exclude: Users and Group: Azure – CA Exclude
        • Cloud apps or actions > Include: All cloud apps
        • Conditions > Location > Include: Any Location
        • Conditions > Location > Exclude: Portugal ← Exception
      • Access controls
        • Grant: Block Access

More Concerning Usage Locations

An assigned Usage Location can easily be incorporated into one or many Geo-Fencing Conditional Access Policies . Such a geo-fencing CA Policy (or policies) prevents usage of users accounts outside their defined geographical zone or country.

For instances, say a foreign hacker attempts a login, with stolen credential, using a Cincinnati-based user account. Not on your watch. Your ‘US based‘ geo-fence CA Policy will detect and prevent this hacker from gaining access – pretty cool huh?  Above all, login attempts from ANY country, other than the US, is denied.


Geo-Fence Use Example

DTS Inc. recently completed a global M365 migration project for a special client.  This client synchronizes users globally from multiple remote Active Directory (AD) forests (i.e. sites). We developed, tested and deployed a series of security geo-fencing CA Policies allowing sign-in only from defined countries locations. Sign ins originating elsewhere were blocked.

Elaborating further; depending on the source AD forest’s physical locations (e.g. UK, Portugal, etc.), we built custom Azure AD Connect (AADC) synchronization rules (see script below).  These rules automated usage location value assignment. In other words, if a user’s home location was say the UK, that location rule automatically assigned and synchronized that particular usage location value to their Azure AD hybrid user account.

Azure dynamic groups were also deployed. This automated group membership assignment for their geo-groups (i.e. separate geo-groups for their zone – e.g. UK, Portugal, US, etc.).

Conditional Access Policies were then carefully developed, tested and deployed for their countries.  These policies were appropriately scoped to their dynamic geo-groups (described above).  As a final summary, their CA Policies block sign-in activity except from designated country(ies).  In the case of overlapping zones (for example someone traveling between the UK and United States), additional geo-groups and CA Policies were deployed providing equivalent restrictions.


Hybrid Objects

On-premises objects synchronized to Azure AD are known as hybrid-objects (e.g. hybrid-computers, hybrid users, etc.).  There are a number of tools that automate this synchronization process of objects.  For an easy and inexpensive route, implement the free Microsoft tool called Azure AD Connect.

Contact DTS Inc. for a free assessment.

Automate Usage Location

Covered above, it is recommended to setup dynamic groups to populate and maintain your geo-groups.  This of course relies on usage location.

You might wonder whether an easy option exists to populate usage location? For synchronized accounts, from on-premises, the answer is yes. (note: for cloud only objects, a script could be used)

When synchronizing on-premises users (known as hybrid), create an Azure AD Connect rule to manually assign usage location.  For instance, one could manually define and maintain usage location with their AD forest (or perhaps within some backend provisioning process).  However an automated scoped-rule (see script below) can be defined within AADC, for that remote location, which automatically assigns and maintains  user usage location.

Similarly, an AADC centralized rule significantly reduces the potential for potential ‘fat fingering’ mistakes.  In addition, a rule will help centralize administrative controls beneath a single AADC instance (important note: any rules applied to your primary AADC server should be deployed to all AADC Stage servers)

Lastly, the powershell script below provides a simple method for automating usage location from different physical AD forests.


Important Note:

It should be explicitly noted that a geo-fence CA Policy does not circumvent nor take the place of other contemporary security methods or deterrents, such as Multi-Factor Authentication (MFA).

AADC Rules: Automate Usage Location

The powershell script below demonstrating how to define an Azure AD Connect (AADC) usage location rule.  Have fun.


                    HelpMessage="Required: Single AD FQDN Domain")]

                    HelpMessage="Optional: Rule Precedence Number")]

                    HelpMessage="Optional: Usage Location Code")]
                    [String]$UsageLocationCode = "US",

                    HelpMessage="Optional: Business Code")]
        Supporting O365 Usage Location, this function creates an inbound Azure AD Connect
        Filter-Rule providing Azure AD Connect Synchronization for the AD attribute c (usage location)

        If populating AD with the country code value, make sure you are using the appropriate
        ISO 3166-2 country code. - https://en.wikipedia.org/wiki/ISO_3166-2

        Script Name: .Create-AADCFilterUsageLoc.ps1
        Author: Shwan May
        Email: shawn@yourdts.com
        Requires: Powershell V3 or greater

        Mandatory - Specify AD Connector - FQDN
        To target a specific AD Connector, provide AD Connector FQDN - e.g. eus.acme.com

    .PARAMETER Precedence
        Mandatory - Specify a unique Filter-Rule Precedence Number
        Specify a precedence (integer) - e.g. 85

    .PARAMETER UsageLocation
        Optional - Specify Usage Location

    .PARAMETER BusinessAcronym
        Optional - Specify Business Acronym

        .Create-AADCFilterUsageLoc.ps1 -ADFQDN acme.com -Precedence 85 
        Creates AADC Filter-Rule - defines the United States as the default usage location and a
        Filter-Rule precedence of 85

        .Create-AADCFilterUsageLoc.ps1 -ADFQDN acme.com -Precedence 85 -UsageLocation GB
        Creates AADC Filter-Rule - defines the United Kingdom as the default usage location and a
        Filter-Rule precedence of 85

        .Create-AADCFilterUsageLoc.ps1 -ADFQDN acme.com -Precedence 25 -UsageLocation CO -BusinessAcronym ACME
        Creates AADC Filter-Rule - defines Colombia as the default usage location and a
        Filter-Rule precedence of 25 and appends business acronym to rule description

Function Create-AADCRuleIn-UsageLoc {

    # Checks if variable is object
    if (![string]::IsNullOrEmpty($ADFQDN))
        # Acquires Filtered AD Connector (selects Identifier's GUID)
        $ADConnector = Get-ADSyncConnector | `
                Where-Object {$_.Type -eq 'AD' -and $_.name -eq $ADFQDN} | `
            Select-Object -ExpandProperty Identifier | `
            Select-Object -ExpandProperty guid

        if ($ADConnector -isnot [object])
            Write-Warning "Could not locate specified AD Connector - $ADFQDN"
        # Acquires Filtered AD Connector (selects Identifier's GUID)
        $ADConnector = Get-ADSyncConnector | `
                Where-Object {$_.Type -eq 'AD'} | `
            Select-Object -ExpandProperty Identifier | `
            Select-Object -ExpandProperty guid

    if (![string]::IsNullOrEmpty($BusinessAcronym))
        {$Acronym = " - " + $BusinessAcronym}

    if ($ADConnector -isnot [array])
        # Defines AADC New Sync Rule Schema
        $syncRule = New-ADSyncRule -Name "In from AD - Custom Filter - User UsageLocation$Acronym - $UsageLocationCode" `
                -Identifier ([GUID]::NewGuid().Guid) `
                -Description 'User Join with UsageLocation from C' `
                -Direction 'Inbound' `
                -Precedence $Precedence `
                -PrecedenceAfter '00000000-0000-0000-0000-000000000000' `
                -PrecedenceBefore '00000000-0000-0000-0000-000000000000' `
                -SourceObjectType 'user' `
                -TargetObjectType 'person' `
                -Connector $ADConnector `
                -LinkType 'Join' `
                -SoftDeleteExpiryInterval 0 `
                -ImmutableTag ''

        # Defines AADC Attribute Flow
        $syncRule = Add-ADSyncAttributeFlowMapping `
            -SynchronizationRule $syncRule[0] `
            -Source @('c') `
            -Destination 'usageLocation' `
            -FlowType 'Expression' `
            -ValueMergeType 'Update' `
            -Expression ("IIF(IsNullOrEmpty([c])," + [char]34 + $UsageLocationCode + [char]34 + ",[c])")
            # Creates new AADC Sync Rule
            Add-ADSyncRule -SynchronizationRule $syncRule[0] -ErrorAction Stop
            # Writes Warning to Shell
            Write-Warning "There was a problem creating this AADC Filter-Rule!"
        Write-Host "Usage Location Inbound Filter-Rule Successfully Created. Perform a full AADC Synchronization." -ForegroundColor Yellow
        {Write-Warning "Please specify a single FQDN domain"}



  • Implementing correct solutions
  • Bringing the correct talent (professional-staff-augmentation or project team)
  • Alignment to the business functional & functional direction
  • Maintaining agility with communication and options
  • Ensure to have a properly scoped project and accurate roadmap eliminating fluff


Stay Well

Here are some incredibly-simple videos to watch & share with co-workers, family and friend on staying well: