With the PnP PowerShell extensions we have a lot of cmdlets to customize our sites in SharePoint Online. There are also cmdlets to move the search configuration from a development environment to a test or production environment. That makes it simple to create new solutions in SharePoint Online. This walkthrough will show how we can configure the search configuration in our development environment and how to prepare a PowerShell script for deployment. You should be somewhat familiar with the configuration options via the web interface in SharePoint Online.

In this example we start with a simple team site. Using PowerShell we create a new library called “Library” (keep it simple) and in this library a new text field called “Freetext”. As we know in SharePoint, when we store documents in the library and store data in the field, the crawler will create a new crawled property. We will use this crawled property to create a new managed property. Additionally we will connect the crawled property to one of the managed properties prepared for the refinement. To restrict the search results to our site collection we will create a new result source. To test and use our search configuration we will create a subsite with the basic search center. In this search center we will modify the search results webpart and the refinement webpart. Finally we will create one single script to deploy our customizations to a new site collection. Let’s go.

A site collection we can use for our development steps is already created in SharePoint Online. First we will create our library and its field. This could be done with a simple PowerShell script (the first part of our deployment script):

$list = New-PnPList -Title "Library" -Template DocumentLibrary -Url "Library" -OnQuicklaunch

$field = Add-PnPField -List "Library" -DisplayName "Freetext" -InternalName "Freetext" -Type Text -AddToDefaultView

Next we need to upload a document to this new library and set the value of our field. This is necessary to create the crawled property in the search configuration. Now we need a little patience, because the crawler needs to crawl the content of our library. It might take 5-10min until the document and the metadata appears in the search results (you can test this using the search box in the top right of the site collection).

Now we can start modifying the search configuration. We will do this using the web interface and the site settings of our development site. We open the site settings and click the link “Search Schema” in the Site Collection Administration section. Next click the “New Managed Property” link. Enter a name for the property (do not use spaces or special characters in the name field), mark the property as

  • Searchable
  • Queryable
  • Retrievable

Scroll down to the section for the “Mappings to crawled properties” and click the “Add a Mapping” button. Search for the crawled property that matches to the field (in our case “ows_Freetext”) and add it to the mappings as we see in the following image.

Scroll down and click the OK button to create the managed property.

Now we need to configure the managed property for the refinements. The starting point is the search schema again. In the filter box for the managed properties search for “refinablestring”.

Click one of the properties found that does not have a mapped crawled property. This will open the settings for this managed property. Scroll down to the section for the “Mappings to crawled properties” and click the “Add a Mapping” button. Search for the crawled property that matches to the field (in our case “ows_Freetext”) and add it to the mappings. That were all settings we need to do in the search schema.

Next we will create a new result source that we use in the search results webpart to limit the search results to the current site collection. In the site settings of the site collection we click the link “Search Result Sources” in the Site Collection Administration section. Click the link “New Result Source”. Type a name for the result source (I used “Current Site Collection”) and scroll down to the Query Transform section. Click the button “Launch Query Builder”. In the Property Filter combobox select “–Show all managed properties–“. That is necessary, because we need to choose the property “SPSiteURL”. As the value select “This site collection”. The query should look like this, after you clicked “Add property filter”.

Now, after we have finalized our necessary search configuration, we can do the export of the configuration. To do this, we have two options:

  • Use Search Configuration Export from the site settings (Site Collection Administration section)
  • Use the Get-PnPSearchConfiguration cmdlet from the PnP PowerShell extensions and use the scope “Site”

Both will produce the same result and create an xml-file with the current search configuration of our site collection. This file will be used by our deployment script to set the search configuration in our target environment.

Next we need a subsite for our basic search center. To create this subsite I use a PowerShell script:

$SubSearchWebTemplate = "SRCHCENTERLITE#1"
$SubSearchDescription = "Search"
$SubSearchTitle = "Search"
$SubSearchUrl = "Search"
$SubSearchLanguage = "1033"
$searchWeb = New-PnPWeb -Title $SubSearchTitle -Url $SubSearchUrl -Description $SubSearchDescription -Locale $SubSearchLanguage -Template $SubSearchWebTemplate

When the subsite is created, open the subsite in a browser and run a search (we need to modify the results.aspx). On the results page (results.aspx) we need to modify the webpart for the refinement panel and the search results webpart.

In the webpart properties for the refinement webpart click the “Choose Refiners…” button and add the RefinableString managed property, we modified a few steps above. Don’t forget to set the display name for the refiner.

In the properties of the search results webpart, click the “Change query” button. In the query builder choose the result source we created in our site collection from the combobox near “Select a query”. That is all we need to configure for the search results webpart.

To make the modifications in the webparts available by our deployment script, we need to export the webpart settings. This could easily be done from the web interface.

Do this export for the refinement webpart and the search results webpart.

Now we have the following artefacts

  • Search-Config.xml
  • Refinement.webpart
  • SearchResults.webpart

So, let’s create the deployment script to make all the customizations in the target environment. The script should do the following:

1. Create the library and its field

2. Import the search configuration

3. Create the search subsite

4. Modifiy the refinement webpart and the search result webpart in the search subsite

5. Configure the search settings in the root site of the site collection (could be done by setting properties in the property bag of the web)

Finally the deployment script will look like this (yes, I know, do not use full qualified paths in these scripts, but it’s just a demo):

Param (
		[string] $Url

Function EstablishConnectionSilent
	Param (
		[string] $Url,
	if ($Credentials -eq $null)
		$Credentials = Get-Credentials
	Connect-PnPOnline -Url $Url -Credentials $Credentials -ErrorAction Stop

$cred = Get-Credential

Write-Host "Connect to site collection"
Connect-PnPOnline -Url $Url -Credentials $cred

Write-Host "Create library"
$list = New-PnPList -Title "Library" -Template DocumentLibrary -Url "Library" -OnQuicklaunch

Write-Host "Add field to library"
$field = Add-PnPField -List "Library" -DisplayName "Freetext" -InternalName "Freetext" -Type Text -AddToDefaultView

Write-Host "Import search configuration"
$sConfig = Set-PnPSearchConfiguration -Scope Site -Path C:\Scripts\Search-Demo\Search-Config.xml

Write-Host "Create search subweb"
$SubSearchWebTemplate = "SRCHCENTERLITE#1"
$SubSearchDescription = "Search"
$SubSearchTitle = "Search"
$SubSearchUrl = "Search"
$SubSearchLanguage = "1033"
$searchWeb = New-PnPWeb -Title $SubSearchTitle -Url $SubSearchUrl -Description $SubSearchDescription -Locale $SubSearchLanguage -Template $SubSearchWebTemplate

if ($searchWeb -ne $null)
	$searchWebUrl = $searchWeb.Url

	Write-Host "Switch context to search subweb"
	EstablishConnectionSilent -Url $searchWebUrl -Credentials $cred
	$resultsPage = $searchWeb.ServerRelativeUrl + "/results.aspx"

	Write-Host "Remove webparts"
	Remove-PnPWebPart -ServerRelativePageUrl $resultsPage -Title "Refinement"
	Remove-PnPWebPart -ServerRelativePageUrl $resultsPage -Title "Search Results"
	Write-Host "Add webparts"
	$wp = Add-PnPWebPartToWebPartPage -ServerRelativePageUrl $resultsPage -Path C:\Scripts\Search-Demo\Refinement.webpart -ZoneId "NavigationZone" -ZoneIndex 1
	$wp = Add-PnPWebPartToWebPartPage -ServerRelativePageUrl $resultsPage -Path C:\Scripts\Search-Demo\SearchResults.webpart -ZoneId "MainZone" -ZoneIndex 2

	Write-Host "Switch context to root web"
	EstablishConnectionSilent -Url $Url -Credentials $cred

	Write-Host "Set search settings in web property bag"
	Set-PnPPropertyBagValue -Key "SRCH_ENH_FTR_URL" -Value $searchWebUrl
	Set-PnPPropertyBagValue -Key "SRCH_ENH_FTR_URL_SITE" -Value $searchWebUrl
	$value = '{"Inherit":false,"ResultsPageAddress":"' + $resultsPage + '","ShowNavigation":false}'
	Set-PnPPropertyBagValue -Key "SRCH_SB_SET_SITE" -Value $value

Write-Host "Done."

To deploy our configuration to a new site collection, simply run the script with a proper url parameter:

Now we can upload new documents to our library, set the values for our Freetext field and wait for a crawl (remember, be patient). When the search index is updated, the search results should look similar to the next image.

Hope this will help in the next customizations, where modifications to the search configuration are necessary.