Querying SharePoint Search from PowerShell

FAST Search for SharePoint 2010 (FS4SP) is a really powerful, flexible and scalable enterprise search engine. However, when compared with the search landscape in SharePoint 2013, it feels like a separate product, an add-on to SharePoint 2010 that gives you a more powerful alternative to the out-of-the-box search engine.

When using FS4SP in a production environment, you need a separate farm just for FAST. That is, you need a set of servers where you install FS4SP and then you connect that FAST farm to a SharePoint farm, by means of two Search Service Applications. These FAST servers don’t have SharePoint installed on them and they have their own PowerShell snap-in that allows you to perform a whole bunch of administration tasks on FS4SP.

Suppose you want to query your search index, for testing or maintenance purposes, in PowerShell. The easiest solution would be to open your SharePoint 2010 Administration PowerShell console, and use the Server Side Object Model to create a new KeywordQuery object and invoke the Execute method on it. You can find many blog posts that teach how to do this. Here’s one example. If, for some reason, you need to run that PowerShell script from one of the FAST servers it won’t work because these servers don’t have SharePoint installed and are not part of the SharePoint farm, hence you can’t use the Server Object Model.

In this case, you’ll need to use the search web service, which can be called from any server as long as it can communicate with the SharePoint farm. The script below shows how you can do this.

$WebApplicationURL = "http://myserver:9999"
$SearchServiceURL = "/_vti_bin/search.asmx"

# Create a proxy to call the search web service
$SearchWS = New-WebServiceProxy -Uri ($WebApplicationURL + $SearchServiceURL) -UseDefaultCredential

# Build the query XML. You can use FQL or KQL.
$queryXml = @"
<QueryPacket Revision="1000">
      <QueryText language="en-US" type="FQL">SharePoint</QueryText>
    <SupportedFormats Format="urn:Microsoft.Search.Response.Document.Document" />
      <Property name="Rank" />
      <Property name="Title" />
      <Property name="Author" />
      <Property name="Write" />
      <Property name="Path" />

# call the web service
$results = $SearchWS.QueryEx($queryXml)

# process the results
if ($results -ne $null -And $results.Tables["RelevantResults"] -ne $null)
    # check the result count (this page) and the total result count (all pages)
    $resultCount = $results.Tables["RelevantResults"].Rows.Count
    $totalCount = $results.Tables["RelevantResults"].ExtendedProperties["TotalRows"]
    Write-Host "Retrieved $resultCount (from a total of $totalCount) results."
    # write the title of each result in the console window
    foreach ($row in $results.Tables["RelevantResults"].Rows)
        Write-Host $row["Title"]