2015-04-14

This script is what we used to rebuild the topology.  Notice the first section define variables this must be set to what you are using in your environment.

or you can view the contents right down here!

Add-PSSnapin Microsoft.SharePoint.PowerShell#### Define Variables ###


#where Database Server Name equals your database server

$DBServer = 'Database Server Name'

#what ever you use for your search

$SearchServiceAccount = 'DOMAIN\SP_Search'

#this is the prefix for your database names

$SearchAdminDatabaseName = 'Company_SP_Search_'

#search topology servers

$IndexServers = 'WFE01','WFE02'

$QueryServers = 'WFE01','WFE02' 

$ContentProcessingServers = 'APP01','APP02'

$CrawlServers = 'APP01','APP02'

$AnalyticsServers = 'APP01','APP02'

$AdminServers = 'APP01','APP02'

#application pool for search

$SearchApplicationPool = 'SPSearch'

#Name of service

$SearchServiceName ="Search Service"

#location of your index must be the same on WFE servers

$IndexLocation = "C:\SearchIndex"





##################################

##################################

##### Create Search Service #####

##################################

##################################

#Add the SharePoint PowerSHell Module

Write-Host 'Adding the SharePoint Snapin'

Add-PSSnapin Microsoft.SharePoint.PowerShell



#Check for existing Search Service

$ExistingSSA = Get-SPEnterpriseSearchServiceApplication

If ($ExistingSSA -ne $Null)

    {

        Write-Host "A Search Service Application is already deployed to this farm, stopping script execution"

        exit

    }



#Validate Index File Location

#Test for Index path borrowed from Joe Rodgers

ForEach ($IndexServer in $IndexServers)

    {

        $driveLetter = $IndexLocation.SubString(0,1)

        $folderPath  = $IndexLocation.SubString(3)

        $uncIndexPath = "\\$IndexServer\$driveLetter`$\$folderPath"

        $TestPath = Test-Path -Path $uncIndexPath

        IF ($TestPath -ne $True)

            {

                Write-Host "The index location does not exist on at least one index server, stopping script"

                exit

            }

        $EmptyTest = Get-ChildItem -Path $uncIndexPath

        IF ($EmptyTest -ne $NULL)

            {

                Write-Host "The index location is not empty on at least one server, stopping script"

                exit

            }

        Write-Host "Index location is ready on" $IndexServer

    }

                



#Prompt user to enter Search Service Account Password

$SearchCredential = Get-Credential -UserName $SearchServiceAccount -Message 'Search Service Account'



#Check for Search Service Managed Account and if it doesn't exist, create it

$ManagedAccount = Get-SPManagedAccount | ?{$_.username -eq $SearchCredential.UserName}

If ($ManagedAccount -eq $NULL)

    {

        Write-Host 'Adding' $SearchCredential.UserName 'as a managed account'

        $ManagedAccount = New-SPManagedAccount -Credential $SearchCredential

    }

ELSE

    {

        Write-Host 'Managed Account' $SearchCredential.UserName 'already exists'

    }



#Validate managed account

IF ($ManagedAccount -eq $NULL)

    {

        Write-Host "There is an error with the managed account, stopping script"

        break

    }





#Change the service account for host controller service and noderunner

#BK:2604515

$CurrentEnterpriseSearchAccount = (Get-SPEnterpriseSearchService).ProcessIdentity

IF($CurrentEnterpriseSearchAccount -ne $SearchCredential.UserName)

    {

        Write-Host 'Changing Process identity for Search Services to' $SearchCredential.UserName

        Get-SPEnterpriseSearchService | Set-SPEnterpriseSearchService -ServiceAccount $SearchCredential.UserName -ServicePassword $SearchCredential.Password

    }

ELSE

    {

        Write-Host 'Search Service process identity is already set to' $CurrentEnterpriseSearchAccount

    }





#Start Services on Index Servers and retreive the Search Instance for the index servers

$IndexSearchInstances = @() #Declare empty array for index instances

Write-Host 'Starting Index Servers'

ForEach ($IndexServer in $IndexServers)

    {

        $IndexInstance = Get-SPEnterpriseSearchServiceInstance | ?{$_.Server -like "*$IndexServer*"} #Get reference to search service instance

        IF ($IndexInstance.Status -eq "disabled")

            {

                Start-SPEnterpriseSearchServiceInstance -Identity $IndexInstance #Start the Search Service Instance

                Start-Sleep -Second 10

            }

        $SSQSIInstance = Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | ?{$_.Server -like "*$IndexServer*"}

        IF ($SSQSIInstance.status -eq "disabled")

            {

                Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity $SSQSIInstance #Retrieve and start the SQSSI for this server

                Start-SLeep -Seconds 10

            }

        $IndexSearchInstances += $IndexInstance

    }



#Start Services on query Servers and retreive the Search Instance for the query servers

$QuerySearchInstances = @() #Delcare empty array for query instances

Write-Host 'Starting Query Servers'

ForEach ($QueryServer in $QueryServers)

    {

        $QueryInstance = Get-SPEnterpriseSearchServiceInstance | ?{$_.Server -like "*$QueryServer*"} #Get reference to search service instance

        IF ($QueryInstance.Status -eq "disabled")

            {

                Start-SPEnterpriseSearchServiceInstance -Identity $QueryInstance #Start the Search Service Instance

                Start-Sleep -Second 10

            }

        $SSQSIInstance = Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | ?{$_.Server -like "*$QueryServer*"}#Retrieve and start the SQSSI for this server

        IF ($SSQSIInstance.Status -eq "disabled")

            {

                 Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity $SSQSIInstance

                 Start-Sleep -Seconds 10

            }

        $QuerySearchInstances += $QueryInstance

    }



#Start services on Content procesing serviers servers and retrieve the search instanes for content procesing servers

$CPCInstances = @() #declare empty array

Write-Host 'Starting CPC Servers'

ForEach ($ContentProcessingServer in $ContentProcessingServers)

    {

        $CPCInstance = Get-SPEnterpriseSearchServiceInstance | ?{$_.Server -like "*$ContentProcessingServer*"}

        IF ($CPCInstance.status -eq "disabled")

            {

                Start-SPEnterpriseSearchServiceInstance -Identity $CPCInstance #Start the Search Service Instance

                Start-Sleep -Seconds 10

            }

        $CPCInstances += $CPCInstance

    }



#Start services on Crawl servers and retrieve the search instanes for servers

$CrawlInstances = @() #declare empty array

Write-Host 'Starting Crawl Servers'

ForEach ($CrawlServer in $CrawlServers)

    {

        $CrawlInstance = Get-SPEnterpriseSearchServiceInstance | ?{$_.Server -like "*$CrawlServer*"}

        IF ($CrawlInstance.Status -eq 'disabled')

            {

                Start-SPEnterpriseSearchServiceInstance -Identity $CrawlInstance #Start the Search Service Instance

                Start-Sleep -Seconds 10

            }

        $CrawlInstances += $CrawlInstance

    }



#Start services in Analytics Processing Servers and retrieve the search instance for these servers

$APCInstances = @() #Delcare an empty array

Write-Host 'Starting APC Servers'

ForEach ($AnalyticsServer in $AnalyticsServers)

    {

        $APCInstance = Get-SPEnterpriseSearchServiceInstance | ?{$_.Server -like "*$AnalyticsServer*"}

        IF ($APCIntance.Status -eq 'disabled')

            {

                Start-SPEnterpriseSearchServiceInstance -Identity $APCInstance #Start the Search Service Instance

                Start-Sleep -Seconds 10

            }

        $APCInstances += $APCInstance

    }



#Start services in Admin Servers and retrieve the search instance for these servers

$AdminInstances = @() #Delcare an empty array

Write-Host 'Starting Admin Servers'

ForEach ($AdminServer in $AdminServers)

    {

        $AdminInstance = Get-SPEnterpriseSearchServiceInstance | ?{$_.Server -like "*$AdminServer*"}

        IF ($AdminInstance.Status -eq 'disabled')

            {

                Start-SPEnterpriseSearchServiceInstance -Identity $AdminInstance #Start the Search Service Instance

                Start-SLeep -Seconds 10

            }

        $AdminInstances += $AdminInstance

    }



#Confirm with user that running search instances are correct

$Response = 'c'

While ($Response -eq 'c')

    {

        $RunningSearchInstances = Get-SPEnterpriseSearchServiceInstance | ?{$_.Status -eq "Online"}

        Write-Host "The following Servers are running the service 'SharePoint Server Search'"

        ForEach ($SearchInstance in $RunningSearchInstances) {Write-Host $SearchInstance.Server}

        $Response = Read-Host "Press C to check again, N to stop script execution or any other key to continue"

    }

If ($Reponse -eq 'n')

    {

        Exit

    }

        





#Confirm with user that running Search Query and Site Settings Service Instances are correct

$Response = 'c'

While ($Response -eq 'c')

    {

        $RunningSQSSI = Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | ?{$_.Status -eq "Online"}

        Write-Host "The following Servers are running the service 'SharePoint Search Query and Site Setting Service'"

        ForEach ($SQSSI in $RunningSQSSI) {Write-Host $SQSSI.Server}

        $Response = Read-Host "Press C to check again, N to stop script execution or any other key to continue"

    }

If ($Reponse -eq 'n')

    {

        Exit

    }





#Create the Search Service Application Pool

$AppPool = Get-SPServiceApplicationPool | ?{$_.name -eq "$SearchApplicationPool"}

IF ($AppPool -eq $NULL)

    {

        

        Write-Host 'Creating Application Pool' $SearchApplicationPool

        $AppPool = New-SPServiceApplicationPool -Name $SearchApplicationPool -Account $ManagedAccount   

    }

ELSE

    {

        Write-Host 'Application Pool' $SearchApplicationPool 'already exists'

    }



#Create Search Service Application

Write-Host 'Creating Search Service Application, this may take a few minutes'

$SearchServiceApp = New-SPEnterpriseSearchServiceApplication -Name $SearchServiceName -ApplicationPool $AppPool -DatabaseServer $DBServer -DatabaseName $SearchAdminDatabaseName

New-SPEnterpriseSearchServiceApplicationProxy -Name $SearchServiceName -SearchApplication $SearchServiceApp

Get-SPEnterpriseSearchServiceApplication





##Create a new search topology

#Create a variable to hold the new search topology

#Defining a search topology

Write-Host "Creating empty search topology"

$SearchServiceApp = Get-SPEnterpriseSearchServiceApplication

$NewSearchTopology = New-SPEnterpriseSearchTopology -SearchApplication $SearchServiceApp





#Define new search topology

Write-Host 'Populating new search topology'



#Define Search Index Components

ForEach ($IndexSearchInstance in $IndexSearchInstances)

    {

        New-SPEnterpriseSearchIndexComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $IndexSearchInstance -IndexPartition 0 -RootDirectory $IndexLocation

    }



#Define Search Query Components

ForEach ($QuerySearchInstance in $QuerySearchInstances)

    {

        New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $QuerySearchInstance

    }





#Define Content Processing Components

ForEach ($CPCInstance in $CPCInstances)

    {

        New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $CPCInstance

    }



#Define Search Crawl Components

ForEach ($CrawlInstance in $CrawlInstances)

    {

        New-SPEnterpriseSearchCrawlComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $CrawlInstance

    }



#Define Analytics Components

ForEach ($APCInstance in $APCInstances)

    {

        New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $APCInstance

    }



#Define Admin Components

ForEach ($AdminInstance in $AdminInstances)

    {

        New-SPEnterpriseSearchAdminComponent -SearchTopology $NewSearchTopology -SearchServiceInstance $AdminInstance

    }



$Topo = Get-SPEnterpriseSearchTopology -Identity $NewSearchTopology -SearchApplication $SearchServiceApp

$topo.GetComponents() | Sort-Object Name | FT ServerName, Name

Write-Host "Number of Components:" $Topo.ComponentCount



#Activate the Search Topology

$Response = Read-Host -Prompt 'Would you like to activate the above search topology? Press Y or N. Pressing N will stop script execution'

IF ($Response -ne "y")

    {

        Write-Host 'Stopping script'

        exit

    }

ELSE

    {

         Write-Host "Activating Search Topology"

         Set-SPEnterpriseSearchTopology -Identity $NewSearchTopology

    }



#If desired remove inactive topologies

$Resposne = Read-Host -Prompt 'Would you like to remove inactive search topologies?'

IF ($Response -ne "y")

    {

        Write-Host 'Stopping script'

        exit

    }

ELSE

    {



        Get-SPEnterprisesearchTopology -SearchApplication $SearchServiceApp | ?{$_.state -eq "Inactive"} | Remove-SPEnterpriseSearchTopology

    }

About the author 

Tony Di Leonardo