Skip Ribbon Commands
Skip to main content

Anders Rask on SharePoint

:

Anders Rask on SharePoint > Posts > Importing and Exporting Search Configuration Settings in SharePoint 2013
March 20
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 SearchConfigurationPortability class.

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

 

Thanx to my brainy colleague Allan Hvam for boilerplate code.

Comments

+1

Same problem here. Cant import to SSA
 on 9/5/2013 6:13 AM

Got the same error trying SSA

...Seeing if making sure the content sources have indexed fully one way through makes a difference.  On Public update mar 2013. 

Source and destination servers both same patch level. 
 on 9/20/2013 1:56 PM

FYI, reindexing didn't work

...per last comment, although I think it would be a good idea so that the crawled properties are created in the new environment you're migrating sites to.
 on 9/22/2013 12:20 PM

You cannot import customized settings into an SSA

 on 1/7/2014 5:19 PM

Getting Access Denied

Heya

I'm running your Import script with context SPSiteSubscription, and I'm getting Access Denied

here's the error message:

PS C:\Windows\system32> $context.ExecuteQuery()
Exception calling "ExecuteQuery" with "0" argument(s): "Access denied. You do not have permission to perform this action or access this resource."
At line:1 char:1
+ $context.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ServerUnauthorizedAccessException
 on 4/7/2015 7:27 PM

Getting Access Denied

Heya

I'm running your Import script with context SPSiteSubscription, and I'm getting Access Denied

here's the error message:

PS C:\Windows\system32> $context.ExecuteQuery()
Exception calling "ExecuteQuery" with "0" argument(s): "Access denied. You do not have permission to perform this action or access this resource."
At line:1 char:1
+ $context.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ServerUnauthorizedAccessException
 on 4/7/2015 8:52 PM

Re: Getting Access Denied

If you are working with SharePoint Online, you have to establish your ClientContext at tenant administration site.

So you would have:
$context = New-Object Microsoft.SharePoint.Client.ClientContext("https://<tenanturl>-admin.sharepoint.com")
 on 10/1/2015 4:24 PM

Does this still work

Hi there.

I used to use this command in our farm and it worked great.
However, after patching to a future Cumulative Update (in my case, Sept 2016 CU), this no longer seems to work.

Are you able to check if it's broken for you also?

In my dev environments, command works fine with version 15.0.4719.1000 but with version 15.0.4859.1000 I get the following error when running this line

$searchConfigurationPortability = New-Object Microsoft.SharePoint.Client.Search.Portability.searchconfigurationportability($context)


Error is New-Object : Cannot find an overload for "SearchConfigurationPortability" and the argument count: "1"
 on 1/24/2017 5:01 PM

Yes it works

This is still valid. Note that this is client code, make sure you have correct client framework and it should be fine.
 on 2/20/2017 8:23 AM

Error upon import

Exception calling "ExecuteQuery" with "0" argument(s): "The request message is too big. The server does not allow messages larger than 2097152 bytes."
 on 2/20/2017 11:51 PM

Add Comment

Title


Body *


Migrated Source URL


Commentator Name


Commentator Email


BotCheck *


Are you human? What is the sum of fifty-two minus ten?

Attachments