Applies to: SharePoint Online, Microsoft 365 Copilot, SharePoint Online Management Shell, Microsoft Graph PowerShell
Level: Intermediate to Advanced | Purpose: Educational
The Symptom
A user who has a Microsoft 365 Copilot license opens a SharePoint site. The Copilot (agent) icon is missing from the global header, so the header shows only Announcements, Settings and Help. On other sites, the same user sees the icon.
Root Causes at a Glance
| # | Cause | Scope | Where to check | Who fixes it |
|---|---|---|---|---|
| 1 | No Microsoft 365 Copilot license, or the Microsoft Copilot in SharePoint service plan is disabled | User | Microsoft Graph PowerShell / M365 admin center | License admin |
| 2 | KnowledgeAgentScope excludes the site (NoSites, an allow-list that doesn't include it, or a block-list that does) | Tenant | SharePoint Online Management Shell (no UI) | SharePoint admin |
| 3 | Restricted Content Discovery (RCD) is On for the site | Site | SharePoint admin center → Active sites → Settings | SharePoint admin |
| 4 | Site AI settings: Copilot hidden for visitors, or the Main agent points to a broken custom agent | Site | Site → Settings (gear) → Site AI | Site owner |
| 5 | Cached session or browser extension | Client | InPrivate / Incognito window | User |
Key insight: once a valid license is confirmed, a missing icon on a single site is almost always a site or tenant scoping problem, not a user problem. Test one other site first. If Copilot appears there, skip straight to checks 2–4.
Step 1 – Rule Out the Browser (2 minutes)
- Open the site in an InPrivate/Incognito window and sign in again.
- Open a second site where you'd expect Copilot. If it shows there but not on the first site, the problem is limited to that site.
Step 2 – Verify the License Service Plan
The service plan that drives Copilot in SharePoint is M365_COPILOT_SHAREPOINT (ID 0aedf20c-091d-420b-aadf-30c042609612).
Connect-MgGraph -Scopes "User.Read.All" -NoWelcome
$upn = "user@contoso.com"
Get-MgUserLicenseDetail -UserId $upn | ForEach-Object {
$_.ServicePlans | Where-Object { $_.ServicePlanId -eq "0aedf20c-091d-420b-aadf-30c042609612" }
} | Select-Object ServicePlanName, ProvisioningStatus
| Result | Meaning |
|---|---|
Success | License is fine, so move on to the site and tenant checks |
No output / Disabled | Assign a Copilot license or enable the service plan, then allow time for it to take effect |
Note: Copilot Chat on its own does not add the SharePoint header icon. A paid Microsoft 365 Copilot license is required.
Step 3 – Check Restricted Content Discovery (UI)
- SharePoint admin center → Sites → Active sites.
- Select the site → Settings tab.
- Check Restrict content discovery. If it's On, Copilot is hidden on that site whatever the other settings are.
PowerShell equivalent: Get-SPOSite -Identity <url> | Select-Object RestrictContentOrgWideSearch
Caution: RCD is usually turned on for a governance reason, such as oversharing risk or a pending permissions review. Confirm with the governance owner before turning it off.
Step 4 – Check Site AI Settings (UI)
Site → Settings (gear) → Site AI. Site owners can:
- Choose the Main agent that opens from the header icon (Copilot in SharePoint or a custom agent).
- Hide the Copilot button for site visitors.
Tip: if the Main agent points to a custom .agent file that was moved, deleted or restricted, the icon may have nothing to open. Switch the Main agent back to the default to test.
Step 5 – Check the Tenant Scope (PowerShell Only)
This is the check most often missed, because there's no admin-center UI for it.
Connect-SPOService -Url https://contoso-admin.sharepoint.com
Get-SPOTenant | Select-Object KnowledgeAgentScope, KnowledgeAgentSelectedSitesList
| KnowledgeAgentScope | Behaviour | Fix |
|---|---|---|
NoSites (default) | Copilot in SharePoint is off on every site | Change the scope (affects the whole tenant) |
AllSites | On everywhere | Not the cause |
IncludeSelectedSites | Allow-list: only listed sites get Copilot | Append the site to the list |
ExcludeSelectedSites | Block-list: listed sites don't get Copilot | Remove the site from the list |
The output truncates long lists, so expand it to check:
$list = (Get-SPOTenant).KnowledgeAgentSelectedSitesList
$list.Count
$list -contains "https://contoso.sharepoint.com/sites/Engineering"
Safely Adding a Site to the Allow-List
# 1. Back up the current list
(Get-SPOTenant).KnowledgeAgentSelectedSitesList | Out-File .\KnowledgeAgentSites_backup.txt
# 2. Append (never omit the Operation parameter)
Set-SPOTenant -KnowledgeAgentSelectedSitesList @("https://contoso.sharepoint.com/sites/Engineering") `
-KnowledgeAgentSelectedSitesListOperation Append
# 3. Verify
(Get-SPOTenant).KnowledgeAgentSelectedSitesList.Count
-KnowledgeAgentSelectedSitesListOperation is Overwrite. If you run Set-SPOTenant -KnowledgeAgentSelectedSitesList "url" without Append, the entire allow-list is replaced with that one site, and Copilot disappears from every other listed site. Always back up first and always specify Append or Remove.
Bonus: One-Shot Read-Only Diagnostic Script
This script runs every check in one go and changes nothing. Run it in Windows PowerShell 5.1 (see the next section for why).
param(
[Parameter(Mandatory)] [string]$AdminUrl,
[Parameter(Mandatory)] [string]$SiteUrl,
[Parameter(Mandatory)] [string]$UserPrincipalName
)
$SiteUrl = $SiteUrl.TrimEnd('/')
# License
Connect-MgGraph -Scopes "User.Read.All" -NoWelcome
$plan = Get-MgUserLicenseDetail -UserId $UserPrincipalName |
ForEach-Object { $_.ServicePlans } |
Where-Object { $_.ServicePlanId -eq "0aedf20c-091d-420b-aadf-30c042609612" }
# Tenant and site
Connect-SPOService -Url $AdminUrl
$tenant = Get-SPOTenant
$site = Get-SPOSite -Identity $SiteUrl
$inList = ($tenant.KnowledgeAgentSelectedSitesList | ForEach-Object { $_.TrimEnd('/') }) -contains $SiteUrl
switch ($tenant.KnowledgeAgentScope) {
"AllSites" { $scopeOk = $true }
"IncludeSelectedSites" { $scopeOk = $inList }
"ExcludeSelectedSites" { $scopeOk = -not $inList }
default { $scopeOk = $false }
}
if ($plan -and $plan.ProvisioningStatus -eq "Success") {
$licenseOk = $true
} else {
$licenseOk = $false
}
[pscustomobject]@{
LicensePlanOk = $licenseOk
TenantScope = $tenant.KnowledgeAgentScope
SiteInSelectedList = $inList
TenantScopeAllowsSite = $scopeOk
RestrictContentDiscovery = $site.RestrictContentOrgWideSearch
LikelyVisible = ($licenseOk -and $scopeOk -and -not $site.RestrictContentOrgWideSearch)
} | Format-List
If LikelyVisible is True and the icon is still missing, check the Site AI Main agent setting (Step 4) and the browser cache (Step 1).
Common PowerShell Hurdles (and Fixes)
| Error | Cause | Fix |
|---|---|---|
Connect-SPOService is not recognized | The module isn't installed or isn't loaded | Install-Module Microsoft.Online.SharePoint.PowerShell -Scope CurrentUser |
| The type initializer for 'Microsoft.Identity.Client.NativeInterop.API' threw an exception / No valid OAuth 2.0 authentication session exists | The WAM sign-in broker fails when the module runs in PowerShell 7 | Open Windows PowerShell 5.1 from the Start menu, not by typing powershell.exe inside PowerShell 7 |
| Module is installed but 5.1 says "no valid module file was found" | The module was installed to a folder (often a redirected Documents folder) that isn't in $env:PSModulePath | Use Save-Module to a known folder and import it by path (see below) |
| A parameter cannot be found that matches parameter name 'KnowledgeAgentScope' | An old module version is loaded | Uninstall all versions, then install the latest (16.0.26615.12013 or later) |
# Portable module load (works even with redirected profile folders)
New-Item -Path C:\PSMods -ItemType Directory -Force | Out-Null
Save-Module -Name Microsoft.Online.SharePoint.PowerShell -Path C:\PSMods -Force
$psd1 = Get-ChildItem C:\PSMods\Microsoft.Online.SharePoint.PowerShell -Recurse `
-Filter Microsoft.Online.SharePoint.PowerShell.psd1 | Select-Object -First 1
Import-Module $psd1.FullName -DisableNameChecking
Why does launching powershell.exe from PowerShell 7 not help? The child 5.1 process inherits PowerShell 7's PSModulePath, so its module discovery gets confused. Always start 5.1 fresh from the Start menu.
Plan Ahead: The November 1, 2026 Change
With Copilot in SharePoint now generally available, Microsoft is retiring the preview-era PowerShell controls (KnowledgeAgentScope, KnowledgeAgentSelectedSitesList, KnowledgeAgentSelectedSitesListOperation).
| Period | What controls visibility |
|---|---|
| Until 1 Nov 2026 | The PowerShell scope and allow-/block-lists are still honoured |
| After 1 Nov 2026 | Site AI settings (site owner) and Restricted Content Discovery (admin) |
Recommendation: if your tenant relies on an IncludeSelectedSites allow-list to limit Copilot, that boundary goes away after the retirement date. Before then:
- Export the current list for your records.
- Decide which of the sites outside the list really need to stay hidden from Copilot.
- Apply Restricted Content Discovery to those sites. Catalog management can apply it in bulk.
- Brief site owners on the Site AI panel, since they now control the header agent.
Quick Decision Flow
| Question | If NO | If YES |
|---|---|---|
| Does Copilot show in an InPrivate window? | Go to the next question | Clear cache / disable extensions |
Is M365_COPILOT_SHAREPOINT = Success? | Fix the license | Go to the next question |
| Is RCD Off for the site? | Review RCD with governance | Go to the next question |
| Does the tenant scope allow the site? | Append to / remove from the list | Go to the next question |
| Does Site AI point to a valid agent, with Copilot not hidden? | Fix the Site AI setting | Open a Microsoft support case |
References
- Get started with Copilot in SharePoint
- Restrict discovery of SharePoint sites and content
- Set-SPOTenant
- Microsoft Copilot service plans
- Manage access to agents in SharePoint
Disclaimer: This article is for educational purposes. All tenant names, URLs and accounts are illustrative (contoso). Test changes in a non-production tenant and follow your organisation's change process.