Building a Site Directory with SharePoint Search


(For more resources on Microsoft Sharepoint, see here.)

Site Directory options

There are two main approaches to providing a Site Directory feature:

  • A central list that has to be maintained
  • Using a search-based tool that can provide the information dynamically


List-based Site Directory

With a list-based Site Directory, a list is provisioned in a central site collection, such as the root of a portal or intranet. Like all lists, site columns can be defined to help describe the site's metadata. Since it is stored in a central list, the information can easily be queried, which can make it easy to show a listing of all sites and perform filtering, sorting, and grouping, like all SharePoint lists.

It is important to consider the overall site topology within the farm. If everything of relevance is stored within a single site collection, a list-based Site Directory, accessible throughout that site collection, may be easy to implement. But as soon as you have a large number of site collections or web applications, you will no longer be able to easily use that Site Directory without creating custom solutions that can access the central content and display it on those other sites. In addition, you will need to ensure that all users have access to read from that central site and list.

Another downside to this approach is that the list-based Site Directory has to be maintained to be effective, and in many cases it is very difficult to keep up with this. It is possible to add new sites to the directory programmatically, using an event receiver, or as part of a process that automates the site creation. However, through the site's life cycle, changes will inevitably have to be made, and in many cases sites will be retired, archived, or deleted.

While this approach tends to work well in small, centrally controlled environments, it does not work well at all in most of the large, distributed environments where the number of sites is expected to be larger and the rate of change is typically more frequent.

Search-based site discovery

An alternative to the list-based Site Directory is a completely dynamic site discovery based on the search system. In this case the content is completely dynamic and requires no specific maintenance. As sites are created, updated, or removed, the changes will be updated in the index as the scheduled crawls complete. For environments with a large number of sites, with a high frequency of new sites being created, this is the preferred approach.

The content can also be accessed throughout the environment without having to worry about site collection boundaries, and can also be leveraged using out of the box features.

The downside to this approach is that there will be a limit to the metadata you can associate with the site. Standard metadata that will be related to the site include the site's name, description, URL, and to a lesser extent, the managed path used to configure the site collection. From these items you can infer keyword relevance, but there is no support for extended properties that can help correlate the site with categories, divisions, or other specific attributes.

How to leverage search

Most users are familiar with how to use the Search features to find content, but are not familiar with some of the capabilities that can help them pinpoint specific content or specific types of content. This section will provide an overview on how to leverage search to provide features that help support users finding results that are only related to sites.

Content classes

SharePoint Search includes an object classification system that can be used to identify specific types of items as shown in the next table. It is stored in the index as a property of the item, making it available for all queries.

Content Class



Site Collection objects


Subsite/Web objects


List objects where [templatename] is the name of the template such as Announcements or DocumentLibrary.


List Item objects where [templatename] is the name of the template such as Announcements or DocumentLibrary.


User Profile objects (requires a User Profile Service Application)

The contentclass property can be included as part of an ad hoc search performed by a user, included in the search query within a customization, or as we will see in the next section, used to provide a filter to a Search Scope.

Search Scopes

Search Scopes provide a way to filter down the entire search index. As the index grows and is filled with potentially similar information, it can be helpful to define Search Scopes to put specific set of rules in place to reduce the initial index that the search query is executed against. This allows you to execute a search within a specific context. The rules can be set based on the specific location, specific property values, or the crawl source of the content.

The Search Scopes can be either defined centrally within the Search service application by an administrator or within a given Site Collection by a Site Collection administrator. If the scope is going to be used in multiple Site Collections, it should be defined in the Search service application. Once defined, it is available in the Search Scopes dropdown box for any ad hoc queries, within the custom code, or within the Search Web Parts.

Defining the Site Directory Search Scope

To support dynamic discovery of the sites, we will configure a Search Scope that will look at just site collections and subsites. As we saw above, this will enable us to separate out the site objects from the rest of the content in the search index. This Search Scope will serve as the foundation for all of the solutions in this article.

To create a custom Search Scope:

  1. Navigate to the Search Service Application.
  2. Click on the Search Scopes link on the QuickLaunch menu under the Queries and Results heading.
  3. Set the Title field to Site Directory.
  4. Provide a Description.
  5. Click on the OK button as shown in the following screenshot:

  6. From the View Scopes page, click on the Add Rules link next to the new Search Scope.
  7. For the Scope Rule Type select the Property Query option.
  8. For the Property Query select the contentclass option.
  9. Set the property value to STS_Site.
  10. For the Behaviorsection, select the Include option.

  11. From the Scope Properties page, select the New Rule link.
  12. For the Scope Rule Type section, select the Property Query option./li>
  13. For the Property Query select the contentclass option.
  14. Set the property value to STS_Web.
  15. For the Behavior section, select the Include option.


The end result will be a Search Scope that will include all Site Collection and subsite entries. There will be no user generated content included in the search results of this scope.

After finishing the configuration for the rules there will be a short delay before the scope is available for use. A scheduled job will need to compile the search scope changes.

Once compiled, the View Scopes page will list out the currently configured search scopes, their status, and how many items in the index match the rules within the search scopes.

Enabling the Search Scope on a Site Collection

Once a Search Scope has been defined you can then associate it with the Site Collection(s) you would like to use it from. Associating the Search Scope to the Site Collection will allow the scope to be selected from within the Scopes dropdown on applicable search forms. This can be done by a Site Collection administrator one Site Collection at a time or it can be set via a PowerShell script on all Site Collections.

To associate the search scope manually:

  1. Navigate to the Site Settings page.
  2. Under the Site Collection Administration section, click on the Search Scopes link.
  3. In the menu, select the Display Groups action.
  4. Select the Search Dropdown item.
  5. You can now select the Sites Scope for display and adjust its position within the list.
  6. Click on the OK button when complete.


Testing the Site Directory Search Scope

Once the scope has been associated with the Site Collection's search settings, you will be able to select the Site Directory scope and perform a search, as shown in the following screenshot:

Any matching Site Collections or subsites will be displayed. As we can see from the results shown in the next screenshot, the ERP Upgrade project site collection comes back as well as the Project Blog subsite.


(For more resources on Microsoft Sharepoint, see here.)

Site Directory page

The initial configuration of the Site Directory Search Scope pointed to the standard results search page. While this may work fine in some cases, a custom results page will allow you to fine tune the user experience and also make additional searches or refinements a little easier.

Creating the Site Directory page

We will now add a custom page to the Search Center to support our Site Directory search page. Once added to the Search Center it will then be configured to be the default destination for the Site Directory search scope.

To create the page:

  1. Navigate to the default Search Center.
  2. Click Site Actions | Show Ribbon.
  3. Select the Page tab.
  4. Select the View All Pages action.



  5. Select the Documents tab.
  6. Click the New Document action and select Page as shown in the next screenshot:

  7. Set the Title field to the value Site Directory.
  8. Provide a Description.
  9. Provide a URL Name such as Site -Directory.
  10. Ensure that for the Page Layout, (Welcome Page) Search results is selected.
  11. Click on the Create button.


Configure the Site Directory page settings

We will now see a standard search results page and will need to make a few minor changes in order to be used to support the Site Directory requirements.

To configure the page's settings:

  1. Click on Site Actions | Edit Page.
  2. From Search Box Web Part, select the Edit Web Part action.
  3. Within the Miscellaneous section, change the Target search results page URL to Site-Directory.aspx so that it directs the request to our Site Directory page.
  4. Click the OK button.
  5. From the Search Core Results Web Part, select the Edit Web Part action.
  6. Within the Location Properties section, set the Scope property to Site Directory.
  7. Within the More Results Link Options, check the checkbox to Show More Results Link.
  8. Click on the OK button.


Adding a Site Directory tab

With both the search query and result pages there is a control that will display contextual tabs that can be used to navigate to customized search pages. The All Sites and People tabs are added by default, but additional tabs can be configured. To make it easy for users to search the Site Directory from the Search Center, we will add a Site Directory tab. Please note, since the values are stored in a set of central lists within the Search Center, you only need to configure the tabs once for the regular search pages and once for the results pages.

To add a new tab:

  1. Click on the Add New Tab option under the existing tabs.
  2. Set the Tab Name property to Site Directory.
  3. Set the Page property to Site-Directory.aspx .
  4. Set the Tooltip property to Click for relevant sites.
  5. Click on the Save button.


Common Searches

The search system's query engine is extremely powerful, but most users are not familiar enough with how to format the queries for advanced searches. A great way to address this is by providing a list of common search keywords and saved queries. This will allow users to quickly and easily initiate a search and it will work with the Refinement Web Part to provide additional drill through capabilities.

This Common Searches information can be saved in a simple link list within the Search Center. Like the search tabs feature, this provides an easy way for the Search Center administrator to maintain the configuration through the standard SharePoint UI. The standard link list template is sufficient, but if you want to potentially have different lists for different search tabs, then I recommend that you add a lookup field to the Tab Name field of the Tabs in Search Results list. A sample view of the list is displayed in the next screenshot:

Defining Common Searches

Adding a saved search is as simple as adding an entry to the link list. The key to this solution is in the formatting of the linked URL. There are three main parameters in the URL that you will frequently need to use.






Search Scope



Simple saved query

In its simplest form, keywords are passed to the results page in the URL's query string. This is the same result as a user passing in a simple keyword in the search box. It might look like this: http://intranet/search2/Pages/Site-Directory. aspx?k=HR!.

The URL can be separated into two parts with the first part being the path to the results page: http://intranet/search2/Pages/Site-Directory.aspx, and the remaining part which identifies the keyword query that will be executed: k=HR.

Advanced saved query

Through the query language it is possible to specify additional keywords and logical operations. The following example will search for Blog subsites and apply a refiner to ensure that any returned sites are within the MySites area.

The query would look like this: k=Blog&r=site%3D%22http%3A%2F%2Fintranet%2F my%2Fpersonal%22.

The keyword part is set to k=Blog. The refiner part is set to r=site%3D%22http%3A%2 F%2Fintranet%2Fmy%2Fpersonal%22.

Adding Common Searches to the Site Directory page

To add the Common Searches list to the Site Directory page we will simply add a standard list view set to the summary view, which will present a bulleted list. Additional properties can be set to change the title and overall display if desired. Alternatively this can be displayed via a Client OM script or a Server OM Web Part if additional control is needed over the rendered display.

Site Directory displayed

The completed Site Directory page with the Common Searches listing is displayed in the following screenshot:

A close up view of the Common Searches list view Web Part is displayed in the following screenshot:

Related sites Web Part

In addition to making it easy for the users to execute ad hoc site searches, it may also be valuable to dynamically display a listing of related web sites. To provide this feature, one approach would be to create a Web Part that allows the site owner to specify some related keywords, and then perform the Site Directory search and display a list of relevant sites.

Creating the Web Part

To add the additional Web Part:

  1. Open the SPBlueprints.WebParts project in Visual Studio 2010.
  2. Browse the installed templates and select Visual C# | SharePoint 2010.
  3. Right-click on the project file and select Add | New Item.
  4. From the template selection screen select the Web Part option.
  5. Provide the name RelatedSites and click on the Add button.
  6. Edit the RelatedSites.webpart file, and add in the custom properties as shown in the following:

    <property name="Title" type="string">Related Sites</property>
    <property name="Description" type="string">SPBlueprints - The
    Related Sites web part will search for sites with matching
    <property name="SearchProxyName" type="string">Search Service
    <property name="SearchScopeName" type="string">Site Directory</
    <property name="DisplayLimit" type="int">5</property>
    <property name="KeywordList" type="string">sites</property>

  7. Start by editing the RelatedSites.cs file and add in the following references:

    using System.Collections;
    using System.Data;
    using System.Text;
    using Microsoft.SharePoint.Administration;
    using Microsoft.Office.Server.Search;
    using Microsoft.Office.Server.Search.Query;
    using Microsoft.Office.Server.Search.Administration;

  8. Next we will need to define the Web Part's properties starting with the Search Proxy Name property. This property will be used to manage the connection to the Search service application.

    private string _searchProxyName;
    WebDisplayName("Search Proxy Name"),
    WebDescription("Please provide the name of your Search Service
    public string SearchProxyName
    get { return _searchProxyName; }
    set { _searchProxyName = value; }

  9. Next we will define the Search Scope Name property which can be used to target the desirable content for display.

    private string _searchScopeName;
    WebDisplayName("Search Scope Name"),
    WebDescription("Please provide the name of your Search Scope."),
    public string SearchScopeName
    get { return _searchScopeName; }
    set { _searchScopeName = value; }

  10. Next we will define the Display Limit property used to determine how many records to display.

    private int _displayLimit;
    Category("Configuration "),
    WebDisplayName("Result limit"),
    WebDescription("The number of items to display."),
    public int DisplayLimit
    get { return _displayLimit; }
    set { _displayLimit = value; }

  11. Next we will define the Keywords property where the site administrator will actually set the keywords.

    private string _keywordList;
    WebDescription("Comma delimited list of keywords"),
    public string KeywordList
    get { return _keywordList; }
    set { _keywordList = value; }

  12. The output will be built within a Literal control defined within the class, and instantiated within the CreateChildControls() method as shown in the following:

    protected Literal _output;
    protected override void CreateChildControls()
    this._output = new Literal();
    this._output.ID = "output";

  13. With all of the setup work complete, we can now define the Display() method that can be called from the OnLoad() method . The method starts by defining StringBuilder that we will use to build the output of the Web Part, and then checks to see if there are any keywords set. Since the keywords are stored within a single string property and are comma delimited, we will do a simple split command to load the values into an array. If there are no keywords, there will be no content to display.

    protected void Display()
    StringBuilder messages = new StringBuilder();
    string[] keywords = this._keywordList.Split(',');
    if (keywords[0] != "")

  14. Next we attempt to connect to the Search Proxy specified in the Web Part properties. There is a try /catch block here in order to handle issues related to connecting to the Search service application differently than errors returned as part of a search.

    SearchQueryAndSiteSettingsServiceProxy settingsProxy = SPFarm.
    SearchServiceApplicationProxy searchProxy = settingsProxy.
    // Query and Display of Web Part
    this._output.Text = "Error: Please specify a Search Service

  15. Now we can instantiate FullTestSqlQuery and prepare the data objects.

    FullTextSqlQuery mQuery = new FullTextSqlQuery(searchProxy);
    ResultTableCollection resultsTableCollection;
    DataTable results = new DataTable();

  16. The formatted query will be broken into two parts, with the first part being the same in all cases and then the addition of the dynamic keywords with a variable number of items. We will then define a simple for loop to append the query to include a dynamic part that covers each keyword. Since we are looking for matches for any of the keywords, the OR operator will be used, which will require that we set the scope predicate starting with the second keyword. The query can also be tailored to exclude other content in your environment as needed.

    mQuery.QueryText = "SELECT Title, Path, SiteName FROM SCOPE()
    Where ";
    for (int i = 0; i <= keywords.GetUpperBound(0); i++)
    if (i > 0) mQuery.QueryText += " OR ";
    mQuery.QueryText += " ((\"scope\" = '" + _searchScopeName + "')
    AND Contains('" + keywords[i] + "'))";

  17. The remaining FullTextSqlQuery properties can now be set and the query executed. The returned DataTable object can now be checked for results to see if the list needs to be rendered.

    mQuery.ResultTypes = ResultType.RelevantResults;
    mQuery.TrimDuplicates = true;
    mQuery.RowLimit = DisplayLimit;
    resultsTableCollection = mQuery.Execute();
    if (resultsTableCollection.Count > 0)
    ResultTable relevantResults = resultsTableCollection[ResultType.
    results.Load(relevantResults, LoadOption.OverwriteChanges);

  18. The output can be as simple or as complex as needed. For this example, I will create a simple HTML bulleted list with a link to the site. A DIV container and the list will be defined, and then we will iterate through the rows, and write out each link.

    messages.AppendFormat(@"<div id='RelatedSites'><ul>");
    foreach (DataRow row in results.Rows)
    messages.AppendFormat(@"<li><a href='{1}'>{0}</a></li>",
    row["Title"].ToString(), row["Path"].ToString(), row["SiteName"].

  19. With the display complete we can now render the output, complete the catch block to handle any exceptions, and dispose our Query object.

    this._output.Text = messages.ToString();
    catch (Exception ex)
    this._output.Text = "Error: " + ex.Message.ToString();


Display Related sites Web Part

Once deployed, the Related sites Web Part can be configured to set the desired keywords in a comma delimited list. The rendered screen is shown as follows:


This article leveraged the search features and configuration along with the Server OM to create a set of solutions that can be used to provide users with easy and intuitive ways to locate relevant sites.

The customizations are grouped as follows:

  • Visual Studio 2010
    • Web Part : Creating a custom Web Part that can display related sites based on a keyword property.
  • Browser based configuration
    • Configure Search Scopes: Create a Search Scope that automatically filters the content to show only site objects, and excludes any other type of content.
    • Search Results Page: A custom search results page that works with our custom search scope, and also includes some additional Web Parts to enhance the user's ability to find relevant sites.
    • Configure Core Results Web Part: The Core Results Web Part was configured to show our Site Directory and interactive search results.

This article showed how you can develop effective solutions that provide easy ways for users to find the relevant sites and resources needed to ensure better collaboration and process efficiency. These solutions are very easy to implement and can deliver immediate value.

Further resources on this subject:

You've been reading an excerpt of:

Microsoft SharePoint 2010 Business Application Blueprints

Explore Title