diff --git a/CHANGELOG.md b/CHANGELOG.md index bca7c73d2..043ccdeb0 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`. [#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) diff --git a/documentation/Get-PnPSearchSettings.md b/documentation/Get-PnPSearchSettings.md index ed71e5924..4399cd278 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 2d1405613..130538e76 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 29a97ef4f..3b3f0eae1 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 644576082..9394bd18b 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 de8112391..16c5003f0 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 9699e21c3..fd5085805 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/Search/GetSearchSettings.cs b/src/Commands/Search/GetSearchSettings.cs index 201a1c725..8d1cf0439 100644 --- a/src/Commands/Search/GetSearchSettings.cs +++ b/src/Commands/Search/GetSearchSettings.cs @@ -1,4 +1,5 @@ -using System.Management.Automation; +using System; +using System.Management.Automation; using Microsoft.SharePoint.Client; namespace PnP.PowerShell.Commands.Search @@ -13,8 +14,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 (Exception ex) when (ex is ServerException or PropertyOrFieldNotInitializedException) + { + 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 b91f3c767..1f4f15d1f 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);