Slinger's Thoughts

April 14, 2008

What features are installed in your farm?

Filed under: SharePoint — slingeronline @ 9:02 am

Well, we’ve reached a landmark at my blog.  Over 5,000 views.  Just seeing that a few people are reading makes it worth it for me.  Thanks.  Now, on to the meat of the matter. 

If you have ever attempted to deploy content from a development farm to a production farm, you have probably run into this issue.  Any time that you deploy content, you need to have the same features installed and enabled in your production farm as your development farm.  The problem is, in most cases, your development farm has had features installed, tested and disabled, or uninstalled, that you likely won’t have in your production farm.  After you check to make sure that everything is the same in all of your site settings, and you try to deploy the job, it still fails.

The problem is, that a feature in your development farm may have been uninstalled without being deactivated first.  This leaves a reference that SharePoint looks for in your production farm that simply isn’t there.  When you check the error messages, it will tell you which feature it it looking for, but according to the GUID “{001f4bd7-746d-403b-aa09-a6cc43de7942}” , not by any common sense Human language reference.  That helps, but when you go into your features folder in your 12 hive, you will notice that there are hundreds of features, some that are crucial to the operation of SharePoint, and some that are the options that you install.  You could go into each folder and check the Manifest.xml for each one looking for that elusive GUID, but that would take a while, and likely not be very productive.  A better solution would be to have a list that shows you exactly what features are installed, in each farm, and be able to find that problematic GUID reference that way.  A few people have run into the same issues, and have created solutions to it.  When I first started looking I happened upon Soeren Nielsen’s blog.  He had run into the exact same problem.  No discredit to him, I couldn’t get his solution to work (as you could probably tell by my comments).  I went cruising around some more, and found this site, which had a prepackaged solution, although it was a little hard for me to locate it at first. (I wasn’t looking very hard.)  But just in case, I will also post the code for you.  This solution creates a new item under the “Global Configuration” heading on your farm’s Central Administration Operations page, labelled “Installed Features in Server Farm.”  Which, when you click on it, lists every feature installed anywhere in your farm, and the GUID for that feature, as well as a brief description of the feature if one was included in the Manifest.xml file for that feature.  Keep in mind that this includes all of the core features of SharePoint, as well as the optional features that you may have installed. Here is an example from our company’s production farm.

FBAConfigurationManagement  (c990a4c5-c5d9-474b-b6f6-67329f1e6a0d)
Activating this feature will allow an administrator to manage the Membership providers and Role managers in a selected Web Application.

This was an optional feature I installed.

SharedServices  (f324259d-393d-4305-aa48-36e8d9a7a0d6)
Shared Services Infrastructure

If you uninstall this feature, you’re going to be pulling your hair out trying to get it fixed.

As you can see, most of the features are labelled, and they list that problematic GUID for you so a simple “CTRL-F” on the page can find the culprit feature or features so that you can either correct them on the development farm, or deploy them to the production farm, depending on what your needs are.  To fix them on the development farm, you will have to re-install the feature, then deactivate it, then uninstall it.  Now, on to the code.

As usual, you will need the standard files for any feature.  Open up whatever code editor you want use, (notepad still works fine for this) and create the following file named “Feature.xml”

<Feature
        Id=”{5006631B-BB77-48aa-80F6-A7CB58B22E83}”
        Title=”Server Farm Features Reporter”
        Description=”Gives an overview of the features installed in the server farm”
        Scope=”Web”
        DefaultResourceFile=”core”
        xmlns=”http://schemas.microsoft.com/sharepoint/“>
  <ElementManifests>
    <ElementManifest Location=”featurereporter.xml”></ElementManifest>
  </ElementManifests>
</Feature>

Oh would you looky there! There’s one of those annoying GUIDs again.  Okay, enough of that.  We will also need that Manifest file.  We’re going to name ours “featuresreporter.xml”, just like the guys at U2U.info did. (They deserve all the credit here, I’m not smart enough to write this much code.)

<Elements xmlns=”http://schemas.microsoft.com/sharepoint/“>
 <CustomAction
   Id=”ServerFarmFeatures”
   GroupId=”GlobalConfiguration”
            Location=”Microsoft.SharePoint.Administration.Operations”
   Sequence=”70″
   Title=”Installed Features in Server Farm”>
  <UrlAction
            Url=”featurereporter.aspx” />
 </CustomAction>
 <Module Name=”FeatureReporter” Url=”” Path=”” >
  <File Url=”featurereporter.aspx” />
 </Module>
</Elements>

And you’ll notice that the Manifest file points to an *.aspx page.  So we will need to create that too.

<%@ Page language=”C#” MasterPageFile=”~masterurl/default.master” Inherits=”Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c” %>
<%@ Register Tagprefix=”SharePoint” Namespace=”Microsoft.SharePoint.WebControls” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register Tagprefix=”Utilities” Namespace=”Microsoft.SharePoint.Utilities” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Import Namespace=”Microsoft.SharePoint” %>
<%@ Import Namespace=”Microsoft.SharePoint.Administration” %>
<%@ Import Namespace=”System.Text” %>

<asp:Content ID=”Content1″ ContentPlaceHolderId=”PlaceHolderPageTitle” runat=”server”></asp:Content>
<asp:Content ID=”Content2″ ContentPlaceHolderId=”PlaceHolderAdditionalPageHead” runat=”server”></asp:Content>
<asp:Content ID=”Content3″ ContentPlaceHolderId=”PlaceHolderPageImage” runat=”server”></asp:Content>

<asp:Content ID=”Content4″ ContentPlaceHolderId=”PlaceHolderPageTitleInTitleArea” runat=”server”>Features installed in server farm</asp:Content>
<asp:Content ID=”Content5″ ContentPlaceHolderId=”PlaceHolderPageDescription” runat=”server”></asp:Content>

<asp:Content ID=”Content6″ ContentPlaceHolderId=”PlaceHolderMain” runat=”server”>

    <asp:Label ID=”Label1″ runat=”server” Text=”Label”></asp:Label>
   
<script language=”C#” runat=”server”>
protected override void OnLoad(EventArgs e)
{
   if (!this.IsPostBack)
  {
     // Get the announcements list
     SPWeb web = SPContext.GetContext(this.Context).Web;

     StringBuilder sb = new StringBuilder();

     sb.Append(GetHeader(“Farm”));
     sb.Append(“<TABLE cellpadding=’2′ cellspacing=’2′ width=’100%’>”);      
     foreach (SPFeatureDefinition feature in SPFarm.Local.FeatureDefinitions)
     {
         if (feature.Scope == SPFeatureScope.Farm)
         {
             sb.Append(GetRow(feature));
         }
     }
     sb.Append(“</TABLE>”);

     sb.Append(GetHeader(“IIS Web Application”));
     sb.Append(“<TABLE cellpadding=’2′ cellspacing=’2′ width=’100%’>”);    
     foreach (SPFeatureDefinition feature in SPFarm.Local.FeatureDefinitions)
     {
         if (feature.Scope == SPFeatureScope.WebApplication)
         {
             sb.Append(GetRow(feature));
         }
     }
     sb.Append(“</TABLE>”);

     sb.Append(GetHeader(“Site Collection”));
     sb.Append(“<TABLE cellpadding=’2′ cellspacing=’2′ width=’100%’>”);
     foreach (SPFeatureDefinition feature in SPFarm.Local.FeatureDefinitions)
     {
         if (feature.Scope == SPFeatureScope.Site)
         {
             sb.Append(GetRow(feature));
         }
     }
     sb.Append(“</TABLE>”);

     sb.Append(GetHeader(“Site”));
     sb.Append(“<TABLE cellpadding=’2′ cellspacing=’2′ width=’100%’>”);
     foreach (SPFeatureDefinition feature in SPFarm.Local.FeatureDefinitions)
     {
         if (feature.Scope == SPFeatureScope.Web)
         {
             sb.Append(GetRow(feature));
         }
     }
     sb.Append(“</TABLE>”);       
             
     Label1.Text = sb.ToString() ;
   }
   base.OnLoad(e);
}

    protected string GetHeader(string scope)
    {
        StringBuilder sb = new StringBuilder();
        
        sb.Append(“<TABLE cellpadding=’2′ cellspacing=’2′ width=’100%’ class=’ms-toolbar’>”);
        sb.Append(“<TR><TD class=’ms-toolbar’ nowrap=’true’>”);
        sb.Append(“<TABLE cellpadding=’1′ cellspacing=’0′ border=’0′><TR>”);
        sb.Append(“<TD class=’ms-toolbar’ nowrap style=’padding: 2px’>”);
        sb.Append(“Features scoped at the level of the ” + scope
                 + “</TD></TR></TABLE></TD></TR></TABLE>”);

        return sb.ToString();
    }
   
    protected string GetRow(SPFeatureDefinition feature)
    {
        StringBuilder sb = new StringBuilder();

        sb.Append(“<TR><TD class=’ms-vb2′ style=’font-weight: bold;’>”);
        sb.Append(“<B>” + feature.DisplayName + “</B>  (” +  feature.Id + “)</TD></TR>”);
        sb.Append(“<TR><TD class=’ms-vb2′><I>” + feature.GetDescription(new System.Globalization.CultureInfo(“en-us”)) + “</I></TD>”);
        sb.Append(“<TR><TD class=’ms-vb2′><UL>”);
        foreach (SPFeatureDependency dep in feature.ActivationDependencies)
        {
            SPFeatureDefinition depFet = GetFeature(dep.FeatureId);
            sb.Append(“<LI>” + depFet.DisplayName + ” (” + depFet.Id + “)</LI>”);
        }
        sb.Append(“</UL></TD>”);
        sb.Append(“</TR>”);
 
        return sb.ToString(); 
    }
   
    protected SPFeatureDefinition GetFeature(Guid guid)
    {
        SPFeatureDefinition retval = null;
        foreach (SPFeatureDefinition feature in SPFarm.Local.FeatureDefinitions)
        {
            if (feature.Id == guid)
            {
                retval = feature;
                break;
            }
        }
        return retval;
    }   
</script>
</asp:Content>

Once you have all these files created you can save them all to a folder in your under …12/Templates/Features, and then install your feature.  When you navigate to your operations page, there is that link, and you should be all set.  (When you install the feature it will place the featurereporter.aspx file where it belongs, you don’t need to move it.)  Obviously the easiest thing would be to just install the solution from u2u.info.  And they have also included an installer script to install the feature, but you will need to edit this for your particular needs, it likely won’t work right out of the gate. Once you have it all set up, click on the new link created, and you should be presented with a list of every single feature installed in your farm, and where it is installed, whether it be at the Farm level, scoped to an IIS Web application, at Site Collections, or at Sites.  From here you can find a troublesome feature, and fix the problem so that your content deployment jobs don’t give you error messages when you try to run them.  I’m sure you can find other uses for this feature also.

 

4 Comments »

  1. Hi Slinger

    I’ve updated my post, so you should be able to download the aspx file without being hit by wordpress’ crappy formatting.

    I’ve also used (and still do) a slightly modified version (improved!) of the feature you’ve found here.
    It’s great, it works.

    However it only fixes the problem where you have features that have been deleted, removed, renamed faulty from the farm (e.g. just delete a feature.xml to see how it works). It will allow you to figure out what features that haven’t been properly uninstalled and do so.

    But it will not catch the problem where one of those features have been activated at some subsite in the farm. Even if you uninstall it at the top there will still be remnants that you have to remove at the subsite level, hence my additional feature.

    As i said I use both and I can recommend you do too.

    Comment by Søren Nielsen — April 15, 2008 @ 2:47 pm

  2. GREAT post, I uploaded the files to my server for others to download (i had issues with the wordpress formatting). Also provided a little detail on how to install the feature so other noobs don’t have to search the interwebs for instructions.

    files:
    http://www.1am2.com/files/1/SharePoint/FeaturesReporter/featurereporter.aspx
    http://www.1am2.com/files/1/SharePoint/FeaturesReporter/Feature.xml
    http://www.1am2.com/files/1/SharePoint/FeaturesReporter/featuresreporter.xml

    Install Process:

    stsadm access:
    cd C:\Program Files\Common Files\Microsoft Shared\web server extensions\12

    command to install the feature:
    stsadm -o installfeature -n featuresreporter

    then go into Central Administration to activate the feature.
    Central Administration > Site Settings > Site Features

    You should then see the new feature installed under Global Configuration
    Installed Features in Server Farm

    Comment by ehaze — November 13, 2008 @ 12:00 pm

  3. Thank you,
    very useful, you made me save me a lot of time.

    Works perfectly well with SharePoint 2010.

    Marc

    Comment by Marc Charmois — June 10, 2010 @ 11:22 pm

  4. WARNING – the file featurereporter.aspx in the comment (2) above contains links to malicious sites. Do not download it, but create the files manually and copy-paste the code from the original article instead.

    Comment by Mike — August 14, 2011 @ 9:55 am


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.