Importing and Exporting Search Configuration Settings in SharePoint 2013

It is often useful when you do SharePoint development to be able to deploy indexed and managed properties and property mappings in a repeatable way across environments.
In SharePoint 2010 we did this as part of our PowerShell provisioning, but things have changed a bit in SharePoint 2013. Not only have the managed properties changed quite a bit with the introduction of Managed Navigation, but also as a developer and architect you really need to think Cloud First if you want your deployment frameworks to work both on premises and in the cloud.
In the Client Side Object Model (CSOM) there is a framework for managing search settings, namely the SearchConfigurationPortabilityclass.
This class makes it possible to import and export search configuration settings as XML. This includes Crawled Properties, Managed Properties and Mappings, but also Query Rules, result types etc.
Here is some sample PowerShell code to export the search configuration settings to XML: 
[reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") | Out-Null
[reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.search") | Out-Null
$context = New-Object Microsoft.SharePoint.Client.ClientContext("http://intranet")
$searchConfigurationPortability = New-Object Microsoft.SharePoint.Client.Search.Portability.searchconfigurationportability($context)
$owner = New-Object Microsoft.SharePoint.Client.Search.Administration.searchobjectowner($context,"SSA")
$value = $searchConfigurationPortability.ExportSearchConfiguration($owner)
$context.ExecuteQuery()
[xml]$schema = $value.Value
$schema.OuterXml | Out-File schema.xml -Encoding UTF8
Note that I export the configuration from SSA. You can use the SearchObjectLevel enum to decide from what level you want to grab the settings: SSA, SPSiteSubscription, SPSite, SPWeb.
So to import the settings again on another environment we can do something like this:
[reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") | Out-Null
[reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.search") | Out-Null
$context = New-Object Microsoft.SharePoint.Client.ClientContext("http://intranet")
$searchConfigurationPortability = New-Object Microsoft.SharePoint.Client.Search.Portability.searchconfigurationportability($context)
#$owner = New-Object Microsoft.SharePoint.Client.Search.Administration.searchobjectowner($context,"SSA")
$owner = New-Object Microsoft.SharePoint.Client.Search.Administration.searchobjectowner($context,"SPSite")
[xml]$schema = gc .\schema.xml
$searchConfigurationPortability.ImportSearchConfiguration($owner,$schema.OuterXml)
$context.ExecuteQuery()

So the idea here is that you configure your SSA as you want to, with crawled properties, managed properties, mappings, query rules etc, you then import them into your "next" environment, that being either TEST, PREPROD or PROD. This especially helpful when you use TFS and Lab Management to spawn up and test your code and deployment.
The XML looks something like this (edited it since it is HUGE):
 <SearchConfigurationSettings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Portability">
  <SearchQueryConfigurationSettings>
    <SearchQueryConfigurationSettings>
      <BestBets xmlns:d4p1="http://www.microsoft.com/sharepoint/search/KnownTypes/2008/08" />
      <DefaultSourceId>00000000-0000-0000-0000-000000000000</DefaultSourceId>
      <DefaultSourceIdSet>true</DefaultSourceIdSet>
      <DeployToParent>false</DeployToParent>
      <DisableInheritanceOnImport>false</DisableInheritanceOnImport>
      <QueryRuleGroups xmlns:d4p1="http://www.microsoft.com/sharepoint/search/KnownTypes/2008/08" />
      <QueryRules xmlns:d4p1="http://www.microsoft.com/sharepoint/search/KnownTypes/2008/08" />
      <ResultTypes xmlns:d4p1="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Administration" />
      <Sources xmlns:d4p1="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Administration.Query" />
      <UserSegments xmlns:d4p1="http://www.microsoft.com/sharepoint/search/KnownTypes/2008/08" />
    </SearchQueryConfigurationSettings>
  </SearchQueryConfigurationSettings>
  <SearchRankingModelConfigurationSettings>
    <RankingModels xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
  </SearchRankingModelConfigurationSettings>
  <SearchSchemaConfigurationSettings>
    <Aliases xmlns:d3p1="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Administration">
       ...
    </Aliases>
    <CategoriesAndCrawledProperties xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      ...
    </CategoriesAndCrawledProperties>
    <CrawledProperties xmlns:d3p1="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Administration" i:nil="true" />
    <ManagedProperties xmlns:d3p1="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Administration">
      ...
    </ManagedProperties>
    <Mappings xmlns:d3p1="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Administration">
      ...
    </Mappings>
    <Overrides xmlns:d3p1="http://schemas.datacontract.org/2004/07/Microsoft.Office.Server.Search.Administration">
      <d3p1:LastItemName i:nil="true" />
      <d3p1:dictionary xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
    </Overrides>
  </SearchSchemaConfigurationSettings>
</SearchConfigurationSettings>
The crawled properties will show up in the CategoriesAndCrawledProperties section. 
NOTE: I only got the Mappings part of search configuration settings to work for SearchObjectLevel SPSite, not SSA. I will look further into this, but if anyone has an idea to why this does not work, throw me a comment!
The error I get if i use SSA when importing Mappings are:
Exception calling "ExecuteQuery" with "0" argument(s): "Search schema could not be successfully imported:
*  Search schema could not be successfully imported:
*  The master schema can't be imported.
"
At C:\Users\spinstall\Downloads\csomsearch\importSearchConfiguration.ps1:28 char:1
+ $context.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ServerException

Comments

Popular posts from this blog

"There's a configuration problem preventing us from getting your document. If possible, try opening this document in Microsoft Word." Office WebApp Error

"Sorry, Word Web App can't open this ... document because the service is busy." Office WebApp

Unable to create a "Send to Connection"- verification failed -url is a not a valid routing destination