Create Result Source with PowerShell in SharePoint 2013

A result source in SharePoint 2013 is used to segment certain types of content so they can be searched in a narrower fashion than searching against all content within the index. Using result sources, we can define query rules that must be met by the content in order for it to appear in search results. In previous versions of SharePoint this concept was addressed through search scopes.

SharePoint 2013 presents us with user interface in Central Administration where we are able to create new result sources and configure their properties:

Search Admin - Result Source

However, at the time of writing this post, there is no Windows PowerShell cmdlet available to create a result source in SharePoint 2013. This is rather limiting, because as user-friendly as the browser interface is, we still need a way to automate search configuration, especially when developing and deploying solutions for a customer. It’s a fact of life that most SharePoint administrators do not make a happy face when being handed a thick document with manual actions to execute, especially if it needs to be done several times on different environments.

Search Assembly To The Rescue

Luckily, the Microsoft.Office.Server.Search assembly exposes all objects and methods needed to create and configure a result source. And since we can load .NET assemblies in a PowerShell session, we are able to come up with a solution. Let’s start.

First, some preparation work – we get a reference to the Search Service Application and we load the Microsoft.Office.Server.Search assembly in our PowerShell session. Then, we create instances of a couple of classes needed to manage search related items - FederationManager and SearchObjectOwner:

# get current search service aplication
$sspApp = Get-SPEnterpriseSearchServiceApplication;

# load Search assembly
[void] [Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.Search")

# create manager instances
$fedManager = New-Object Microsoft.Office.Server.Search.Administration.Query.FederationManager($sspApp)
$searchOwner = New-Object Microsoft.Office.Server.Search.Administration.SearchObjectOwner([Microsoft.Office.Server.Search.Administration.SearchObjectLevel]::Ssa, $site.RootWeb)

We will be creating our result source with Search Service Application scope, so we specify Ssa level for the search owner instance. This object also requires a valid SharePoint context, so we need to pass a SPWeb instance as a second parameter to its constructor.

Having laid the groundwork, we are now ready to create a result source:

# define query
$query = '{searchTerms?} {?ContentTypeId:0x0100E6631D88BF1B44CA861A1DF7D62E5292*}'
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties

# define custom sorting
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection
$sortCollection.Add("Title", [Microsoft.Office.Server.Search.Query.SortDirection]::Ascending)
$queryProperties["SortList"] = [Microsoft.Office.Server.Search.Query.SortCollection]$sortCollection

# create result source
$resultSource = $fedManager.CreateSource($searchOwner)
$resultSource.Name = 'Glossary'
$resultSource.ProviderId = $fedManager.ListProviders()['Local SharePoint Provider'].Id
$resultSource.CreateQueryTransform($queryProperties, $query)
$resultSource.Commit()

In the example above, we create a result source named Glossary. Since we are looking for results from the index of the Search Service Application, we specify that the result source uses the Local SharePoint Provider.

We define the query transform that will scope results returned by our result source. The query transform consists of a query template string, which in this case limits search results to a specific content type, and an instance of the QueryTransformProperties class.

These query properties can be used to specify the sort order of search results based on managed properties or a ranking model. In our case we want to display entries from a glossary of terms, so we would like our search results to be sorted alphabetically in ascending order depending on their title. In order to define sorting based on managed properties, we create an instance of the SortCollection class and add an entry to it for each managed property we would like to sort by, together with the sort direction. Finally we add this sort collection to the query transform properties under the key SortList.

The key here is of primary importance, specifying an incorrect key will not apply the sorting rule to results. This turns out to be the biggest caveat of creating a result source, simply because there is no documentation on the keys to use in the query transform properties.

Print Properties of Existing Result Source

To come around this last obstacle, we use a small trick. We utilize the Query Builder to create the result source we want:

Query Builder

Then, we use the following PowerShell script to get the existing result source and print its properties to the console:

# print properties of existing result source
$source = $fedManager.GetSourceByName('Glossary', $searchOwner)
Write-Host "Id:" $source.Id
Write-Host "Name:" $source.Name
Write-Host "Provider Id:" $source.ProviderId
Write-Host $source.QueryTransform
Write-Host "Query Transform Properties:" $source.QueryTransform.OverrideProperties

This gives us the final piece of the puzzle – the key for specifying sorting in the query transform properties.

The full script can be downloaded here.

2 thoughts on “Create Result Source with PowerShell in SharePoint 2013

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>