Monday, August 20, 2012

Search Topology Automation using Powershell



Hi,

Search Topology automation has been done using power shell script.
Below is the sequence that has been followed for search topology.

1)      Creating Managed Account
2)      Creating Application Pool
3)      Creating Search Service Application
4)      Creating Service Proxy
5)      Creating Crawl Topology(crawl components0,1 in app server2, crawl components2,3 in app server3)
6)      Creating Query Topology(query components0,2 in WFE server2, query components 1,3 in WFE server3)
7)      Configure Default Content Access Account
8)      Configure Crawl Target Server
The script is as below

//SearchTopology_Batch.bat
Powershell.exe -Command Set-ExecutionPolicy "Bypass"
Powershell.exe -Command "& {D:\Naga\SP2010AppServer\SearchTopologyAutomation\SearchTopologyScript.ps1}"
Pause

//SearchTopologyScript.ps1
$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null)
{
Write-Host "Loading SharePoint Powershell Snap-in"
Add-PSSnapin "Microsoft.SharePoint.Powershell"
}

# Get complete file path (eg:  E:\SP2010AppServer\xxxx.ps1)
$filepath = $MyInvocation.MyCommand.Definition                                        
# Get current Directory  file path  (eg:  E:\SP2010AppServer)
$directorypath = [System.IO.Path]::GetDirectoryName($filepath)         
# Get current Drive   (eg:  E:\)
$directory = Get-Item $directorypath | Split-Path -Parent              
$InputFile = $directorypath+"\SetupInputs.xml"

$xmlinput = [xml] (get-content $InputFile)
$item = $xmlinput.SearchTopologyInputs


## Start logging
$LogTime = Get-Date -Format yyyy-MM-dd_h-mm
$LogFile = $directorypath + "\SearchTopologyScript-$LogTime.rtf"
Start-Transcript -Path $LogFile -Force


#Region Register Managed Accounts

$ManagedAcctUserName = $item.ManagedAccountName

If (($item.ManagedAccountPassword -ne "") -and ($item.ManagedAccountPassword -ne $null))
{$ManagedAcctPassword = (ConvertTo-SecureString $item.ManagedAccountPassword -AsPlainText -force)}

$credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $ManagedAcctUserName,$ManagedAcctPassword

New-SPManagedAccount –Credential $credentials
#EndRegion

$ContentAccessAcctName = $item.DefaultContentAccessAcctName
If (($item.DefaultContentAccessAcctPassword -ne "") -and ($item.DefaultContentAccessAcctPassword -ne $null))
{$ContentAccessAcctPassword = (ConvertTo-SecureString $item.DefaultContentAccessAcctPassword -AsPlainText -force)}

##$ContentAccessAcctPassword = $item.DefaultContentAccessAcctPassword


#---------------------Variables-----------------------------------#
##$SearchAppPoolName - to get Search Application Pool Name from xml
$SearchAppPoolName = $item.SearchAppPoolName

##$searchserviceapp- to get Search Service Application Name from xml
$searchserviceappname = $item.SearchServiceApplicationName

##$SearchServiceAppProxy - to get Search Service Application Proxy from xml
$SearchServiceAppProxy = $item.SearchServiceApplicationProxy

##$SearchAppProxyName - to get Search Application Proxy Name from xml
$SearchAppProxyName = $item.SearchServiceApplicationProxyName

##$SearchServiceAppName - to get Search Service Application Name from xml
$SearchServiceAppName = $item.SearchServiceApplicationName

##App2servernamefromxml - to get App 2 server Name from xml
$App2servernamefromxml =  $item.App2servername

##App3servernamefromxml - to get App 3 server Name from xml
$App3servernamefromxml =  $item.App3servername

##wfe1servernamefromxml - to get wfe 1 server Name from xml
$wfe1servernamefromxml = $item.wfe1servername

##wfe2servernamefromxml - to get wfe 2 server Name from xml
$wfe2servernamefromxml = $item.wfe2servername

##wfe3servernamefromxml - to get wfe 3 server Name from xml
$wfe3servernamefromxml = $item.wfe3servername


##db1servernamefromxml - to get db1 server Name from xml
$db1servernamefromxml = $item.DBServer1

##db2servernamefromxml - to get db2 server Name from xml
$db2servernamefromxml = $item.DBServer2

##db3servernamefromxml - to get db3 server Name from xml
$db3servernamefromxml = $item.DBServer3

##$crawlDatabaseName - to create new database for crawl
$crawlDatabaseName = $item.CrawlDatabase

##$propertydatabasename - to create new database for property
$propertydatabasename = $item.PropertyDatabase

##$CrawlComponentsLocation - location to create crawl components
$CrawlComponentsLocation = $item.CrawlComponentsLocation

##$QueryComponentsLocation - location to create query components
$QueryComponentsLocation = $item.QueryComponentsLocation

#Region of Site Query and Site Settings Service Instance
try
{
                #Start Query Processor Instance
                $wfe1SearchAndQuerySvcInstance = Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | where {($_.server) -match $wfe1servernamefromxml}
                Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -identity $wfe1servernamefromxml
                write-host $wfe1servernamefromxml "Search Query and Site Settings Service Instance has been started."

                $wfe2SearchAndQuerySvcInstance = Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | where {($_.server) -match $wfe2servernamefromxml}
                Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -identity $wfe2servernamefromxml
                write-host $wfe2servernamefromxml "Search Query and Site Settings Service Instance has been started."

                $wfe3SearchAndQuerySvcInstance = Get-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance | where {($_.server) -match $wfe3servernamefromxml}
                Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -identity $wfe3servernamefromxml
                write-host $wfe3servernamefromxml "Search Query and Site Settings Service Instance has been started."
}
catch
{
                Write-Output $_
}

#End Region

#Create Search Service Application
If ($SearchAppPoolName  -ne $NULL -and $searchserviceappname -ne $NULL)
{
                ##Remove-SPServiceApplicationPool $SearchAppPoolName
                Write-Host "Creating Search Service Application pool ..."
                $pool = New-SPServiceApplicationPool -Name $SearchAppPoolName -Account $ManagedAcctUserName
                write-host $pool "successfully created". -foreground green
               
                $searchserviceapp = new-spenterprisesearchserviceapplication -name $searchserviceappname -applicationpool $SearchAppPoolName

                write-host $searchserviceapp "successfully created". -foreground green

}
#EndRegion

#Create service application proxy

if($SearchAppProxyName -ne $null -and $SearchServiceAppName -ne $null)
{
$ssaproxy = New-SPEnterpriseSearchServiceApplicationProxy -Name $SearchAppProxyName -SearchApplication $SearchServiceAppName
write-host $ssaproxy  "has been generated successfully." -ForegroundColor green

}
else
{
Write-Host "Error: Search Application Name '($($SearchAppProxyName))' does not exist" -ForegroundColor Red
}
#EndRegion

#Start App server 2 Search Service Instance
$appserver2searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $App2servernamefromxml}
if ($appserver2searchInstance.status -eq "Disabled")
{
Start-SpEnterpriseSearchServiceInstance -identity $appserver2searchInstance
}

## Wait
Write-Host -ForegroundColor Blue " - Waiting for App server 2 Search Service Instance to start..." -NoNewline
While ($appserver2searchInstance.status -ne "Online")
{
Write-Host -ForegroundColor Blue "." -NoNewline
#start-sleep 1
$appserver2searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $App2servernamefromxml}
}
Write-Host -BackgroundColor yellow -ForegroundColor Black " ......: App server 2 Search Service Started!"
#EndRegion

#Start App server 3 Search Service Instance
$appserver3searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $App3servernamefromxml}
if ($appserver3searchInstance.status -eq "Disabled")
{
Start-SpEnterpriseSearchServiceInstance -identity $App3servernamefromxml
}
## Wait
Write-Host -ForegroundColor Blue " - Waiting for App server 3 Search Service Instance to start..." -NoNewline
While ($appserver3searchInstance.status -ne "Online")
{
Write-Host -ForegroundColor Blue "." -NoNewline
##start-sleep 1
$appserver3searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $App3servernamefromxml}
}
Write-Host -BackgroundColor yellow -ForegroundColor Black " ......: App server 3 Search Service Started!"

#Start Web Server 1 Search Service Instance
$wfe1searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $wfe1servernamefromxml}
if ($wfe1searchInstance.status -eq "Disabled")
{
Start-SpEnterpriseSearchServiceInstance -identity $wfe1servernamefromxml
}
## Wait
Write-Host -ForegroundColor Blue " - Waiting for Web Server 1 Search Service Instance to start..." -NoNewline
While ($wfe1searchInstance.status -ne "Online")
{
Write-Host -ForegroundColor Blue "." -NoNewline
##start-sleep 1
$wfe1searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $wfe1servernamefromxml}
}
Write-Host -BackgroundColor yellow -ForegroundColor Black " ......: Web Server 1 Search Service Started!"
#EndRegion

#Start Web Server 2 Search Service Instance
$wfe2searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $wfe2servernamefromxml}
if ($wfe2searchInstance.status -eq "Disabled")
{
Start-SpEnterpriseSearchServiceInstance -identity $wfe2servernamefromxml
}
## Wait
Write-Host -ForegroundColor Blue " - Waiting for Web Server 2 Search Service Instance to start..." -NoNewline
While ($wfe2searchInstance.status -ne "Online")
{
Write-Host -ForegroundColor Blue "." -NoNewline
##start-sleep 1
$wfe2searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $wfe2servernamefromxml}
}
Write-Host -BackgroundColor yellow -ForegroundColor Black " ......: Web Server 2 Search Service Started!"
#EndRegion

#Start Web Server 3 Search Service Instance
$wfe3searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $wfe3servernamefromxml}
if ($wfe3searchInstance.status -eq "Disabled")
{
Start-SpEnterpriseSearchServiceInstance -identity $wfe3servernamefromxml
}

## Wait
Write-Host -ForegroundColor Blue " - Waiting for Web Server 3 Search Service Instance to start..." -NoNewline
While ($wfe3searchInstance.status -ne "Online")
{
Write-Host -ForegroundColor Blue "." -NoNewline
##start-sleep 1
$wfe3searchInstance = Get-SPEnterpriseSearchServiceInstance | where {($_.server) -match $wfe3servernamefromxml}
}
Write-Host -BackgroundColor yellow -ForegroundColor Black " ......: Web Server 3 Search Service Started!"
#EndRegion


##Provision Search Administration Component
$appserver2searchInstance = get-spenterprisesearchserviceinstance  | where {($_.server) -match $App2servernamefromxml}
set-spenterprisesearchadministrationcomponent –searchapplication $SearchServiceAppName –searchserviceinstance $appserver2searchInstance
write-host " Provisioning Search AdministrationComponent is completed." -foreground green
#EndRegion

##Create Crawl Topology
try
{


                write-host Getting Initial Crawl Topology
                # Retrieve the active topology
                $InitialCrawlTopology = $SearchServiceAppName | Get-SPEnterpriseSearchCrawlTopology -Active


                write-host Cloning Crawl Topology
                # Clone the topology
                $CrawlTopology = $SearchServiceAppName | New-SPEnterpriseSearchCrawlTopology -Clone -CrawlTopology $InitialCrawlTopology

                #$crawlDB - variable to hold newly created database
                $crawlDB = New-SPEnterpriseSearchCrawlDatabase -SearchApplication $SearchServiceAppName  -DatabaseName $crawlDatabaseName -Dedicated

                write-host Creating new crawl component
                # Create the new crawl component
                $CrawlDatabase0 = ([array]($SearchServiceAppName | Get-SPEnterpriseSearchCrawlDatabase))[0]
                $CrawlDatabase1 = ([array]($SearchServiceAppName | Get-SPEnterpriseSearchCrawlDatabase))[1]
                $CrawlComponent0 = New-SPEnterpriseSearchCrawlComponent -CrawlTopology $CrawlTopology -CrawlDatabase $CrawlDatabase0 -SearchServiceInstance $appserver2searchInstance -IndexLocation $CrawlComponentsLocation
                $CrawlComponent1 = New-SPEnterpriseSearchCrawlComponent -CrawlTopology $CrawlTopology -CrawlDatabase $CrawlDatabase0 -SearchServiceInstance $appserver2searchInstance -IndexLocation $CrawlComponentsLocation
                $CrawlComponent2 = New-SPEnterpriseSearchCrawlComponent -CrawlTopology $CrawlTopology -CrawlDatabase $CrawlDatabase1 -SearchServiceInstance $appserver3searchInstance -IndexLocation $CrawlComponentsLocation
                $CrawlComponent3 = New-SPEnterpriseSearchCrawlComponent -CrawlTopology $CrawlTopology -CrawlDatabase $CrawlDatabase1 -SearchServiceInstance $appserver3searchInstance -IndexLocation $CrawlComponentsLocation

                write-host Activating new crawl topology
                # Activate the new crawl topology
                $CrawlTopology | Set-SPEnterpriseSearchCrawlTopology -Active
                Write-Host -ForegroundColor white Waiting for the old crawl topology to become inactive
                do {write-host -NoNewline .;Start-Sleep 1;} while ($InitialCrawlTopology.State -ne "Inactive")
}
catch
                {
                                Write-Output $_
                }

##Create Query Topology
try
{

write-host Retrieving Active Topology
                                # Retrieve the Active Query Topology
                                $InitialQueryTopology = $SearchServiceAppName | Get-SPEnterpriseSearchQueryTopology -Active


                                write-host Cloning Query Topology
                                # Create New topology
                                $QueryTopology = $SearchServiceAppName | New-SPEnterpriseSearchQueryTopology -Partitions 2     


                                write-host Adding Query Components


                                $IndexPartition0 = ([array](Get-SPEnterpriseSearchIndexPartition -QueryTopology $QueryTopology))[0]                               
                                $IndexPartition1 = ([array](Get-SPEnterpriseSearchIndexPartition -QueryTopology $QueryTopology))[1]

                                $QueryComponent0 = New-SPEnterpriseSearchQuerycomponent -QueryTopology $QueryTopology -IndexPartition $IndexPartition0 -SearchServiceInstance $wfe1searchInstance -IndexLocation $QueryComponentsLocation
                                $QueryComponent1 = New-SPEnterpriseSearchQuerycomponent -QueryTopology $QueryTopology -IndexPartition $IndexPartition1 -SearchServiceInstance $wfe1searchInstance -IndexLocation $QueryComponentsLocation                               
                                $QueryComponent2 = New-SPEnterpriseSearchQuerycomponent -QueryTopology $QueryTopology -IndexPartition $IndexPartition0 -SearchServiceInstance $wfe2searchInstance -IndexLocation $QueryComponentsLocation                               
                                $QueryComponent3 = New-SPEnterpriseSearchQuerycomponent -QueryTopology $QueryTopology -IndexPartition $IndexPartition1 -SearchServiceInstance $wfe2searchInstance -IndexLocation $QueryComponentsLocation                               

                                # Reuse the existing property database
                                #$PropertyDatabase0 = ([array]($SearchServiceAppName | Get-SPEnterpriseSearchPropertyDatabase))[0]

                                #Create New Property Database
                                $searchApp = Get-SPEnterpriseSearchServiceApplication $SearchServiceAppName
                                $PropertyDatabase = New-SPEnterpriseSearchPropertyDatabase -SearchApplication $searchApp -DatabaseName $propertydatabasename


                                # Assign two index partitions to the property database
                                $IndexPartition0 | Set-SPEnterpriseSearchIndexPartition -PropertyDatabase $PropertyDatabase
                                $IndexPartition1 | Set-SPEnterpriseSearchIndexPartition -PropertyDatabase $PropertyDatabase
                               
                                write-host Activating new query topology
                                # Activate the new query topology
                                $QueryTopology | Set-SPEnterpriseSearchQueryTopology -Active
                                Write-Host -ForegroundColor white Waiting for the old query topology to become inactive
                                do{write-host -NoNewline.;Start-Sleep 1;} while ($InitialQueryTopology.State -ne "Inactive")


}
catch
                {
                                Write-Output $_
                }
#EndRegion
##region to set default access account.
try
{
                Write-Host "Setting the default content access account..."
                $SearchServiceAppName | Set-SPEnterpriseSearchServiceApplication -DefaultContentAccessAccountName $ContentAccessAcctName -DefaultContentAccessAccountPassword $ContentAccessAcctPassword -Debug:$false    
                write-host "Default content access account has been set to access crawlers." -foreground green
}
catch
                {
                                Write-Output $_
                }
#EndRegion

#Region Crawl Target Configuration
Function CrawlTargetConfiguration()
{
Write-Host -ForegroundColor Blue "- Configuring Crawl Target Server..." -NoNewline
                try
                {

                $svc=[Microsoft.SharePoint.Administration.SPWebServiceInstance]::LocalContent
                $svc.DisableLocalHttpThrottling
                $svc.DisableLocalHttpThrottling=$true
                $svc.Update()
                $listOfUri = new-object System.Collections.Generic.List[System.Uri](1)
                $zoneUrl = [Microsoft.SharePoint.Administration.SPUrlZone]'Default'

                ## This is your web application url(e.g. http://xxx.com, note crawl target configuration is
                ## per web application
                $webAppUrl = $item.WebApplicationUrl
                $webApp = Get-SPWebApplication -Identity $webAppUrl
                $webApp.SiteDataServers.Remove($zoneUrl) 

                ## This is your crawl target server
                ## You can use a server name e.g.  http://crawltargetservername, or a URL e.g. ##http://webappurl
                ## you can also add multiple crawl target servers
                ## this assumes that the web application is provisioned on port 80, otherwise specify the port no
                $URLOfDedicatedMachine = New-Object System.Uri($item.CrawlTargetMachineUrl)

                $listOfUri.Add($URLOfDedicatedMachine);
                $webApp.SiteDataServers.Add($zoneUrl,$listOfUri);
                $WebApp.Update()

                ##Verify the crawl target configuration, the following script will list the configured crawl target urls
                $webAppUrl = $item.WebApplicationUrl
                $webApp = Get-SPWebApplication -Identity $webAppUrl
                $webapp.SiteDataServers | fl | Out-String


                write-host $item.crawltargetserver has been configured as crawl target server successfully -ForegroundColor Green


                }
                catch
                {
        Write-Output $_
                }             
               
}CrawlTargetConfiguration
#EndRegion

$EndDate = Get-Date
Write-Host -ForegroundColor White "-----------------------------------"
Write-Host -ForegroundColor White "| Search Creation completed |"
Write-Host -ForegroundColor White "| Started on: $StartDate |"
Write-Host -ForegroundColor White "| Completed:  $EndDate |"
Write-Host -ForegroundColor White "-----------------------------------"
Stop-Transcript
Invoke-Item $LogFile           

Below is the topology that has been created

//SetInputs.xml
<?xml version="1.0" encoding="utf-8" ?>
<SearchTopologyInputs>
  <SearchAppPoolName>SearchServiceApplicationPool</SearchAppPoolName>
  <DefaultContentAccessAcctName>domain\username</DefaultContentAccessAcctName>
  <DefaultContentAccessAcctPassword>password</DefaultContentAccessAcctPassword>
  <ManagedAccountName>domain\username</ManagedAccountName>
  <ManagedAccountPassword>password</ManagedAccountPassword>
  <SearchServiceApplicationName> Search Service Application</SearchServiceApplicationName>
  <SearchServiceApplicationProxyName> Search Service Application Proxy</SearchServiceApplicationProxyName>
  <App2servername> App2servername </App2servername> 
  <App3servername> App3servername </App3servername> 
  <wfe1servername> wfe1servername </wfe1servername> 
  <wfe2servername> wfe2servername </wfe2servername>
  <wfe3servername> wfe3servername </wfe3servername>
  <CrawlDatabase>Search_Service_Application_CrawlStore02</CrawlDatabase>
  <PropertyDatabase> Search_Service_Application_PropertyStore02</PropertyDatabase>
  <CrawlComponentsLocation>E:\crawlcomponents</CrawlComponentsLocation>
  <QueryComponentsLocation>E:\querycomponents</QueryComponentsLocation>
  <DBServer1>INSQL06_01</DBServer1>
  <DBServer2>INSQL06_02</DBServer2>
  <DBServer3>INSQL06_03</DBServer3>
  <crawltargetserver>crawltargetservername</crawltargetserver>
  <WebApplicationUrl>http://webappurl</WebApplicationUrl>
  <CrawlTargetMachineUrl>http://crawltargetservername</CrawlTargetMachineUrl>
</SearchTopologyInputs>

No comments:

Post a Comment