I mentioned in my previous post that I was doing a presentation at the local SharePoint user group meeting and wanted to create a simple command to demonstrate what is involved with creating custom stsadm extensions. The first command I created (gl-backupsites) turned out to be too complex for demonstration purposes so I took another approach and decided to show how to simply wrap an existing command in order to extend it. What I chose to do was to wrap the existing out-of-the-box backup command and simply add an -includeiis parameter. I called my new command gl-backup.

The code is pretty simple. I basically just reproducing the parameters from the built-in command which I just grabbed with the help of Reflector. I then just loop through the parameters in order to build the call to the built-in command. Once the built-in command is finished running I grab the generated XML index file and locate the folder in which the backup was stored. I then use this folder to store the IIS settings:

  1 public class Backup2 : SPOperation
  2 {
  3     private const int FLAG_EXPORT_INHERITED_SETTINGS = 1;
  4  
  5     /// <summary>
  6     /// Initializes a new instance of the <see cref="BackupSites"/> class.
  7     /// </summary>
  8     public Backup2()
  9     {
 10         SPParamCollection parameters = new SPParamCollection();
 11  
 12         parameters.Add(new SPParam("directory", "dir", false, null, null));
 13         parameters.Add(new SPParam("backupmethod", "method", false, "None", null));
 14         parameters.Add(new SPParam("item", "item", false, null, null));
 15         parameters.Add(new SPParam("quiet", "quiet", false, null, null));
 16         parameters.Add(new SPParam("percentage", "update", false, null, new SPIntRangeValidator(1, 100)));
 17         parameters.Add(new SPParam("backupthreads", "threads", false, null, new SPIntRangeValidator(1, 10)));
 18         parameters.Add(new SPParam("showtree", "tree", false, "False", null));
 19         parameters.Add(new SPParam("url", "url", false, null, null));
 20         parameters.Add(new SPParam("filename", "f", false, null, new SPValidator()));
 21         parameters.Add(new SPParam("overwrite", "overwrite"));
 22         parameters.Add(new SPParam("includeiis", "iis"));
 23  
 24         StringBuilder sb = new StringBuilder();
 25         sb.Append("For site collection backup:");
 26         sb.Append("\r\n    stsadm.exe -o backup ");
 27         sb.Append("\r\n        -url <url>");
 28         sb.Append("\r\n        -filename <filename>");
 29         sb.Append("\r\n        [-overwrite]");
 30         sb.Append("\r\n\r\nFor catastrophic backup:");
 31         sb.Append("\r\n    stsadm.exe -o backup");
 32         sb.Append("\r\n        -directory <UNC path>");
 33         sb.Append("\r\n        -backupmethod <full | differential>");
 34         sb.Append("\r\n        [-item <created path from tree>]");
 35         sb.Append("\r\n        [-percentage <integer between 1 and 100>]");
 36         sb.Append("\r\n        [-backupthreads <integer between 1 and 10>]");
 37         sb.Append("\r\n        [-showtree]");
 38         sb.Append("\r\n        [-quiet]");
 39         sb.Append("\r\n        [-includeiis]");
 40  
 41         Init(parameters, sb.ToString());
 42     }
 43  
 44     #region ISPStsadmCommand Members
 45  
 46     /// <summary>
 47     /// Gets the help message.
 48     /// </summary>
 49     /// <param name="command">The command.</param>
 50     /// <returns></returns>
 51     public override string GetHelpMessage(string command)
 52     {
 53         return HelpMessage;
 54     }
 55  
 56     /// <summary>
 57     /// Runs the specified command.
 58     /// </summary>
 59     /// <param name="command">The command.</param>
 60     /// <param name="keyValues">The key values.</param>
 61     /// <param name="output">The output.</param>
 62     /// <returns></returns>
 63     public override int Run(string command, StringDictionary keyValues, out string output)
 64     {
 65         output = string.Empty;
 66  
 67         InitParameters(keyValues);
 68  
 69         string args = "-o backup";
 70         foreach (string key in keyValues.Keys)
 71         {
 72             if (key.ToLowerInvariant() == "includeiis" || key.ToLowerInvariant() == "o")
 73                 continue;
 74  
 75             args += string.Format(" -{0} \"{1}\"", key, keyValues[key]);
 76         }
 77  
 78         if (Utilities.RunStsAdmOperation(args, false) != 0)
 79             return 0;
 80  
 81  
 82         if (Params["includeiis"].UserTypedIn && Params["directory"].UserTypedIn)
 83         {
 84             bool verbose = !Params["quiet"].UserTypedIn;
 85             XmlDocument xmlToc = new XmlDocument();
 86             xmlToc.Load(Path.Combine(Params["directory"].Value, "spbrtoc.xml"));
 87             string iisBakPath = Path.Combine(xmlToc.DocumentElement.FirstChild.SelectSingleNode("SPBackupDirectory").InnerText, "iis.bak");
 88             using (DirectoryEntry de = new DirectoryEntry("IIS://localhost"))
 89             {
 90                 if (verbose)
 91                     Console.WriteLine("Flushing IIS metadata to disk....");
 92                 de.Invoke("SaveData", new object[0]);
 93                 if (verbose)
 94                     Console.WriteLine("IIS metadata successfully flushed to disk.");
 95             }
 96             using (DirectoryEntry de = new DirectoryEntry("IIS://localhost"))
 97             {
 98                 if (verbose)
 99                     Console.WriteLine("Exporting full IIS settings to {0}....", iisBakPath);
100                 string decryptionPwd = string.Empty;
101                 de.Invoke("Export", new object[] { decryptionPwd, iisBakPath, "/lm", FLAG_EXPORT_INHERITED_SETTINGS });
102             }
103         }
104  
105         return 1;
106     }
107  
108     #endregion
109  
110 }

The syntax of the command can be seen below:

C:\>stsadm -help gl-backup

stsadm -o gl-backup
For site collection backup:
    stsadm.exe -o gl-backup
        -url <url>
        -filename <filename>
        [-overwrite]

For catastrophic backup:
    stsadm.exe -o gl-backup
        -directory <UNC path>
        -backupmethod <full | differential>
        [-item <created path from tree>]
        [-percentage <integer between 1 and 100>]
        [-backupthreads <integer between 1 and 10>]
        [-showtree]
        [-quiet]
        [-includeiis]

Here’s an example of how to backup a farm and include the IIS settings:

stsadm -o gl-backup -directory c:\backups -backupmethod full -includeiis