Table of Contents
New Get-AdaptiveScopeMembers Cmdlet Reveals Adaptive Scope Membership
Message center notification MC1221450 (23 January 2026) reports the addition of the Get-AdaptiveScopeMembers cmdlet, available in the latest version of the Exchange Online management module. Adaptive scopes (an E5 feature) are widely used by Purview solutions to find target locations for processing. For instance, an adaptive scope can find mailboxes to apply retention policies.
Scopes are adaptive because they are based on queries to find target objects. If the settings of an object change to match the scope, that object is found by the adaptive scope and will be processed. Different approaches can be taken to populate the targets of an adaptive scope. For example, here’s how to use the membership of a dynamic group with an adaptive scope.
Programmatic Reporting of Scope Targets
Adding a user, group, or site to an adaptive scope is not an immediate operation. Background processes that you cannot control must run to evaluate the scope query and determine which directory objects match. It can take between two and five days for the process to complete, so waiting for adjustments to adaptive scope membership is a waiting game. Until now, the only way to check the membership of an adaptive scope is by examining scope details through the Purview compliance portal (Figure 1).

The new Get-AdaptiveScopeMembers cmdlet is a programmatic way to report the membership of an adaptive scope. It is relatively easy to extract the membership for scopes targeted at user accounts and Microsoft 365 groups because the scope filter can be resolved with the Get-Recipient cmdlet. However, things aren’t quite so easy for scopes targeted at SharePoint Online sites and OneDrive accounts. The Get-AdaptiveScopeMembers cmdlet handles both types of scope. It also reports members that have been added and removed from a scope.
Adaptive Scope Membership in Action
The results of Get-AdaptiveScopeMembers are divided into a summary record (aka, result metadata) for the scope with subsequent records holding details for individual members. Here’s an example of a summary record:
TotalMemberCount : 7 CurrentPageMemberCount : 7 Watermark : IsLastPage : True Identity : office365itpros.onmicrosoft.com\Executive Mailboxes IsValid : True ObjectState : Unchanged
Member records capture details of member additions and removals. This is an example of a record for a user being added to a scope. The LocationType property can also be Group (Microsoft 365 Group) or Site (SharePoint Online site or OneDrive account).
LocationType : User State : Added EventDateTime : 10/26/2021 16:02:32 +00:00 DisplayName : James.A.Abrahams@office365itpros.com MailboxGuid : 4ee41d66-5ab0-4570-8707-6c865804f55e SmtpAddress : James.A.Abrahams@office365itpros.com ObjectId : d446f6d7-5728-44f8-9eac-71adb354fc89 SiteUrl : SiteId : 00000000-0000-0000-0000-000000000000 Upn : James.A.Abrahams@office365itpros.com
The EventDateTime property is when the background process added or removed an object from the scope. It’s an odd date format that needs a little manipulation to generate a printable date in PowerShell.
The ObjectId property is the GUID for the user’s Entra ID account. You can use it with the Get-MgUser cmdlet to fetch details of the account:
Get-MgUser -UserId $Members.ObjectId
The error handling for the Get-AdaptiveScopeMembers cmdlet could be better. If you attempt to fetch the membership of an empty scope (one with no members), the response isn’t very helpful.
Get-AdaptiveScopeMembers -Identity 'French IT Architects' Get-AdaptiveScopeMembers: Failed to get adaptive scope members response. Status: Request failed with status code NotFound for AdaptiveScopeReport: 3e275435-aa56-4578-803c-5324f732b0e5, InnerException: , StackTrace: at Microsoft.Office.CompliancePolicy.Tasks.ComplianceWorkbenchClient.GetAdaptiveLocationAsync(String policyOrScopeId, Int32 adaptiveReportTenantShardId, String query, Boolean isPolicyLocation) at Microsoft.Office.CompliancePolicy.Tasks.GetAdaptiveScopeMembers.GetAdaptiveLocationsResponse(String policyOrScopeId,String query).
To avoid unsightly errors, it’s best to do something like this:
$ScopeName = "Permanent Employees”
[array]$Membership = Get-AdaptiveScopeMembers -Identity $ScopeName -ErrorAction SilentlyContinue
If (!($Membership)) {
Write-Output ("No members found for {0} scope" -f $ScopeName )
} Else {
Write-Output ("{0} members found in {1} scope" -f $Membership.count, $ScopeName)
}
By default, the Get-AdaptiveScopeMembers cmdlet fetches the first 10,000 members. The PageResultSize parameter gives control over how many records the cmdlet fetches. You can set the value to Unlimited to fetch all. According to the documentation, Microsoft doesn’t recommend this approach because it might lead to long-running queries.
[array]$Members = Get-AdaptiveScopeMembers -Identity $Scope.Name -PageResultSize Unlimited -ErrorAction SilentlyContinue
In larger tenants, you might need to retrieve successive pages of membership records until all available data is fetched. The summary record in the results contains a watermark (called nextlink for Graph pagination) to fetch the next set of records. Here’s an example where a watermark is returned after fetching 100 member records:
TotalMemberCount : 142 CurrentPageMemberCount : 100 Watermark : H4sIAAAAAAAACh2R207CUBBF16cYYhQTm2gQRBMfUEEU8QJWlBdTsVwCIpSLEeO/u9qcTDN7z549c05/yTEzTo1tlnyJziiyI+ozYiIXk8jl6RGxEOdp+42yyj5b7GY4UT1lINqTi5lnlQofnthI+dS154yVyqWeadfKasovGOswy3YYy02tX1Ewr3iqzhhmUzsEvHFBVzZko6Jr7YAWTbUDFS3RtU5DlT01oXmbsvmEW0ocOSHmUfepWZUnq3PROQ07E7m1rg/id545NrrUudch4pBLNx1x4i6B/R2ZunMb3rCkx8ZTM0+cEOlaUzHWq+/0kkzgtKbZj3e4853XvHDDt8ynW1Z1TW8a8Wr/wn1De8tqC35zvnZONv1bRf74B8DSM628AQAA IsLastPage : False
We can see that 42 remaining members must be fetched. Using the watermark from the first members record, we can do the following to fetch the 42 records:
$Watermark = $Members[0].Watermark [array]$NextMembers = Get-AdaptiveScopeMembers -Identity $Scope.Name -PageCookie $Watermark $Members = $Members + $NextMembers
If more pages of data were available, the process of fetching pages would continue until no more data remains and the IsLastPage property is True. An example of fetching membership results page by page is available online.
Example Script
After understanding the basics of fetching scope members with the Get-AdaptiveScopeMembers cmdlet, let’s create a report to allow administrators to review the membership of the adaptive scopes defined in a tenant. I wrote a PowerShell script to do the job, which you can download from the Office 365 for IT Pros GitHub repository.
Figure 2 shows an extract from the HTML report generated by the script. Notice the warnings when mailboxes cannot be found. Adaptive scopes keep deleted objects in their membership. I’m not quite sure why this happens because some of the mailboxes are not inactive mailboxes retained because of a policy or retention label.

Microsoft seems to have put a fair amount of effort into developing the cmdlet, so customer demand for such a facility must exist. It will be interesting to see how Microsoft 365 tenants use the Get-AdaptiveScopeMembers cmdlet in production.
Need help to write and manage PowerShell scripts for Microsoft 365, including Azure Automation runbooks? Get a copy of the Automating Microsoft 365 with PowerShell eBook, available standalone or as part of the Office 365 for IT Pros eBook bundle (incredible value!)