How to: Create a Health Rule
Applies to: SharePoint Foundation 2010
In Microsoft SharePoint Foundation 2010, you create a health rule by writing code for a concrete subclass that inherits from one of these two abstract classes: SPHealthAnalysisRule or SPRepairableHealthAnalysisRule.
Both base classes require that you implement the Summary, Explanation, Remedy, Category, and ErrorLevel properties as well as the Check() method. For custom rules, do not set the ErrorLevel to Success or RuleExecutionFailure, which are for internal use only.
Use the Check method to detect the problem that your rule is designed to find. If your rule inherits from the SPRepairableHealthAnalysisRule class, you must also implement the Repair() method. This is where to place code that corrects the problem found by the Check method.
If you intend to install the rule so that it can run automatically, you should also override and implement the AutomaticExecutionParameters property. This property provides default settings for the timer job that runs the rule.
To create a health rule
Open Visual Studio as an administrator by right-clicking the program in the Start menu and selecting Run as administrator.
Create a new class library project.
In the New Project dialog, select Visual C# or Visual Basic, then select Windows and choose the Class Library template.
The name that you give your project is used as the default namespace for the assembly. Several health rules can be deployed in the same assembly, so you should consider naming the project accordingly: CompanyNameHealthRules, for example.
Sign the assembly.
In Solution Explorer, right-click the project name and select Properties. On the property sheet, click Signing, and then check Sign the assembly. Browse to a strong name key file or create a new one.
This step is necessary because the assembly must be installed in the Global Assembly Cache (GAC) on all machines before it is registered with SharePoint Health Analyzer. Assemblies that are installed in the GAC must be signed with a strong name. For more information, see How to: Sign an Assembly with a Strong Name.
Change the name of the class from Class1 to a name that describes the error that your rule will detect.
In Solution Explorer, right-click the file Class1.cs or Class1.vb, choose Rename, and then type a new name. When you are asked if you want to rename all references to Class1, click Yes.
Add a reference to Microsoft.SharePoint.dll.
In Solution Explorer, right-click the project name and select Add Reference.... In the Add Reference dialog, browse to %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\ISAPI\Microsoft.SharePoint.dll. Select Microsoft.SharePoint.dll, and then click OK.
Add a using statement (Imports in Visual Basic) for the Microsoft.SharePoint.Administration.Health namespace.
using Microsoft.SharePoint.Administration.Health;
Imports Microsoft.SharePoint.Administration.Health
Modify the class declaration so that the class inherits either from the SPHealthAnalysisRule class or the SPRepairableHealthAnalysisRule class.
If you are working with Visual C#, navigate to the class declaration. After the class name, type a colon and then the name of the class your rule should inherit from. Then press Shift+Alt+F10. When you are asked if you want to implement the class, press Enter. Stubs for members that are marked abstract in the base class are added to the derived class.
At this point, the code for your class library should resemble the following example.
using Microsoft.SharePoint.Administration.Health; namespace Samples.HealthRules { public class DiskDriveAlmostFull: SPHealthAnalysisRule { public override SPHealthCategory Category { get { throw new System.NotImplementedException(); } } public override SPHealthCheckStatus Check() { throw new System.NotImplementedException(); } public override SPHealthCheckErrorLevel ErrorLevel { get { throw new System.NotImplementedException(); } } public override string Explanation { get { throw new System.NotImplementedException(); } } public override string Remedy { get { throw new System.NotImplementedException(); } } public override string Summary { get { throw new System.NotImplementedException(); } } } }
If you are working with Visual Basic, on the first blank line below the class declaration, type Inherits and the name of the class your rule should inherit from. Then press Enter. Stubs for members that are marked MustOverride in the base class are added to the derived class.
At this point, the code for your class library should resemble the following example.
Imports Microsoft.SharePoint.Administration.Health Public Class DiskDriveAlmostFull Inherits SPHealthAnalysisRule Public Overrides ReadOnly Property Category() As Microsoft.SharePoint.Administration.Health.SPHealthCategory Get End Get End Property Public Overrides Function Check() As Microsoft.SharePoint.Administration.Health.SPHealthCheckStatus End Function Public Overrides ReadOnly Property ErrorLevel() As Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel Get End Get End Property Public Overrides ReadOnly Property Explanation() As String Get End Get End Property Public Overrides ReadOnly Property Remedy() As String Get End Get End Property Public Overrides ReadOnly Property Summary() As String Get End Get End Property End Class
Write code to implement the abstract (or, in Visual Basic, MustOverride) members of the class. For more information, see the documentation for the SPHealthAnalysisRule and SPRepairableHealthAnalysisRule classes.
Override and implement the AutomaticExecutionParameters property.
The following example shows the implementation of this property for a rule that should run hourly on all servers in the farm.
public override SPHealthAnalysisRuleAutomaticExecutionParameters AutomaticExecutionParameters { get { SPHealthAnalysisRuleAutomaticExecutionParameters retval = new SPHealthAnalysisRuleAutomaticExecutionParameters(); retval.Schedule = SPHealthCheckSchedule.Hourly; retval.Scope = SPHealthCheckScope.All; retval.ServiceType = typeof(SPTimerService); return retval; } }
Public Overrides ReadOnly Property AutomaticExecutionParameters() As Microsoft.SharePoint.Administration.Health.SPHealthAnalysisRuleAutomaticExecutionParameters Get Dim retval As SPHealthAnalysisRuleAutomaticExecutionParameters = _ New SPHealthAnalysisRuleAutomaticExecutionParameters() retval.Schedule = SPHealthCheckSchedule.Hourly retval.Scope = SPHealthCheckScope.All retval.ServiceType = Type.GetType("Microsoft.SharePoint.Administration.SPTimerService") Return retval End Get End Property
Compile and test the rule.
For information about preparing the new health rule for installation by a farm administrator, see How to: Create a Feature to Register a Health Rule.
Example
The following example is a health rule that checks every server in the farm once every day to see if disks that have been fixed are running out of free space.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Administration.Health;
namespace Samples.HealthRules
{
public class DiskDriveAlmostFull: SPHealthAnalysisRule
{
private List<DriveInfo> m_FailingDrives = new List<DriveInfo>();
public override string Summary
{
get { return "One or more disk drives are running out of free space."; }
}
public override string Explanation
{
get
{
StringBuilder sb = new StringBuilder();
foreach (DriveInfo drive in this.m_FailingDrives)
{
sb.AppendFormat("{0} ({1}), ",
drive.VolumeLabel, drive.Name);
}
if (sb.Length > 2)
sb.Remove(sb.Length - 2, 2);
return string.Concat(
"The following drives on the failing servers have less than 10GB free: ", sb);
}
}
public override string Remedy
{
get { return "Examine the failing servers and delete old logs or free space on the drives."; }
}
public override SPHealthCategory Category
{
get { return SPHealthCategory.Availability; }
}
public override SPHealthCheckErrorLevel ErrorLevel
{
get { return SPHealthCheckErrorLevel.Error; }
}
public override SPHealthAnalysisRuleAutomaticExecutionParameters AutomaticExecutionParameters
{
get
{
SPHealthAnalysisRuleAutomaticExecutionParameters retval =
new SPHealthAnalysisRuleAutomaticExecutionParameters();
retval.Schedule = SPHealthCheckSchedule.Daily;
retval.Scope = SPHealthCheckScope.All;
retval.ServiceType = typeof(SPTimerService);
return retval;
}
}
public override SPHealthCheckStatus Check()
{
const long bytesInGb = 1024 * 1024 * 1024;
if (!SPFarm.Joined)
throw new InvalidOperationException();
foreach (DriveInfo di in DriveInfo.GetDrives())
{
try
{
if (!(di.IsReady && di.DriveType == DriveType.Fixed))
continue;
if (di.TotalFreeSpace < 10 * bytesInGb)
this.m_FailingDrives.Add(di);
}
catch (IOException)
{
}
}
if (this.m_FailingDrives.Count == 0)
return SPHealthCheckStatus.Passed;
else
return SPHealthCheckStatus.Failed;
}
}
}
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Text
Imports Microsoft.SharePoint.Administration
Imports Microsoft.SharePoint.Administration.Health
Public Class DiskDriveAlmostFull
Inherits SPHealthAnalysisRule
Private m_FailingDrives As List(Of DriveInfo) = New List(Of DriveInfo)
Public Overrides ReadOnly Property Summary() As String
Get
Return "One or more disk drives are running out of free space."
End Get
End Property
Public Overrides ReadOnly Property Explanation() As String
Get
Dim sb As StringBuilder = New StringBuilder()
Dim drive As DriveInfo
For Each drive In Me.m_FailingDrives
sb.AppendFormat("{0} ({1}), ", _
drive.VolumeLabel, drive.Name)
Next
If sb.Length > 2 Then
sb.Remove(sb.Length - 2, 2)
End If
Return String.Concat( _
"The following drives on the failing servers have less than 10GB free: ", sb)
End Get
End Property
Public Overrides ReadOnly Property Remedy() As String
Get
Return "Examine the failing servers and delete old logs or free space on the drives."
End Get
End Property
Public Overrides ReadOnly Property Category() As Microsoft.SharePoint.Administration.Health.SPHealthCategory
Get
Return SPHealthCategory.Availability
End Get
End Property
Public Overrides ReadOnly Property ErrorLevel() As Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel
Get
Return SPHealthCheckErrorLevel.Error
End Get
End Property
Public Overrides ReadOnly Property AutomaticExecutionParameters() As Microsoft.SharePoint.Administration.Health.SPHealthAnalysisRuleAutomaticExecutionParameters
Get
Dim retval As SPHealthAnalysisRuleAutomaticExecutionParameters = _
New SPHealthAnalysisRuleAutomaticExecutionParameters()
retval.Schedule = SPHealthCheckSchedule.Daily
retval.Scope = SPHealthCheckScope.All
retval.ServiceType = Type.GetType("Microsoft.SharePoint.Administration.SPTimerService")
Return retval
End Get
End Property
Public Overrides Function Check() As Microsoft.SharePoint.Administration.Health.SPHealthCheckStatus
Dim bytesInGb As Long = 1024 * 1024 * 1024
If Not SPFarm.Joined Then
Throw New InvalidOperationException()
End If
Dim di As DriveInfo
For Each di In DriveInfo.GetDrives()
Try
If Not (di.IsReady And di.DriveType = DriveType.Fixed) Then
Continue For
End If
If di.TotalFreeSpace < 10 * bytesInGb Then
Me.m_FailingDrives.Add(di)
End If
Catch ex As IOException
End Try
Next
If Me.m_FailingDrives.Count = 0 Then
Return SPHealthCheckStatus.Passed
Else
Return SPHealthCheckStatus.Failed
End If
End Function
End Class
See Also
Tasks
How to: Test a Health Rule During Development