From 6201c650458448e433f367c44a315cfac36ab644 Mon Sep 17 00:00:00 2001 From: Mikael Svenson <51104+wobba@users.noreply.github.com> Date: Fri, 25 Sep 2026 15:37:37 +0200 Subject: [PATCH 1/4] Add Copilot Search site and tenant settings Adds -CopilotSearchOptOut to Set-PnPSearchSettings (exposed by Get-PnPSearchSettings) and -CopilotSearchOptIn to Set-PnPTenant (exposed by Get-PnPTenant), using the typed CSOM properties from Microsoft.SharePointOnline.CSOM 16.1.27709.12000. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 1 + documentation/Get-PnPSearchSettings.md | 12 ++++++++--- documentation/Get-PnPTenant.md | 9 +++++++- documentation/Set-PnPSearchSettings.md | 24 ++++++++++++++++++++-- documentation/Set-PnPTenant.md | 22 ++++++++++++++++++++ src/Commands/Admin/SetTenant.cs | 8 ++++++++ src/Commands/Model/SPOTenant.cs | 13 ++++++++++++ src/Commands/PnP.PowerShell.Release.csproj | 2 +- src/Commands/PnP.PowerShell.csproj | 2 +- src/Commands/Search/GetSearchSettings.cs | 12 ++++++++++- src/Commands/Search/SetSearchSettings.cs | 13 ++++++++++++ 11 files changed, 109 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bca7c73d2c..7e990a4e59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added - Added `Get-PnPPersistedLogin` which lists the tenant url, client id and authentication type of every login registered to use the local token cache, so the cache can be inspected without reading it. [#5463](https://github.com/pnp/powershell/pull/5463) - Added `-PersistLogin` to the certificate based app only parameter sets of `Connect-PnPOnline`, so a connection made with `-CertificatePath`, `-CertificateBase64Encoded`, `-Thumbprint` or the environment variables can reuse its access token from the local cache. The certificate, tenant and client id are still required on each connection, as neither the certificate nor its password is stored. [#5463](https://github.com/pnp/powershell/pull/5463) +- Added `-CopilotSearchOptOut` to `Set-PnPSearchSettings` and exposed the value through `Get-PnPSearchSettings`; added `-CopilotSearchOptIn` to `Set-PnPTenant` and exposed the value through `Get-PnPTenant`. ### Changed - Changed `Connect-PnPOnline` to write verbose message on which stored credential it resolved for the url, as it previously picked one up from the credential manager without saying so. [#5463](https://github.com/pnp/powershell/pull/5463) diff --git a/documentation/Get-PnPSearchSettings.md b/documentation/Get-PnPSearchSettings.md index ed71e59248..4399cd278a 100644 --- a/documentation/Get-PnPSearchSettings.md +++ b/documentation/Get-PnPSearchSettings.md @@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Get-PnPSearchSettings.h # Get-PnPSearchSettings ## SYNOPSIS -Retrieves search settings for a site +Retrieves search settings for a site, including whether the site collection has opted out of Copilot Search. ## SYNTAX @@ -20,7 +20,7 @@ Get-PnPSearchSettings [-Connection ] ## DESCRIPTION -Allows to retrieve search settings for a site. +Allows to retrieve search settings for a site. The returned object includes the site collection-level `CopilotSearchOptOut` setting. If the setting is not available yet on the tenant, its value is `$null` and a warning is shown. ## EXAMPLES @@ -31,6 +31,13 @@ Get-PnPSearchSettings Retrieve search settings for the site +### EXAMPLE 2 +```powershell +(Get-PnPSearchSettings).CopilotSearchOptOut +``` + +Returns whether the current site collection has opted out of Copilot Search. + ## PARAMETERS ### -Connection @@ -52,4 +59,3 @@ Accept wildcard characters: False ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - diff --git a/documentation/Get-PnPTenant.md b/documentation/Get-PnPTenant.md index 2d14056135..130538e76a 100644 --- a/documentation/Get-PnPTenant.md +++ b/documentation/Get-PnPTenant.md @@ -25,7 +25,7 @@ Get-PnPTenant [-Verbose] [-Connection ] ## DESCRIPTION Returns organization-level site collection properties such as StorageQuota, StorageQuotaAllocated, ResourceQuota, -ResourceQuotaAllocated, and SiteCreationMode. The returned object also includes newer tenant settings and telemetry-backed values when available, such as OneDrive organization sharing link expiration settings, block download configuration, request digest enforcement, notification subscription support, content type sync templates, external sharing restrictions, and file version policy overrides. +ResourceQuotaAllocated, and SiteCreationMode. The returned object also includes newer tenant settings and telemetry-backed values when available, such as the Copilot Search opt-in, OneDrive organization sharing link expiration settings, block download configuration, request digest enforcement, notification subscription support, content type sync templates, external sharing restrictions, and file version policy overrides. If one or more properties cannot be retrieved, such as when a property is not available yet on the tenant due to a new feature rollout, a warning will be shown. Use -Verbose to see detailed information on properties that could not be retrieved. @@ -54,6 +54,13 @@ $tenant | Select-Object OneDriveOrganizationSharingLinkMaxExpirationInDays, OneD This example inspects OneDrive sharing link expiration settings together with list-based tenant restrictions and version policy overrides. +### EXAMPLE 4 +```powershell +(Get-PnPTenant).CopilotSearchOptIn +``` + +Returns whether the tenant has opted in to Copilot Search. + ## PARAMETERS ### -Connection diff --git a/documentation/Set-PnPSearchSettings.md b/documentation/Set-PnPSearchSettings.md index 29a97ef4f9..3b3f0eae15 100644 --- a/documentation/Set-PnPSearchSettings.md +++ b/documentation/Set-PnPSearchSettings.md @@ -15,7 +15,7 @@ Sets search settings for a site. ## SYNTAX ```powershell -Set-PnPSearchSettings [-SearchBoxInNavBar ] [-SearchPageUrl ] +Set-PnPSearchSettings [-CopilotSearchOptOut ] [-SearchBoxInNavBar ] [-SearchPageUrl ] [-SearchBoxPlaceholderText ] [-SearchScope ] [-Scope ] [-Force] [-Connection ] ``` @@ -75,6 +75,13 @@ Set-PnPSearchSettings -SearchScope Hub Sets default behavior of the suite bar search box to show hub results instead of site results on an associated hub site. +### EXAMPLE 8 +```powershell +Set-PnPSearchSettings -CopilotSearchOptOut $true +``` + +Opts the current site collection out of Copilot Search. The setting is stored on the site collection regardless of the value of `-Scope`. + ## PARAMETERS ### -Connection @@ -91,6 +98,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -CopilotSearchOptOut +Specifies whether the current site collection is opted out of Copilot Search. The setting is stored on the site collection and requires `ManageWeb` permission. + +```yaml +Type: Boolean +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Force Do not ask for confirmation. @@ -181,4 +202,3 @@ Accept wildcard characters: False ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - diff --git a/documentation/Set-PnPTenant.md b/documentation/Set-PnPTenant.md index 644576082f..9394bd18b6 100644 --- a/documentation/Set-PnPTenant.md +++ b/documentation/Set-PnPTenant.md @@ -188,6 +188,7 @@ Set-PnPTenant [-SpecialCharactersStateInFileFolderNames [-EnableMediaReactions ] [-ResyncContentSecurityPolicyConfigurationEntries] [-ContentSecurityPolicyEnforcement ] + [-CopilotSearchOptIn ] [-DisableSpacesActivation ] [-CoreOrganizationSharingLinkRecommendedExpirationInDays ] [-CoreOrganizationSharingLinkMaxExpirationInDays ] @@ -271,6 +272,13 @@ Set-PnPTenant -ResyncContentSecurityPolicyConfigurationEntries This example requests a resync of Content Security Policy trusted script sources for SharePoint Framework solutions in the tenant app catalog and reads back whether the resync request is still pending. +### EXAMPLE 10 +```powershell +Set-PnPTenant -CopilotSearchOptIn $true +``` + +This example opts the tenant in to Copilot Search. + ## PARAMETERS ### -AllowDownloadingNonWebViewableFiles @@ -552,6 +560,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -CopilotSearchOptIn +Specifies whether the tenant is opted in to Copilot Search. + +```yaml +Type: Boolean +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -DelayContentSecurityPolicyEnforcement Delays the Content security policy enforcement by 90 days, until June 1, 2026. diff --git a/src/Commands/Admin/SetTenant.cs b/src/Commands/Admin/SetTenant.cs index de8112391f..16c5003f0e 100644 --- a/src/Commands/Admin/SetTenant.cs +++ b/src/Commands/Admin/SetTenant.cs @@ -585,6 +585,9 @@ public class SetTenant : PnPSharePointOnlineAdminCmdlet [Parameter(Mandatory = false)] public bool? ContentSecurityPolicyEnforcement { set; get; } + [Parameter(Mandatory = false)] + public bool? CopilotSearchOptIn { set; get; } + [Parameter(Mandatory = false)] public bool? DisableSpacesActivation { set; get; } @@ -1828,6 +1831,11 @@ protected override void ExecuteCmdlet() Tenant.ContentSecurityPolicyEnforcement = ContentSecurityPolicyEnforcement.Value; modified = true; } + if (CopilotSearchOptIn.HasValue) + { + Tenant.CopilotSearchOptIn = CopilotSearchOptIn.Value; + modified = true; + } if (DisableSpacesActivation.HasValue) { Tenant.DisableSpacesActivation = DisableSpacesActivation.Value; diff --git a/src/Commands/Model/SPOTenant.cs b/src/Commands/Model/SPOTenant.cs index 9699e21c3f..fd5085805e 100644 --- a/src/Commands/Model/SPOTenant.cs +++ b/src/Commands/Model/SPOTenant.cs @@ -363,6 +363,9 @@ public class SPOTenant public bool? ContentSecurityPolicyConfigSynced { get; private set; } + [CsomToModelConverter(Skip = true)] + public bool? CopilotSearchOptIn { get; private set; } + public bool? CoreDefaultLinkToExistingAccess { get; private set; } public string CustomizedExternalSharingServiceUrl { get; private set; } @@ -650,6 +653,16 @@ public SPOTenant(Tenant tenant, ClientContext clientContext, BasePSCmdlet cmdlet cmdlet.LogDebug($"Property ContentTypeSyncSiteTemplatesList not loaded due to error '{e.Message}'"); } + try + { + CopilotSearchOptIn = tenant.EnsureProperty(t => t.CopilotSearchOptIn); + } + catch (Exception e) + { + failedProperties++; + cmdlet.LogDebug($"Property CopilotSearchOptIn not loaded due to error '{e.Message}'"); + } + ResyncContentSecurityPolicyConfigurationEntries = ContentSecurityPolicyConfigSynced.HasValue ? !ContentSecurityPolicyConfigSynced.Value : null; diff --git a/src/Commands/PnP.PowerShell.Release.csproj b/src/Commands/PnP.PowerShell.Release.csproj index 6a16cb0fde..966f836c66 100644 --- a/src/Commands/PnP.PowerShell.Release.csproj +++ b/src/Commands/PnP.PowerShell.Release.csproj @@ -43,7 +43,7 @@ - + diff --git a/src/Commands/PnP.PowerShell.csproj b/src/Commands/PnP.PowerShell.csproj index eb84d817e0..dca46d2e5b 100644 --- a/src/Commands/PnP.PowerShell.csproj +++ b/src/Commands/PnP.PowerShell.csproj @@ -52,7 +52,7 @@ - + diff --git a/src/Commands/Search/GetSearchSettings.cs b/src/Commands/Search/GetSearchSettings.cs index 201a1c7254..73c8bfabd6 100644 --- a/src/Commands/Search/GetSearchSettings.cs +++ b/src/Commands/Search/GetSearchSettings.cs @@ -1,4 +1,4 @@ -using System.Management.Automation; +using System.Management.Automation; using Microsoft.SharePoint.Client; namespace PnP.PowerShell.Commands.Search @@ -13,8 +13,18 @@ protected override void ExecuteCmdlet() string siteUrl = ClientContext.Web.GetSiteCollectionSearchCenterUrl(); string webUrl = ClientContext.Web.GetWebSearchCenterUrl(urlOnly: true); + bool? copilotSearchOptOut = null; + try + { + copilotSearchOptOut = ClientContext.Site.EnsureProperty(s => s.CopilotSearchOptOut); + } + catch (ServerException ex) + { + LogWarning($"The CopilotSearchOptOut setting could not be retrieved: {ex.Message}"); + } PSObject res = new PSObject(); + res.Properties.Add(new PSNoteProperty("CopilotSearchOptOut", copilotSearchOptOut)); res.Properties.Add(new PSNoteProperty("Classic Search Center URL", siteUrl)); res.Properties.Add(new PSNoteProperty("Redirect search URL", webUrl)); res.Properties.Add(new PSNoteProperty("Site Search Scope", ClientContext.Web.SearchScope)); diff --git a/src/Commands/Search/SetSearchSettings.cs b/src/Commands/Search/SetSearchSettings.cs index b91f3c7670..1f4f15d1f9 100644 --- a/src/Commands/Search/SetSearchSettings.cs +++ b/src/Commands/Search/SetSearchSettings.cs @@ -21,6 +21,9 @@ public class SetSearchSettings : PnPWebCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)] public SearchScopeType? SearchScope; + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)] + public bool? CopilotSearchOptOut; + [Parameter(Mandatory = false)] public SearchSettingsScope Scope = SearchSettingsScope.Web; @@ -70,6 +73,16 @@ protected override void ExecuteCmdlet() } } + if (CopilotSearchOptOut.HasValue) + { + ClientContext.Site.CopilotSearchOptOut = CopilotSearchOptOut.Value; + if (!SearchBoxInNavBar.HasValue && !hasSearchPageUrl && !hasSearchPlaceholderText && !SearchScope.HasValue) + { + ClientContext.ExecuteQueryRetry(); + return; + } + } + if (this.Scope == SearchSettingsScope.Site) { ClientContext.Site.RootWeb.EnsureProperty(w => w.SearchScope); From 093c0a71b428b36615aa3c3f6f70cae8964ef252 Mon Sep 17 00:00:00 2001 From: Mikael Svenson <51104+wobba@users.noreply.github.com> Date: Fri, 25 Sep 2026 15:43:17 +0200 Subject: [PATCH 2/4] Keep CSOM on floating 16.1.* version Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/Commands/PnP.PowerShell.Release.csproj | 2 +- src/Commands/PnP.PowerShell.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/PnP.PowerShell.Release.csproj b/src/Commands/PnP.PowerShell.Release.csproj index 966f836c66..6a16cb0fde 100644 --- a/src/Commands/PnP.PowerShell.Release.csproj +++ b/src/Commands/PnP.PowerShell.Release.csproj @@ -43,7 +43,7 @@ - + diff --git a/src/Commands/PnP.PowerShell.csproj b/src/Commands/PnP.PowerShell.csproj index dca46d2e5b..eb84d817e0 100644 --- a/src/Commands/PnP.PowerShell.csproj +++ b/src/Commands/PnP.PowerShell.csproj @@ -52,7 +52,7 @@ - + From d638ac4e152ab00015f9dcdb807835be6db8fc92 Mon Sep 17 00:00:00 2001 From: Mikael Svenson <51104+wobba@users.noreply.github.com> Date: Fri, 25 Sep 2026 15:44:51 +0200 Subject: [PATCH 3/4] Add PR link to changelog entry Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e990a4e59..043ccdeb00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added - Added `Get-PnPPersistedLogin` which lists the tenant url, client id and authentication type of every login registered to use the local token cache, so the cache can be inspected without reading it. [#5463](https://github.com/pnp/powershell/pull/5463) - Added `-PersistLogin` to the certificate based app only parameter sets of `Connect-PnPOnline`, so a connection made with `-CertificatePath`, `-CertificateBase64Encoded`, `-Thumbprint` or the environment variables can reuse its access token from the local cache. The certificate, tenant and client id are still required on each connection, as neither the certificate nor its password is stored. [#5463](https://github.com/pnp/powershell/pull/5463) -- Added `-CopilotSearchOptOut` to `Set-PnPSearchSettings` and exposed the value through `Get-PnPSearchSettings`; added `-CopilotSearchOptIn` to `Set-PnPTenant` and exposed the value through `Get-PnPTenant`. +- Added `-CopilotSearchOptOut` to `Set-PnPSearchSettings` and exposed the value through `Get-PnPSearchSettings`; added `-CopilotSearchOptIn` to `Set-PnPTenant` and exposed the value through `Get-PnPTenant`. [#5478](https://github.com/pnp/powershell/pull/5478) ### Changed - Changed `Connect-PnPOnline` to write verbose message on which stored credential it resolved for the url, as it previously picked one up from the credential manager without saying so. [#5463](https://github.com/pnp/powershell/pull/5463) From 72b7e1c5b026bfedce910e3de0ca7625e224ef00 Mon Sep 17 00:00:00 2001 From: Mikael Svenson <51104+wobba@users.noreply.github.com> Date: Fri, 25 Sep 2026 16:01:59 +0200 Subject: [PATCH 4/4] Also warn when CopilotSearchOptOut is not initialized Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/Commands/Search/GetSearchSettings.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Commands/Search/GetSearchSettings.cs b/src/Commands/Search/GetSearchSettings.cs index 73c8bfabd6..8d1cf04396 100644 --- a/src/Commands/Search/GetSearchSettings.cs +++ b/src/Commands/Search/GetSearchSettings.cs @@ -1,3 +1,4 @@ +using System; using System.Management.Automation; using Microsoft.SharePoint.Client; @@ -18,7 +19,7 @@ protected override void ExecuteCmdlet() { copilotSearchOptOut = ClientContext.Site.EnsureProperty(s => s.CopilotSearchOptOut); } - catch (ServerException ex) + catch (Exception ex) when (ex is ServerException or PropertyOrFieldNotInitializedException) { LogWarning($"The CopilotSearchOptOut setting could not be retrieved: {ex.Message}"); }