# encoding: ascii
# api: powershell
# title: Get-CrawlHealth (MOSS)
# description: This extends the functionality of the SharePoint Search Administration page, producing dashboard-like analysis of your farm’s search crawls. I do not intend to use this script in production, but instead will use it as a starting point to help me build out search crawl health monitoring functionality.
# version: 1.0
# type: function
# author: Peter
# license: CC0
# function: Calculate-CrawlDuration
# x-poshcode-id: 1264
# x-archived: 2011-12-28T18:41:08
# x-published: 2011-08-10T13:37:00
#
# Added mid-expression newlines for readability. EDIT: now no longer formats the result as a list—you may now choose to format the results yourself (or not)
# EDIT: oopsies, fixed math error in index health calculator; now index health calculator is (appropriately) less generous
#
[reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint") | out-null
[reflection.assembly]::LoadWithPartialName("Microsoft.Office.Server") | out-null
[reflection.assembly]::LoadWithPartialName("Microsoft.Office.Server.Search") | out-null
#NOTE: I've set strict crawl freshness/crawl duration/success ratio threshholds. Reset as desired
# to something that more suits your reality.
$crawlFreshnessDayThreshhold = 2
$crawlDurationHourThreshhold = 4
$successRatioThreshhold = 0.9
function Calculate-CrawlDuration(
[Microsoft.Office.Server.Search.Administration.SharePointContentSource]$contentSource)
{
if ($contentSource.CrawlStatus -eq [Microsoft.Office.Server.Search.Administration.CrawlStatus]::Idle) {
return "Green - no current crawl"
}
$timespan = [datetime]::Now - $contentSource.CrawlStarted
$timespanFormatted = "Running for $($timespan.TotalDays.ToString('0.00')) Days" +
"($($timespan.TotalHours.ToString('0.0')) hours)"
if ($timespan.TotalHours -le ($crawlDurationHourThreshhold / 2)) {
return "Green - $timespanFormatted"
} elseif ($timespan.TotalHours -le ($crawlDurationHourThreshhold)) {
return "Yellow - $timespanFormatted"
} else {
return "Red - $timespanFormatted"
}
}
function Calculate-CrawlFreshness(
[Microsoft.Office.Server.Search.Administration.SharePointContentSource]$contentSource)
{
$timespan = [datetime]::Now - $contentSource.CrawlCompleted
$timespanFormatted = "$($timespan.TotalDays.ToString('0.00')) days ago"
if ($timespan.Days -le 0) {
return "Green - $timespanFormatted"
} elseif ($timespan.Days -lt $crawlFreshnessDayThreshhold) {
return "Yellow - $timespanFormatted"
} else {
return "Red - $timespanFormatted"
}
}
function Calculate-IndexHealth(
[Microsoft.Office.Server.Search.Administration.SharePointContentSource]$contentSource,
$successCount, $warningCount, $errorCount)
{
$formatted = "($($successCount)/$($warningCount)/$($errorCount))"
if ($errorCount -eq 1) {
return "Red - exactly 1 error, usually indicates permissions/config error - $formatted"
}
$successRatio = ([double]$successCount)/([double]($warningCount + $errorCount))
$successRatioMidpointToPerfection = (1.0 + $successRatioThreshhold)/2.0
if ($successRatio -ge $successRatioMidpointToPerfection) {
return "Green - $formatted"
} elseif ($successRatio -ge $successRatioThreshhold) {
return "Yellow - $formatted"
} else {
return "Red - $formatted"
}
}
function Get-CrawlHealth
{
$serverContext = [Microsoft.Office.Server.ServerContext]::Default
$searchContext = [Microsoft.Office.Server.Search.Administration.SearchContext]::GetContext($serverContext)
$content = [Microsoft.Office.Server.Search.Administration.Content]$searchContext
$history = [Microsoft.Office.Server.Search.Administration.CrawlHistory]$searchContext
$contentSources = $content.ContentSources | foreach { $_ }
$contentSources | foreach {
#unroll DataTable object into more useful DataRow object
$crawlHistory = $history.GetLastCompletedCrawlHistory($_.Id) | % { $_ }
add-member -inputobject $_ -membertype NoteProperty -name "CurrentCrawlDuration" -value (
Calculate-CrawlDuration $_)
add-member -inputobject $_ -membertype NoteProperty -name "CompletedCrawlFreshness" -value (
Calculate-CrawlFreshness $_)
add-member -inputobject $_ -membertype NoteProperty -name "IndexHealth" -value (
Calculate-IndexHealth -contentSource $_ -successCount $crawlHistory.SuccessCount -warningCount (
$crawlHistory.WarningCount) -errorCount $crawlHistory.ErrorCount)
}
$contentSources | select Name, CurrentCrawlDuration, CompletedCrawlFreshness, IndexHealth
}
#USAGE: -Open a PowerShell session on the SharePoint server with elevated credentials
# (specifically, with access to the SSP - usually the SharePoint farm account)
# -Tweak the threshholds (they may be too ambitious for your environment)
# -Paste this text into an open PowerShell window and type (without the # mark)
# Get-CrawlHealth | Format-List