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