Thursday, April 9, 2015

SharePoint 2013: Create Result Sources With PowerShell

Hello Readers!

Sorry for the delay in posts recently, between work and personal events I have been totally swamped (in a good way)!

What I wanted to share today is PowerShell script which provisions result sources at the Site Collection level.  The script will loop through each result source within the script, check to see if it exists, if it does it will blow it away and re-create it or if it is brand new just create   This script is useful for automating deployments or if you need to create the same result sources on multiple site collections.


If you need to deploy result sources at the Search Service Application Level, simply swap out: SPSite with Ssa at our $searchOwner line.  Your site collection URL and Search Service Application are both params which will be prompted.


$searchOwner = New-Object Microsoft.Office.Server.Search.Administration.SearchObjectOwner([Microsoft.Office.Server.Search.Administration.SearchObjectLevel]::SPSite, $site.RootWeb)

The real question though, what do you need to update in order to use this script?  Luckily, the only parts you need to update are the actual result sources themselves!  This is under the Result Sources Start Here Section.  The below example is for a result source which finds anything with the ContentTypeId matching Article.  For the below section I did not need a sort order, but if you do un-comment out the sortCollection and queryProperties line.  You can swap out "Created" with the Managed property you need to sort by.  You can also swap out Descending with Ascending if desired.  The name of the result source is input between the single quotes, my example result source below will be called Articles.


# Articles
Write-Host -ForegroundColor Green "Starting To Build  Articles Result Source"
# define query and sorting
$query = "ContentTypeId:0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39003F11102A7C0343B0836EDF8DA14F33ED00B679312D96584105BCFD3A33F39BD3AF*"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
##This can be updated if a sort order is required
#$sortCollection.Add("Created", [Microsoft.Office.Server.Search.Query.SortDirection]::Descending) 
#$queryProperties["SortList"] = [Microsoft.Office.Server.Search.Query.SortCollection]$sortCollection
# create result source
CreateResultSource $searchOwner $fedManager ' Articles' $queryProperties $query 
Write-Host -ForegroundColor Yellow " Articles Result Source Complete"

How to use this script:
  1. Update the script to include each result source you need created, you can swap out my example result sources with your own
  2. Run the script
  3. When prompted: input your root site collection url: i.e. http://danstestsite.local
  4. When prompted: input your search service application name (make sure to put it in double quotes) i.e. "Search Service Application"
  5. Check out the new result sources at your site collection level!
Full Script:


## Getting the ducks in a row
param($url = $(Read-Host -prompt "Site Colleciton Root URL"), $ssaName = $(Read-Host -prompt "Search Service Application Name"))

#Funciton To Create Result Sources
function CreateResultSource($searchOwner, $fedManager, $name, $queryProperties, $query)
{  
   # check if result source already exists
   $resultSource = $fedManager.GetSourceByName($name, $searchOwner)

   if ($resultSource -eq $null) 
   {    
        Write-Host -f cyan "Creating Result Source <"$name">."
        
        #create result source
        $resultSource = $fedManager.CreateSource($searchOwner)      
        $resultSource.Name = $name
        $resultSource.CreateQueryTransform($queryProperties, $query)
        $resultSource.ProviderId = $fedManager.ListProviders()["Local SharePoint Provider"].Id
        $resultSource.Commit()
   }
   else
   {
        Write-Host -f Green "Result Source" $name "already exists, updating" $name "result source"

        # print properties of existing result source 
        $source = $fedManager.GetSourceByName($name, $searchOwner) 
        $fedManager.RemoveSource($source)
          #create result source
        $resultSource = $fedManager.CreateSource($searchOwner)      
        $resultSource.Name = $name
        $resultSource.CreateQueryTransform($queryProperties, $query)
        $resultSource.ProviderId = $fedManager.ListProviders()["Local SharePoint Provider"].Id
        $resultSource.Commit()
   }
   return $resultSource
}

Write-Host -ForegroundColor Green "Script Warming Up And Adding Snapins"
Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue

Start-SPAssignment -Global

#Get SP Site and SP Web
##$url = (Read-Host -Prompt "Site Collection URL")
$url = $url.Trim()
$web = get-spweb $url
$site = get-spsite $url -WarningAction SilentlyContinue

#Get Search Service Applicaiton
$ssa = Get-SPEnterpriseSearchServiceApplication $ssaName -ErrorAction SilentlyContinue
if($ssa -eq $null) {
    $ssa = @(Get-SPEnterpriseSearchServiceApplication)[0]
}

#Output results from SSA
Write-host -ForegroundColor Cyan ("Using search app {0}" -f $ssa.Name)

# load Search assembly
Write-Host -ForegroundColor Green "Loading Search Assemblies"
[void] [Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.Search")

# create manager instances
$fedManager = New-Object Microsoft.Office.Server.Search.Administration.Query.FederationManager($ssa)
    Write-Host -ForegroundColor Green "The fed manager is" $fedManager


#Update SPSite to Ssa if you want them provisioned at Search Service Level
$searchOwner = New-Object Microsoft.Office.Server.Search.Administration.SearchObjectOwner([Microsoft.Office.Server.Search.Administration.SearchObjectLevel]::SPSite, $site.RootWeb)
    Write-Host -ForegroundColor Cyan "The Search Owner is" $searchOwner

###################################################################################
#Result Sources Start Here
###################################################################################


# Articles
Write-Host -ForegroundColor Green "Starting To Build  Articles Result Source"
# define query and sorting
$query = "ContentTypeId:0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39003F11102A7C0343B0836EDF8DA14F33ED00B679312D96584105BCFD3A33F39BD3AF*"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
##This can be updated if a sort order is required
#$sortCollection.Add("Created", [Microsoft.Office.Server.Search.Query.SortDirection]::Descending) 
#$queryProperties["SortList"] = [Microsoft.Office.Server.Search.Query.SortCollection]$sortCollection
# create result source
CreateResultSource $searchOwner $fedManager ' Articles' $queryProperties $query 
Write-Host -ForegroundColor cyan " Articles Result Source Complete"


#Statistic
Write-Host -ForegroundColor Green "Starting To Build Statistic Result Source"
$query = "ContentTypeId:0x0100AAF9B8EBA36A47F6BB7BA54A5D01B1B8001B7C18A4B6C343C88F4D4293F72F397400ABFD858ADE3B44A0988105611D2187B1*"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
CreateResultSource $searchOwner $fedManager ' Statistics' $queryProperties $query 
Write-Host -ForegroundColor cyan "Statistic Result Source Complete"

#Event Documents
Write-Host -ForegroundColor Green "Starting To Build Call To Event Documents Result Source"
$query = "ContentTypeId:0x01010069411AE48AE74A3096A71D0C77BC6CBD* AND ManagedTerm:{Term.Id}"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
CreateResultSource $searchOwner $fedManager 'Event Documents' $queryProperties $query 
Write-Host -ForegroundColor cyan "Event Documents Result Source Complete"

#Event Images
Write-Host -ForegroundColor Green "Starting To Build Event Images Result Source"
$query = "ContentTypeId:0x010102002042E861E3D14C70B595912F16571C8C* AND ManagedTerm:{Term.Id}"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
CreateResultSource $searchOwner $fedManager 'Event Images' $queryProperties $query 
Write-Host -ForegroundColor cyan "Event Images Result Source Complete"



###################################################################################
#Result Sources End Here
###################################################################################
Well that is really it folks, hopefully this helps to automate some deployments or at the very least was an interesting read! Dan