PurviewHow-to

Adaptive scopes in Microsoft Purview: target retention policies with OPATH and KQL queries

Build Purview adaptive scopes for users, groups and sites with OPATH and KQL, validate them in PowerShell, plan for the five-day population and fix scopes that stay empty.

Static scopes make you list mailboxes, sites and OneDrive URLs by hand and keep that list current. Adaptive scopes replace the list with a query on attributes such as department, country or site template, which Microsoft Purview runs again every day. In this post I'll explain where adaptive scopes work (and what to use for DLP), how to build user, group and site queries, how to validate them before the five-day wait, and how to fix a scope that stays empty.

How this guide is organized: How it works → Prerequisites → Step-by-step → Verify → Tips and gotchasFlow diagram of the article's sections in reading order: 1. How it works. 2. Prerequisites. 3. Step-by-step (5 steps: Create the scope; Use the advanced query builder for anything subtle; Validate the query before you rely on it; Wait, then check membership; Attach the scope to a policy). 4. Verify. 5. Tips and gotchas. Toolbox: Get-AdaptiveScopeMembers, Get-AppRetentionCompliancePolicy, Get-Recipient, CustomAttribute1, ExtensionCustomAttribute1.1How it works2Prerequisites3Step-by-step4Verify5Tips andgotchas1Create the scope2Use the advancedquery builder for a…3Validate the querybefore you rely on…4Wait, then checkmembership5Attach the scope toa policyTOOLBOXGet-AdaptiveScopeMembersGet-AppRetentionCompliancePolicyGet-RecipientCustomAttribute1ExtensionCustomAttribute1How this guide is organized: How it works → Prerequisites → Step-by-step → Verify → Tips and gotchasFlow diagram of the article's sections in reading order: 1. How it works. 2. Prerequisites. 3. Step-by-step (5 steps: Create the scope; Use the advanced query builder for anything subtle; Validate the query before you rely on it; Wait, then check membership; Attach the scope to a policy). 4. Verify. 5. Tips and gotchas. Toolbox: Get-AdaptiveScopeMembers, Get-AppRetentionCompliancePolicy, Get-Recipient, CustomAttribute1, ExtensionCustomAttribute1.1How it works2Prerequisites3Step-by-step1Create the scope2Use the advanced query builder for anythingsubtle3Validate the query before you rely on it4Wait, then check membership5Attach the scope to a policy4Verify5Tips and gotchasTOOLBOXGet-AdaptiveScopeMembersGet-AppRetentionCompliancePolicyGet-RecipientCustomAttribute1ExtensionCustomAttribute1
At a glance: how this guide is organized · 5 steps · 5 key settings and tools

How it works#

An adaptive scope is a reusable query object. Its type decides what it can target and which query language it uses:

Scope typeTargetsAdvanced queryAttributes in the simple builder
UsersExchange mailboxes, OneDrive accounts, Teams chats, Viva Engage user messages, Copilot and AI app interactionsOPATHName and address fields, job title, department, office, country or region, email addresses, alias, CustomAttribute1–15, ExtensionCustomAttribute1–5
SharePoint sitesSites and OneDrive accounts (retention); sites (auto-labeling)KQLSite URL, site name, site template, RefinableString00–99
Microsoft 365 GroupsGroup mailboxes and sites, Teams channel messages, Viva Engage community messagesOPATHName, display name, description, email addresses, alias, custom attributes

User and group attributes are Exchange filterable recipient properties that map to Microsoft Entra attributes; site properties are SharePoint managed properties. Because the query runs daily, new hires and new sites join without anyone editing the policy, and an adaptive policy has no item limit.

Note: Microsoft's adaptive scopes page lists policies for retention, communication compliance and auto-labeling; the Get-AdaptiveScopeMembers reference also mentions Insider Risk Management. DLP policies aren't listed. For DLP, scope locations by users and groups or administrative units, or tighten rules for risky users with Adaptive Protection. Re-check the page, because supported solutions change.

Static or adaptive?#

For retention, each policy uses one or the other. Static is simplest when a policy covers all mailboxes or all sites. Adaptive is better when membership changes or the list is long, and it's the only way to target or exclude inactive mailboxes deliberately. Know the trade-offs:

  • Skype for Business and Exchange public folders need static scopes.
  • Adaptive scopes don't currently support Preservation Lock.
  • An adaptive policy counts as scoped under the principles of retention, so its delete action beats an org-wide policy's delete action (retention still wins over deletion).
  • One adaptive policy can cover Teams and Viva Engage together; without adaptive scopes each location needs its own policy.

Prerequisites#

  • A role group with the Scope Manager role, such as Compliance Administrator, Compliance Data Administrator, Organization Management or Records Management.
  • Reliable directory data. Agree with the Entra ID and Exchange admins which attribute holds the value and exactly how it's written.
  • For custom site properties, extra SharePoint search configuration so the value lands in a RefinableString managed property.
  • Licenses that cover adaptive scopes for the targeted users: unlicensed users can match a query but don't get the policy.

Step-by-step#

From an adaptive scope query to a retention policy that appliesStep 1: Create the scope and pick its type. Users, SharePoint sites or Microsoft 365 Groups, under Settings › Roles and scopes Step 2: Write the query in the advanced builder. OPATH for users and groups, KQL for sites; filter sites on SiteTemplate Step 3: Validate the query in PowerShell. The portal doesn't check values; run the same filter with Get-Recipient Step 4: Wait, then check membership. Up to five days to populate; use Scope details or Get-AdaptiveScopeMembers Step 5: Attach the scope to a retention policy. Choose adaptive instead of static; allow up to seven days for it to apply Step 6: Confirm with Policy lookup. Check a sample member, then DistributionStatus : Success1Create the scope and pick itstypeUsers, SharePoint sites or Microsoft365 Groups, under Settings › Rolesand scopes2Write the query in theadvanced builderOPATH for users and groups, KQLfor sites; filter sites onSiteTemplate3Validate the query inPowerShellThe portal doesn't check values;run the same filter withGet-Recipient4Wait, then checkmembershipUp to five days to populate; useScope details orGet-AdaptiveScopeMembers5Attach the scope to aretention policyChoose adaptive instead of static;allow up to seven days for it toapply6Confirm with Policy lookupCheck a sample member, thenDistributionStatus : SuccessFrom an adaptive scope query to a retention policy that appliesStep 1: Create the scope and pick its type. Users, SharePoint sites or Microsoft 365 Groups, under Settings › Roles and scopes Step 2: Write the query in the advanced builder. OPATH for users and groups, KQL for sites; filter sites on SiteTemplate Step 3: Validate the query in PowerShell. The portal doesn't check values; run the same filter with Get-Recipient Step 4: Wait, then check membership. Up to five days to populate; use Scope details or Get-AdaptiveScopeMembers Step 5: Attach the scope to a retention policy. Choose adaptive instead of static; allow up to seven days for it to apply Step 6: Confirm with Policy lookup. Check a sample member, then DistributionStatus : Success1Create the scope and pick its typeUsers, SharePoint sites or Microsoft 365 Groups, underSettings › Roles and scopes2Write the query in the advanced builderOPATH for users and groups, KQL for sites; filter siteson SiteTemplate3Validate the query in PowerShellThe portal doesn't check values; run the same filter withGet-Recipient4Wait, then check membershipUp to five days to populate; use Scope details orGet-AdaptiveScopeMembers5Attach the scope to a retention policyChoose adaptive instead of static; allow up to sevendays for it to apply6Confirm with Policy lookupCheck a sample member, then DistributionStatus :Success
Figure 1 · Process From an adaptive scope query to a retention policy that applies. Follow the steps in order: validate the query before you rely on it, and allow for the daily query and policy distribution delays.

1. Create the scope#

In the Microsoft Purview portal go to Settings › Roles and scopes › Adaptive scopes and select Create scope. If your account is restricted to administrative units, pick one; otherwise keep Full directory. Site scopes aren't available when you select an administrative unit. Choose the type and add conditions with Add attribute (or Add property for sites). The simple builder offers is equal to, is not equal to, starts with and not starts with.

2. Use the advanced query builder for anything subtle#

For users and groups it accepts OPATH with and, or, not, eq, ne, lt, gt, like and notlike; for sites it takes KQL:

Text
Users: Finance in Germany, excluding inactive mailboxes
(Department -eq "Finance") -and (CountryOrRegion -eq "Germany") -and (IsInactiveMailbox -eq "False")

Users: inactive mailboxes only
(IsInactiveMailbox -eq "True")

Sites: modern communication sites only
SiteTemplate=SITEPAGEPUBLISHING

Site scopes include every site type, so filter on SiteTemplate: GROUP (group-connected), TEAMCHANNEL (private channel sites), STS (classic team sites) or SPSPERS (OneDrive).

3. Validate the query before you rely on it#

The portal doesn't check values as you type them, so run the same filter in Exchange Online PowerShell:

PowerShell
Connect-ExchangeOnline
# User scope; Get-Recipient also returns MailUser objects (on-premises mailboxes in hybrid)
Get-Recipient -RecipientTypeDetails UserMailbox,MailUser,SharedMailbox,RoomMailbox,EquipmentMailbox `
  -Filter {(Department -eq "Finance") -and (CountryOrRegion -eq "Germany")} -ResultSize Unlimited |
  Measure-Object
# Microsoft 365 Group scope
Get-Mailbox -RecipientTypeDetails GroupMailbox -Filter {CustomAttribute15 -eq "Marketing"} -ResultSize Unlimited

EmailAddresses values usually need the smtp: prefix. For site scopes, open https://<tenant>.sharepoint.com/search as a SharePoint admin and run the KQL query.

4. Wait, then check membership#

Queries run daily and can take up to five days to populate, and later query changes take as long, so create scopes a few days before you need them. Open the scope and select Scope details: the State column shows Added for current members and Removed for members that no longer match. For large scopes use PowerShell:

PowerShell
Connect-IPPSSession
# Metadata only: total member count
(Get-AdaptiveScopeMembers -Identity "DE Finance users" -PageResultSize 0)[0].TotalMemberCount
# Current members; the first object returned is metadata
Get-AdaptiveScopeMembers -Identity "DE Finance users" -State Added | Select-Object -Skip 1

Each call returns up to 10,000 members, and the metadata carries a watermark for -PageCookie to fetch the next page.

5. Attach the scope to a policy#

When you create the retention policy, choose adaptive instead of static, add one or more scopes, and turn on the locations that scope type supports. Allow up to seven days for the policy to apply.

Verify#

  • Scope details or Get-AdaptiveScopeMembers list the members you expect. Small differences from PowerShell counts are normal (scope details include arbitration mailboxes).
  • Policy lookup in Data Lifecycle Management or Records Management shows the policy for a sample member (exact email address or site URL; no wildcards).
  • Get-RetentionCompliancePolicy -Identity "<policy>" -DistributionDetail (Get-AppRetentionCompliancePolicy for Teams chats, Viva Engage and Copilot locations) shows DistributionStatus : Success; otherwise see policy distribution errors.

Tips and gotchas: when a scope stays empty#

  • It's too new. Wait five days before changing the query.
  • The value doesn't match. A department spelled differently in HR and Entra ID, or a value with a typo, silently matches nobody. Compare with the PowerShell filter.
  • Administrative units. A scope restricted to an administrative unit only finds that unit's members, even if the attribute matches elsewhere.
  • Hybrid and unlicensed accounts. Validate with Get-Recipient or Get-User, because Get-Mailbox doesn't return MailUser objects. Synced accounts without a mailbox (Get-User -RecipientTypeDetails User) inflate counts but never get the policy.
  • Sites missing. Site scopes depend on search: test the KQL in SharePoint search and confirm custom properties are mapped. Legacy Records Center sites aren't supported.
  • Query limits. 200 characters per value, 10 attributes per group, 10 groups, no nested groups, 10,000 characters per advanced query.
  • Right members, wrong outcome. Overlapping policies follow the principles of retention; see retention policies not applying and, for mailboxes, retention policies vs litigation hold.

References#

Written and checked against current Microsoft Learn documentation. Test changes with a pilot group before rolling them out to everyone, and if an admin center path has moved since, search for the setting name instead.

Spotted a mistake, or did this fix work differently for you? Email me or message me on LinkedIn — corrections are credited in the article.

Written by

Omer Eltayeb

M365 Subject Matter Expert, former Microsoft Cloud Solutions Architect, Microsoft Certified Trainer and Microsoft Innovative Educator Expert (2024–26) and Microsoft Elevate Educator Expert (2026–27). I share practical, step-by-step guides, study plans, scripts and toolkits for Microsoft Intune, Configuration Manager, Microsoft Entra ID, Microsoft Defender, Exchange and Microsoft 365 with the community.

Microsoft Certified Trainer (MCT) 2026Microsoft Innovative Educator Expert 2025–2026Microsoft Elevate Educator Expert 2026–2027ISC2 Certified Information Systems Security Professional (CISSP)Microsoft 365 Certified: Enterprise Administrator Expert (MS-102)