Configuring SharePoint 2013 Search with PowerShell
Post courtesy Partner Solution Consultant Priyo Lahiri:
I wrote this script for a demo during our Practice Accelerater for SharePoint 2013. If you have attended the session you have already seen this in action. If not, here is the script for you to try out in your lab.
Disclaimer: before we proceed you should know that this script has been tested in my lab to work in a very specific scenario. If you wish to use this, your environment should exactly look like mine. In other words, we are not responsible if this script ruins your farm .
Take a note on the environment first:
SharePoint Farm:
- 2 web front end servers
- 2 application servers
- 1 SQL Server
Following are the services running on the server:
This script will provision Search on all the servers and configure our WFEs to host Query Processing Role.
Very important: if your environment doesn’t look like this, STOP here.
If you already have Search Configured, which would be your default setting if you have run the Farm Configuration Wizard, don’t use this script.
Follow these TechNet guidance to understand more:
- Change the default search topology in SharePoint Server 2013
- Manage search components in SharePoint Server 2013
As you can see from the above screenshot, my environment doesn’t even have Search Service started, so we are good to go in using this script. It’s ok to modify the script to use 3 server or 2 server environment, as long as Search has never been configured on your Farm or was configured and now removed.
Let’s understand the script on a piecemeal basis:
Section 1: setting up the environment and gather user inputs on Server Names, load SharePoint snap-in, managed account to use etc
Set-ExecutionPolicy unrestricted
Clear-Host
# Start Loading SharePoint Snap-in
$snapin = (Get-PSSnapin -name Microsoft.SharePoint.PowerShell -EA SilentlyContinue)
IF ($snapin -ne $null){
write-host -f Green "SharePoint Snap-in is loaded... No Action taken"}
ELSE {
write-host -f Yellow "SharePoint Snap-in not found... Loading now"
Add-PSSnapin Microsoft.SharePoint.PowerShell
write-host -f Green "SharePoint Snap-in is now loaded"}
# END Loading SharePoint Snapin
$hostA = Get-SPEnterpriseSearchServiceInstance -Identity "SP13App"
$hostB = Get-SPEnterpriseSearchServiceInstance -Identity "SP13-App2"
$hostC = Get-SPEnterpriseSearchServiceInstance -Identity "SP13WFE01"
$hostD = Get-SPEnterpriseSearchServiceInstance -Identity "SP13WFE02"
$searchName = "Fabricam Search Service"
$searchDB = "SP_Services_Search_DB"
$searchAcct = "fabricam\spService"
$searchAcctCred = convertto-securestring "pass@word1" -asplaintext -force
$searchManagedAcct = Get-SPManagedAccount | Where {$_.username-eq 'fabricam\spService'}
$searchAppPoolName = "Search Services Application Pool"
IF((Get-spserviceapplicationPool | Where {$_.name -eq "Search Services Application Pool"}).name -ne "Search Services Application Pool"){
$searchAppPool = New-SPServiceApplicationPool -Name $searchAppPoolName -Account $searchManagedAcct}
Section 2: Starting Search Service on all servers. You will notice there are some error handling in this script, for example, instead of just firing off the commands, I am actually waiting for the Search Service to respond before I go over to the next step. I have always found this approach very stable.
## Start Search Service Instances
Write-Host "Starting Search Service Instances..."
# Server 1
IF((Get-SPEnterpriseSearchServiceInstance -Identity $hostA).Status -eq 'Disabled'){
Start-SPEnterpriseSearchServiceInstance -Identity $hostA
Write-Host "Starting Search Service Instance on" $hostA.Server.Name
Do { Start-Sleep 5;
Write-host -NoNewline "." }
While ((Get-SPEnterpriseSearchServiceInstance -Identity $hostA).Status -eq 'Online')
Write-Host -ForegroundColor Green "Search Service Instance Started on" $hostA.Server.Name
} ELSE { Write-Host -f Green "Search Service Instance is already running on" $hostA.Server.Name }
#Server 2
IF((Get-SPEnterpriseSearchServiceInstance -Identity $hostB).Status -eq 'Disabled'){
Start-SPEnterpriseSearchServiceInstance -Identity $hostB
Write-Host "Starting Search Service Instance on" $hostB.Server.Name
Do { Start-Sleep 5;
Write-host -NoNewline "." }
While ((Get-SPEnterpriseSearchServiceInstance -Identity $hostB).Status -eq 'Online')
Write-Host -ForegroundColor Green "Search Service Instance Started on" $hostB.Server.Name
} ELSE { Write-Host -f Green "Search Service Instance is already running on" $hostB.Server.Name }
#Server 3
IF((Get-SPEnterpriseSearchServiceInstance -Identity $hostC).Status -eq 'Disabled'){
Start-SPEnterpriseSearchServiceInstance -Identity $hostC
Write-Host "Starting Search Service Instance on" $hostC.Server.Name
Do { Start-Sleep 5;
Write-host -NoNewline "." }
While ((Get-SPEnterpriseSearchServiceInstance -Identity $hostC).Status -eq 'Online')
Write-Host -ForegroundColor Green "Search Service Instance Started on" $hostC.Server.Name
} ELSE { Write-Host -f Green "Search Service Instance is already running on" $hostC.Server.Name }
#Server 4
IF((Get-SPEnterpriseSearchServiceInstance -Identity $hostD).Status -eq 'Disabled'){
Start-SPEnterpriseSearchServiceInstance -Identity $hostD
Write-Host "Starting Search Service Instance on" $hostD.Server.Name
Do { Start-Sleep 5;
Write-host -NoNewline "." }
While ((Get-SPEnterpriseSearchServiceInstance -Identity $hostD).Status -eq 'Online')
Write-Host -ForegroundColor Green "Search Service Instance Started on" $hostD.Server.Name
} ELSE { Write-Host -f Green "Search Service Instance is already running on" $hostD.Server.Name }
Section 3: Starting the Search Query and Site Setting Service Instance on Application Servers. If you don’t wait for a response from Search Service on Application Servers in the step above and try to run this step, it’s very likely that it would fail.
Additional Reference: https://msdn.microsoft.com/en-us/library/office/microsoft.office.server.search.administration.searchqueryandsitesettingsservice.aspx
This service provides the creation of a SearchServiceApplication or a SearchServiceApplicationProxy to a Search service application. This allows the caller to establish effective load balancing of Search queries across query servers.
## Start Query and Site Settings Service Instance
Write-Host "
Starting Search Query and Site Settings Service Instance on" $hostA.server.Name "and" $hostB.server.Name
Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance $hostA.server.Name
Do { Start-Sleep 3;
Write-host -NoNewline "." }
While ((Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | Where {$_.Server.Name -eq $hostA.server.Name}).status -ne 'Online')
Write-Host -ForegroundColor Green "
Query and Site Settings Service Instance Started on" $hostA.Server.Name
Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance $hostB.server.Name
Do { Start-Sleep 3;
Write-host -NoNewline "." }
While ((Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | Where {$_.Server.Name -eq $hostB.server.Name}).status -ne 'Online')
Write-Host -ForegroundColor Green "
Query and Site Settings Service Instance Started on" $hostB.Server.Name
Section 4: Create the Search Service Application
## Create Search Service Application
Write-Host "
Creating Search Service Application..."
$searchAppPool = Get-SPServiceApplicationPool -Identity "Search Services Application Pool"
IF ((Get-SPEnterpriseSearchServiceApplication).Status -ne 'Online'){
Write-Host " Provisioning. Please wait..."
$searchApp = New-SPEnterpriseSearchServiceApplication -Name $searchName -ApplicationPool $searchAppPool -AdminApplicationPool $searchAppPool -DatabaseName $searchDB
DO {start-sleep 2;
write-host -nonewline "." } While ( (Get-SPEnterpriseSearchServiceApplication).status -ne 'Online')
Write-Host -f green "
Provisioned Search Service Application"
} ELSE { write-host -f green "Search Service Application already provisioned."
$searchApp = Get-SPEnterpriseSearchServiceApplication
}
Section 5: creating the Admin Component. Initial Search Topology is created with this as well.
## Set Search Admin Component
Write-Host "Set Search Admin Component..."
$AdminComponent = $searchApp | Get-SPEnterpriseSearchAdministrationComponent | Set-SPEnterpriseSearchAdministrationComponent -SearchServiceInstance $hostA
Section 6: get the Initial Search Topology and Clone it
## Get Initial Search Topology
Write-Host "Get Initial Search Topology..."
$initialTopology = Get-SPEnterpriseSearchTopology -SearchApplication $searchApp
## Create Clone Search Topology
Write-Host "Creating Clone Search Topology..."
$cloneTopology = New-SPEnterpriseSearchTopology -SearchApplication $searchApp -Clone -SearchTopology $initialTopology
Section 7: here is where we define where different Search Components will live. We want to create a redundant topology for load balancing and high availability. As long as same services are running on multiple servers, SharePoint will use its internal Load Balancer.
We will deploy Admin Component, Crawl Component, Analytics Processing Component, Content Processing Component and Index Partition 0 on both the Application Servers and we will run Query Processing Component on both the Web Front End Servers.
If you are new these components mentioned above, refer to this TechNet Article .
## Host-A Components
Write-Host "Creating Host A Components (Admin, Crawl, Analytics, Content Processing, Index Partition)..."
$AdminTopology = New-SPEnterpriseSearchAdminComponent -SearchServiceInstance $hostA -SearchTopology $cloneTopology
$CrawlTopology = New-SPEnterpriseSearchCrawlComponent -SearchServiceInstance $hostA -SearchTopology $cloneTopology
$AnalyticsTopology = New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchServiceInstance $hostA -SearchTopology $cloneTopology
$ContentProcessingTopology = New-SPEnterpriseSearchContentProcessingComponent -SearchServiceInstance $hostA -SearchTopology $cloneTopology
$IndexTopology = New-SPEnterpriseSearchIndexComponent -SearchServiceInstance $hostA -SearchTopology $cloneTopology -IndexPartition 0
## Host-B Components
Write-Host "Creating Host B Components (Admin, Crawl, Analytics, Content Processing, Index Partition)..."
$AdminTopology = New-SPEnterpriseSearchAdminComponent -SearchServiceInstance $hostB -SearchTopology $cloneTopology
$CrawlTopology = New-SPEnterpriseSearchCrawlComponent -SearchServiceInstance $hostB -SearchTopology $cloneTopology
$AnalyticsTopology = New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchServiceInstance $hostB -SearchTopology $cloneTopology
$ContentProcessingTopology = New-SPEnterpriseSearchContentProcessingComponent -SearchServiceInstance $hostB -SearchTopology $cloneTopology
$IndexTopology = New-SPEnterpriseSearchIndexComponent -SearchServiceInstance $hostB -SearchTopology $cloneTopology -IndexPartition 0
## Host-C Components
Write-Host "Creating Host C Components (Query)..."
$QueryTopology = New-SPEnterpriseSearchQueryProcessingComponent -SearchServiceInstance $hostC -SearchTopology $cloneTopology
## Host-D Components
Write-Host "Creating Host D Components (Query)..."
$QueryTopology = New-SPEnterpriseSearchQueryProcessingComponent -SearchServiceInstance $hostD -SearchTopology $cloneTopology
Section 8: Next we will activate the new topology that we just created above and remove the initial Search topology which should be in “Inactive” State.
## Activate Clone Search Topology
Write-Host "Activating Clone Search Topology...Please wait. This will take some time"
Set-SPEnterpriseSearchTopology -Identity $cloneTopology
## Remove Initial Search Topology
Write-Host "Removing Initial Search Topology..."
$initialTopology = Get-SPEnterpriseSearchTopology -SearchApplication $searchApp | where {($_.State) -eq "Inactive"}
Remove-SPEnterpriseSearchTopology -Identity $initialTopology -Confirm:$false
Section 9: Last step is to create the Search Service Application Proxy
## Create Search Service Application Proxy
Write-Host "Creating Search Service Application Proxy..."
$searchAppProxy = New-SPEnterpriseSearchServiceApplicationProxy -Name "$searchName Proxy" -SearchApplication $searchApp
And here is the end result:
Here are the services running on all servers:
And here is the topology:
Cheers!
Priyo
Note: The referenced PowerShell script is attached to this post. Use at your own risk, modify to meet the parameters of your own environment, and test before using in production!
Comments
- Anonymous
January 07, 2014
Reflecting back on 2013, I just dived (dove?) into the logs for the PTS Blog for 2013, and thought I - Anonymous
February 06, 2014
This is a great script but I had to run it many times to get it to complete successfully, each time deleting the search and databases due to TIMER failure...Is there anyway to chack or make the timer service more reliable - Anonymous
March 18, 2014
Thanks for the powershell. It helped a lot. - Anonymous
May 18, 2015
The comment has been removed - Anonymous
February 07, 2017
Thank you very much! this helped a lot. I made this work in SP2016. One observation, I think the Do-While loop should be (... -ne 'Online') - on section 2 when starting the search service instance. - Anonymous
November 08, 2017
Simply hats offf