January 21, 2021
Hot Topics:

Extend Your SharePoint Control with Custom Stsadm Commands

  • By Gustavo Velez
  • Send Email »
  • More Articles »

Programming New Commands

To generate new operations you need Visual Studio (2005 or 2008) and one of its default program languages (C# or VB). Launch Visual Studio and create a new project of the type "Class Library", giving it a unique name (ToolsSpsadm in the following example). The class should inherit from the ISPStsadmCommand Interface and must have at least two methods: GetHelpMessage and Run:

using System; 
using System.Collections.Specialized; 
using System.Text; 
using Microsoft.SharePoint; 
using Microsoft.SharePoint.StsAdmin;   
namespace ToolsSpsadm 
   public class ClassToolssSpsadm : ISPStsadmCommand  
      public string GetHelpMessage(string command) {}
      public int Run(string command, 
         StringDictionary keyValues, out string output) {}

The GetHelpMessage method runs with the stsadm help function and displays messages indicating its syntax and operation parameters. The example uses only one parameter (URL) to configure the URL of a site. The method looks like this:

public string GetHelpMessage(string command)
   return "-url <URL complete in Site and SharePoint>";

For example, to get help on the EnumerateFeatures command, you would use the command stsadm -help –EnumerateFeatures. That executes the GetHelpMessage method and the help message appears.

The Run method contains the source code to execute the operations. A switch statement selects one of the commands, if there is more than one in the class:

public int Run(string command, StringDictionary keyValues, 
   out string output)
   command = command.ToLowerInvariant();
   switch (command)
      case "enumeratefeatures":  
         //Attention: all in lower case to prevent the error: 
         // 'Operation not valid because of the actual 
         // state of the object')
         return this.EnumerateFeatures(keyValues, out output); 
      case "eliminatewebrecursively ": 
         return this.EliminateWebRecursively(keyValues, out output); 
         throw new InvalidOperationException(); 

The example class exposes two commands: EnumerateFeatures and EliminateWebRecursively. The command parameter contains the name of the operation to be executed and the switch statement selects the matching method. Note that all strings are converted to lower case to prevent the error "Operation not valid because of the actual state of the object" that occurs if the case statement has any uppercase letters.

The first method, EnumerateFeatures, does just that: Given the URL of a site, it returns the installed and activated Features in that site:

private int EnumerateFeatures(
   StringDictionary keyValues, out string output)
   if (!keyValues.ContainsKey("url"))
      throw new InvalidOperationException(
         "The URL parameter was not specified"); 
   String myUrl = keyValues["url"];
   SPFeatureCollection AllFeatures = null;
   SPSite mySite = null;
   SPWeb myWeb = null;
   StringBuilder myOutput = new StringBuilder();
      mySite = new SPSite(myUrl);
      myWeb = mySite.OpenWeb();
      AllFeatures = myWeb.Features;
      myOutput.AppendLine("Features in '" + miWeb.Url + "':\n");  
      foreach (SPFeature oneFeature in AllFeatures)
         myOutput.AppendLine(oneFeature.Definition.DisplayName + 
            "\t\t(" + oneFeature.DefinitionId + ")");
   catch (Exception ex)
      throw new InvalidOperationException(
         "Error searching the URL '" + myUrl + 
         "'. Check the URL format and ensure that the Site exists." + 
         "Details: " + ex.Message);
      if (mySite != null) mySite.Dispose();
      if (myWeb != null) myWeb.Dispose();
      myOutput.AppendLine("EnumerateFeatures finished");
   output = myOutput.ToString();
   return 0;

The StringDictionary parameter contains pairs consisting of operation names and their values. The output parameter is a string that, at the end of the method, contains all the return data. The first lines check that the url parameter has been passed; otherwise, the method returns an error message and aborts the operation. Next, the code creates SharePoint objects to contain the Site, Web, and the Features Collection in that Web, and then instantiates them. Finally, it creates a StringBuilder to collect the output. After instantiating the SharePoint objects, it loops through the Features, appending information to the StringBuilder. If an error occurs, the method generates a general exception that indicates the type of problem. Finally, when the process completes, it disposes of the created SharePoint objects, and assigns the contents of the StringBuilder to the output string.

Page 2 of 3

This article was originally published on June 18, 2009

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date