Sunday, February 23, 2014

How to trigger a full re-index in SharePoint On-line

[Update 2019-09-02]
The script is no longer available due to request from Microsoft support - and there are good reasons for not doing this, even though there are good reasons for doing it as well :) Hit me up on twitter questions.

[Update 2015-01-05]
Latest version of the script can be found at https://github.com/wobba/SPO-Trigger-Reindex

In SharePoint Online you cannot trigger a full re-index of all your data as you can on-premises via the Content Sources on your Search Service Application.

And this might be something you would like to do, especially if you start mapping crawled properties to new managed properties. A full list of scenario’s which require a full re-index is available at TechNet.

The only option provided in SPO is to via the settings pages on a site or a list/library, trigger a re-index as outlined in the SPO documentation.

But fortunately this is not entirely true, as you via CSOM can manipulate a site’s property bag and set or change the value of vti_searchversion which is what triggers a re-index of this site. The same property applies to a list/library.

The below script uses the SharePoint Online Management cmdlets to iterate all the site collections, and SharePoint CSOM to iterate the sites within each site collection. For each site it will update vti_searchversion, which will trigger the site to be picked up for re-indexing on the next crawl cycle.

Note: This will not improve crawl time, merely ensure items are re-indexed.
The script may be downloaded from http://gallery.technet.microsoft.com/How-to-full-crawl-your-07d24bbd

# Re-index SPO tenant script
# Author: Mikael Svenson - @mikaelsvenson
# Blog: http://techmikael.blogspot.com

Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
# replace these details or use Get-Credential to enter password securely as script runs
$username = "admin@tenant.onmicrosoft.com" 
$password = "password" 
$url = "https://tenant.sharepoint.com"
$adminUrl = "https://tenant-admin.sharepoint.com"
 
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force 

# change to the path of your CSOM dll's
$csomPath = "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI"

Add-Type -Path "$csomPath\Microsoft.SharePoint.Client.dll" 
Add-Type -Path "$csomPath\Microsoft.SharePoint.Client.Runtime.dll" 

$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword) 

function Reset-Webs( $siteUrl ) {
    $clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)     
    $clientContext.Credentials = $credentials 
     
    if (!$clientContext.ServerObjectIsNull.Value) 
    { 
        Write-Host "Connected to SharePoint Online site: '$siteUrl'" -ForegroundColor Green 
    } 
     
    function processWeb($web)
    {
        $subWebs = $web.Webs
        $clientContext.Load($web)
        $clientContext.Load($web.AllProperties)
        $clientContext.Load($subWebs)
        $clientContext.ExecuteQuery()
        [int]$version = 0
        $allProperties = $web.AllProperties
        Write-Host "Web URL:" $web.Url -ForegroundColor White
        if( $allProperties.FieldValues.ContainsKey("vti_searchversion") -eq $true ) {
            $version = $allProperties["vti_searchversion"]            
        }
        Write-Host "Current search version: " $version -ForegroundColor White
        $version++
        $allProperties["vti_searchversion"] = $version
        Write-Host "Updated search version: " $version -ForegroundColor White
        $web.Update()
        $clientContext.ExecuteQuery()

        foreach ($subWeb in $subWebs)
        {
            processWeb($subWeb)
        }
    }

    $rootWeb = $clientContext.Web
    processWeb($rootWeb)
}

$spoCredentials = New-Object System.Management.Automation.PSCredential($username, $securePassword)

Connect-SPOService -Url $adminUrl -Credential $spoCredentials
Get-SPOSite | foreach {Reset-Webs -siteUrl $_.Url }