Deploying SharePoint 2013 SSA Across Multiple Servers Using PowerShell

Update (5-May-2015) I posted a new version of this script at this link below: 

new script here >> PowerShell to Deploy an SSA Across Multiple Servers (v2.0)

---- Everything else below should be considered out of date -----

Update: Since the release of SharePoint 2013 RTM, I've made some modifications in an effort to simplify things (e.g. removing the unnecessary command line parameters) as well as improving the functionality (e.g. ability to provision multiple index partitions, register a Managed Account, clean up the inactive topology at the end). The core functionality has remained largely the same as the previous script, so it should still work, too.

As always, I'm interested to hear your feedback, suggestions, etc and want to make this script better and more robust. As I have time, I'm also planning to back port this to SharePoint 2010 and hope to enable topology updates (e.g. add a component to an existing topology) using this script.


There was so much excitement at first with everything being new... then - confusion. I fought it, thinking "I've got to be missing something, right?!?!". After some poking and prodding, acceptance finally set in...


This was my progression with the UI in Central Admin when creating my first Search Service Application in a SharePoint 2013 Preview (aka "Beta 2") farm. I wasn't able to target any servers, specify what components (and how many) I wanted in the topology, avoid the GUIDs in my database names, or do much in terms of making this topology fit my environment. Instead, I found all my components dropped onto the Central Admin server and no way to modify the topology from the UI.

Enter PowerShell to the rescue...

I probably got carried away with this, but I'm regularly creating new SSAs to test various implementations, so I needed some flexibility. To this post, I've attached my PowerShell script that I created to accomplish this, but I must first give the disclaimer: ALL information in this blog is provided "AS IS" with no warranties and confers no rights. This blog does not represent the thoughts, intentions, plans or strategies of my employer. All content is solely my opinion and provided with a best effort to be based in reality. All examples, code samples, demonstrations, or anything resembling a “how-to” are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. Inappropriate comments will be deleted at the authors discretion. And yes, the spelling of strategery was intentional. 

And, just to reiterate, this script was created and tested using the SharePoint 2013 Preview (aka "Beta 2"). If anything changes in future versions, I will do my best to make the appropriate updates in a reasonable timeframe.


Using the script (updated):

If you open up the file, you'll see the sample configuration settings (which are the scripts defaults) for running the script. In your environment, edit your copy of the script to use the configuration and server names to match your environment to specify which components you want where. For example below, running this script will create a Crawl Component (CC) on the server "theVan"... an Admin Component, Content Processing (CP) and Analytics Processing (AP) component on the "murdock" and "col-smith" servers, and create an Index Partition (IP) and a Query Processing (QP) component on the "bosco" server (Partition 0) and the "faceman" server (Partition 1).

A point worth emphasizing is that whatever index path that you specify above must exist on both the applicable target servers (e.g. "bosco" and "faceman" in this case) as well as the server from which you run this script. For example, if I ran this script from the "murdock" server, then the paths that I specified (e.g. in this case "C:\garage\index-p0\" and "C:\garage\index-p1\") must both exist on the "murdock" server even though this server will not host an index partition. For the applicable target servers, the path "C:\garage\index-p0\" must exist on the "bosco" server and "C:\garage\index-p1\" on the "faceman" server (and for what it's worth, there is nothing special about the paths C:\garage\index-p[#]\... it's just the naming convention I chose for my custom index paths)

$ssaConfig = @{
  ssaName = "SSA";
  dbSrv = "theVette";
  dbNamePrefix = "V5_SSA";
  appPoolName = "SSA AppPool";  # if exists, will just use the existing pool
  appPoolAccount = "OFFICESPACE\spSearch";
  #(optional)adminPoolName = "sp15SvcAppPool-Search";
  #(optional)adminPoolAccount = "officespace\fakeSearchSvc";
  servers = @{ 
    "theVan"    = @{ components = @{ CC=$true; }; };
    "murdock"   = @{ components = @{ Admin=$true; CP=$true; AP=$true; }; };
    "col-smith" = @{ components = @{ Admin=$true; CP=$true; AP=$true; }; };
    "bosco"     = @{ components = @{ IP=$true; QP=$true; }; 
                     index =      @{ Partition=0; # The index partition number
                                      # Specified path must exist and be empty
    "faceman"   = @{ components = @{ IP=$true; QP=$true; }; 
                     index =      @{ Partition=1; # The index partition number
                                      # Specified path must exist and be empty

After making changes applicable to your environment, save/close and then simply *run the script (*make sure you start the SharePoint 2013 Administrative PowerShell command window by using "Run as Administrator") without any parameter. With the options above (e.g. defined in $ssaConfig), the script created the following topology:



PS C:\garage> .\sp2013-buildSSA.ps1

Name                           Value
----                           -----
dbSrv                          theVette
appPoolAccount                 OFFICESPACE\spSearch
servers                        {murdock, theVan, col-smith, faceman...}
ssaName                        OfficeSpaceSSA
appPoolName                    SSA AppPool
dbNamePrefix                   sp15_SSA

-- Search App Pool [SSA AppPool] already exists... <skipping>

Starting Search Instances...

Creating New SSA
   - My tests have taken ~10 min to complete this step
   - Starting at: 01/29/2013 12:32:46

$SSA =>
MergeWithDefaultPartition   : False
LocationConfigurations      : {Internet Search Results, Internet Search
                               Suggestions, Local Search Results, Local
                               People Search Results...}
TypeName                    : Search Service Application Proxy
FASTAdminProxy              :
ServiceEndpointUri          : urn:schemas-microsoft-com:sharepoint:service:
ManageLink                  :
PropertiesLink              :
CanUpgrade                  : True
IsBackwardsCompatible       : True
NeedsUpgradeIncludeChildren : False
NeedsUpgrade                : False
UpgradeContext              : Microsoft.SharePoint.Upgrade.SPUpgradeContext
Name                        : OfficeSpaceSSA
DisplayName                 : OfficeSpaceSSA
Id                          : 758a8dbc-a561-42ef-806e-c12c1b2567d2
Status                      : Online
Parent                      : SearchQueryAndSiteSettingsServiceProxy
Version                     : 163122
Properties                  : {Microsoft.Office.Server.Utilities.SPPart...}
Farm                        : SPFarm Name=V5_Config
UpgradedPersistedProperties : {}
CanSelectForBackup          : True
DiskSizeRequired            : 0
CanSelectForRestore         : True
CanRenameOnRestore          : True

Cloning the topology...

Creating Components on specified server(s)...

   [murdock] --> Admin
ComponentId : 390b3c7c-787a-4408-be8b-0f4d7164c901
TopologyId  : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId    : c9faef15-53b8-4492-97bd-d7f7b880f78f
Name        : AdminComponent1
ServerName  : MURDOCK

IndexLocation : C:\Program Files\Microsoft Office Servers\15.0\Data\Office Server\Applications
Initialized   : True
Name          : f3f707ec-94f6-4059-9263-81e2cf13c63a
ServerName    : MURDOCK
ServerId      : c9faef15-53b8-4492-97bd-d7f7b880f78f
Server        : SearchServiceInstance

   [murdock] --> AP
NumProcessingTasksInParallel : 4
MaxSortMemoryInMB            : 40
ComponentId                  : 52454a0d-78a7-4905-a3cb-4bba9f6a41ed
TopologyId                   : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId                     : c9faef15-53b8-4492-97bd-d7f7b880f78f
Name                         : AnalyticsProcessingComponent1
ServerName                   : MURDOCK

   [murdock] --> CP
ComponentId : 437b9645-4dd8-4f03-b288-d4dbf966eee0
TopologyId  : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId    : c9faef15-53b8-4492-97bd-d7f7b880f78f
Name        : ContentProcessingComponent1
ServerName  : MURDOCK

   [theVan] --> CC
ComponentId : 1f5421e7-0564-4205-9c3b-b26c559cd901
TopologyId  : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId    : ee17cdb4-90c0-4e8e-baf5-478a9606b44e
Name        : CrawlComponent1
ServerName  : THEVAN

   [col-smith] --> Admin
ComponentId : 771fb366-8e56-4575-ac28-a349c8198ab1
TopologyId  : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId    : 8fe7a7ca-f2cd-4c91-b82e-04a0a397bd8b
Name        : AdminComponent2
ServerName  : COL-SMITH

IndexLocation : C:\Program Files\Microsoft Office Servers\15.0\Data\Office Server\Applications
Initialized   : True
Name          : f3f707ec-94f6-4059-9263-81e2cf13c63a
ServerName    : MURDOCK
ServerId      : c9faef15-53b8-4492-97bd-d7f7b880f78f
Server        : SearchServiceInstance

   [col-smith] --> AP
NumProcessingTasksInParallel : 4
MaxSortMemoryInMB            : 40
ComponentId                  : 81845e56-5aa1-4d92-b363-993da9a0c7f5
TopologyId                   : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId                     : 8fe7a7ca-f2cd-4c91-b82e-04a0a397bd8b
Name                         : AnalyticsProcessingComponent2
ServerName                   : COL-SMITH

   [col-smith] --> CP
ComponentId : 3d6ca1db-9f8b-4ed3-9db9-0543b5384904
TopologyId  : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId    : 8fe7a7ca-f2cd-4c91-b82e-04a0a397bd8b
Name        : ContentProcessingComponent2
ServerName  : COL-SMITH

   [faceman] --> IP
IndexPartitionOrdinal : 1
RootDirectory         : C:\garage\index-p1\
ComponentId           : b03ade01-76f4-47b2-9191-63746e91bae2
TopologyId            : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId              : e59bd3ee-c0dd-457a-a17e-f6a7fe0a5280
Name                  : IndexComponent1
ServerName            : FACEMAN

   [faceman] --> QP
ComponentId : 0ea589a0-7434-4b54-a948-46fade4c8e0f
TopologyId  : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId    : e59bd3ee-c0dd-457a-a17e-f6a7fe0a5280
Name        : QueryProcessingComponent1
ServerName  : FACEMAN

   [bosco] --> IP
IndexPartitionOrdinal : 0
RootDirectory         : C:\garage\index-p0\
ComponentId           : 895fdecd-e19f-4a7e-bed7-36ba124802b6
TopologyId            : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId              : c1ef303d-b1a2-4901-8398-dde10393140e
Name                  : IndexComponent2
ServerName            : BOSCO

   [bosco] --> QP
ComponentId : b0b92068-19e0-47c7-92c9-79759f7b0e46
TopologyId  : b931e94c-dfa2-4bf2-a998-0f064156c77f
ServerId    : c1ef303d-b1a2-4901-8398-dde10393140e
Name        : QueryProcessingComponent2
ServerName  : BOSCO

Activating the new topology:
   - This also may run for a few minutes...

Cleaning up the inactive topology...

PS C:\garage>


Additional References:



Comments (5)

  1. Sunil Kumar says:

    Wonderful article.

    thank you so much

  2. Harminder says:

    This is a great post; How can you tailor for script to scale to 2 partitions with HA?

  3. @Harminder, from my testing just leaving Partition=0 for multiple hosts will give you the replicas you need.

  4. Joe Starr says:

    Do you have a similar script for a single server?

  5. bspender says:

    Hi Joe… just change the config object at the top of the script to be something like:

    servers = @{

       "mySingleServer" = @{

           components = @{

           Admin=$true; CC=$true; CP=$true; AP=$true; IP=$true; QP=$true;


           index = @{ Partition=0; # The index partition number

               Path="C:somePath" # Specified path must exist and be empty




Skip to main content