Provisioning SharePoint 2013 Search Service Application via PowerShell

Well, it is a quite some time since my last post. And yes, I know! I promised and still didn’t made my second post on Enterprise Search in SharePoint 2010. Well, I can’t help myself. This SharePoint 2013 hype got me as well. It doesn’t mean I won’t do what I promised. It’s only postponed (again). Priorities must be well defined 🙂

This article has a history on its own as well. I started writing it somewhere during public preview, left it in OneNote and forgot it. Now I finally got some time to catch a breathe again and continue playing with RTM bits. So, last night I got myself into configuring Search Service Application in SharePoint 2013. I think it is a good starting point on fetching design changes. And we have some significant changes in this new version. Search engine got a full new facelift, under the hood tuning, call it how you want – it is just cool.

So, what actually changed? Let’s answer this question by comparing topologies first:

SharePoint 2010 SharePoint 2013
Administration component Administration component(s)
Crawl component(s) Crawl component(s)
Index component(s) Index component(s)
Query processing Query processing component(s)
Content processing component(s)
Analytics processing component(s)

So, we have some new fellows in here. Also worth to mention is, that query and crawl topologies are merged now into a single topology, simply called “search topology” now.

So, let’s start creating a brand new Search Service Application. We’ll define some constants for a start.

$serviceAppName = "Enterprise Search Service Application"
$serverName = "CONSP01"
$adminServer = $serverName
$crawlServer = $serverName
$queryServer = $serverName
$indexServer = $serverName
$analyticsServer = $serverName
$contentProcessingServer = $serverName
$dbServer = "CONSP01"
$searchServer = $serverName
$searchDBName = "SP2013_Enterprise_Search"
$svcAppPoolName = "SharePoint Web Services Default"
$indexLocation = "D:\SharePoint2013\index"

Now, it is worth of mentioning, that I am creating a search topology using only one server. This is, of course, not a limitation. Search topology is pretty scaleable. It was already in SharePoint 2010 and it got even better in SharePoint 2013. At the time of writing this article, tests on RTM bits were made to provide a general gudance on topology, sizing and capacity planning.

Provisioning of the search service application will create 4 databases:

  • SP2013_Enterprise_Search
    This is a search administration database. It contains configuration and topology information.
  • SP2013_Enterprise_Search_AnalyticsReportingStore
    This database stores the result of usage analysis
  • SP2013_Enterprise_Search_CrawlStore
    The crawl database contains detailed tracking and historical information about crawled items
  • SP2013_Enterprise_Search_LinksStore
    Stores the information extracted by the content processing component and also stores click-through information.

So, let’s get back to business. We need a Search Service managed account. First of all, we will check if the account is already registered as a managed account and create it if it isn’t.

$searchCred = "CONTOSO\sp_search"
$searchPwd = ConvertTo-SecureString -String 'Pass@word1' -AsPlainText -Force
$cred = Get-Credential $searchCred
$searchSvcAccount = Get-SPManagedAccount $cred.UserName -ErrorAction SilentlyContinue

if ($searchSvcAccount -eq $null)
   $searchSvcAccount = New-SPManagedAccount $cred

Next thing to do is to configure a search service instance. We can set a default index location here and provision it. Well, actually DefaultIndexLocation parameter is obsolete now. We can however, set the index location during the creation of the index component later on.

$searchSvc = Get-SPEnterpriseSearchServiceInstance -Local
if ($searchSvc -eq $null)
   throw "Unable to retrieve search service"

# set Search Service parameter
$searchSvc | Set-SPEnterpriseSearchServiceInstance

if ($searchSvc.Status -ne "Online")
   $searchSvc | Start-SPServiceInstance

Now it is time to configure some additional settings in the search service, like service identity, e-mail, connection time out, proxy and preformance level.

$svc = Get-SPEnterpriseSearchService
Set-SPEnterpriseSearchService `
   -Identity $svc `
   -ServiceAccount $searchSvcAccount.UserName `
   -ServicePassword $(ConvertTo-SecureString -String 'Pass@word'
   -AsPlainText -Force) `
   -ContactEmail "" `
   -ConnectionTimeout "60" `
   -AcknowledgementTimeout "60" `
   -ProxyType "Default" `
   -PerformanceLevel "PartlyReduced"

From the service perspective, everything is up and running. Next step in the provisioning process is to create Search Service Application.

$searchApp = Get-SPEnterpriseSearchServiceApplication $serviceAppName -ErrorAction SilentlyContinue
if ($searchApp -eq $null)
   $saAppPool = Get-SPServiceApplicationPool | where { $_.Name -eq $svcAppPoolName }
   $searchApp = New-SPEnterpriseSearchServiceApplication -Name $serviceAppName -ApplicationPool $saAppPool -DatabaseServer $dbServer -DatabaseName $searchDBName

Now, this is where things start to differ from SharePoint 2010. We had two topologies earlier, a crawl and query topology. In SharePoint 2013 everything merged into one topology – a search topology. Still, some habits never change. Creating new search service application will create a search topology as well and activate it. As we cannot add components to an active topology, we will have to create a new search topology and add components there, concluding this with a removal of an old topology. This is a similar behavior as in SharePoint 2010 where we had to create new crawl and query topologies and decomission the old ones.

$initialSearchTopology = ($searchApp | Get-SPEnterpriseSearchTopology)
$searchTopology = ($searchApp | New-SPEnterpriseSearchTopology)

We have two new fellows here – Analytics and Content Processing. The reason is that the Analytics is now a part of Search Service Application, it is not a Service Application on its own anymore. Let’s start an admin component:

$adminSearchInstance = Get-SPEnterpriseSearchServiceInstance $adminServer
if ($adminSearchInstance.Status -ne "Online")
    $adminSearchInstance | Start-SPServiceInstance
$admin = $searchApp | Get-SPEnterpriseSearchAdministrationComponent
$admin | Set-SPEnterpriseSearchAdministrationComponent -SearchServiceInstance $adminSearchInstance
$admin = ($searchApp | Get-SPEnterpriseSearchAdministrationComponent)
while (-not $admin.Initialized)
    Start-Sleep 10
    $admin = ($searchApp | Get-SPEnterpriseSearchAdministrationComponent)
Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance $adminServer
$adminSearchInstance = Get-SPEnterpriseSearchServiceInstance $adminServer
$adminComponent = New-SPEnterpriseSearchAdminComponent -SearchTopology $searchTopology -SearchServiceInstance $adminSearchInstance

Create a crawl component:

$crawlInstance = Get-SPEnterpriseSearchServiceInstance $crawlServer
$crawlComponent = New-SPEnterpriseSearchCrawlComponent -SearchTopology $searchTopology -SearchServiceInstance $crawlInstance

Create a query processing component:

$queryInstance = Get-SPEnterpriseSearchServiceInstance $queryServer
$queryComponent = New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $searchTopology -SearchServiceInstance $queryInstance

Create a index component. We will use RootDirectory parameter to set the index location.

$indexInstance = Get-SPEnterpriseSearchServiceInstance $indexServer
$indexComponent = New-SPEnterpriseSearchIndexComponent -SearchTopology $searchTopology -SearchServiceInstance $indexInstance -RootDirectory $indexLocation

Create a analytics component:

$analyticsInstance = Get-SPEnterpriseSearchServiceInstance $analyticsServer
$analyticsComponent = New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $searchTopology -SearchServiceInstance $analyticsInstance

Create a content processing component:

$contentProcessingInstance = Get-SPEnterpriseSearchServiceInstance $contentProcessingServer
$contentProcessingComponent = New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $searchTopology -SearchServiceInstance $contentProcessingInstance

A new topology is now created. Let’s activate it.


The old topology will be automatically deactivated, however we need to fetch an object again and delete old topology.

$initialSearchTopology = ($searchApp | Get-SPEnterpriseSearchTopology | where { $_.TopologyId -eq $initialSearchTopology.TopologyId } )
Remove-SPEnterpriseSearchTopology -SearchApplication $searchApp -Identity $initialSearchTopology

At the end, register a service application proxy.

$searchProxy = New-SPEnterpriseSearchServiceApplicationProxy -Name "$serviceAppName Proxy" -SearchApplication $searchApp

Your Search Service Application is up and running now.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s