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

  1. Open Visual Studio as an administrator by right-clicking the program in the Start menu and selecting Run as administrator.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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
    
  7. 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
      
  8. 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.

  9. 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
    
  10. 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

How to: Create a Feature to Register a Health Rule

How to: Deploy a Health Rule with a Solution Package