I recently had to use the built-in deleteweb command to delete a web site and was irritated to find that the command wouldn't let me delete the web because it had sub-webs. I simply couldn't live with that as it's extremely frustrating to have to delete all the child webs one at a time. So I created a better deleteweb command, called simply gl-deleteweb2. It behaves exactly like the built-in deleteweb command except that you can pass in a "recurse" switch to have it delete recursively (delete the web and all it's children). What was really nice is that it took me literally 2 minutes to create this command (nice change from some of the more challenging ones I've had lately).
The code is extremely simple:
1: /// <summary>
2: /// Runs the specified command.
3: /// </summary>
4: /// <param name="command">The command.</param>
5: /// <param name="keyValues">The key values.</param>
6: /// <param name="output">The output.</param>
7: /// <returns></returns>
8: public override int Run(string command, StringDictionary keyValues, out string output)
9: {
10: output = string.Empty;
11:
12: InitParameters(keyValues);
13:
14: string url = Params["url"].Value.TrimEnd('/');
15:
16: using (SPSite site = new SPSite(url))
17: using (SPWeb web = site.OpenWeb())
18: {
19: if (web.IsRootWeb)
20: {
21: throw new SPException(SPResource.GetString("CannotDelRootwebByDelweb", new object[0]));
22: }
23:
24: if (web.Webs.Count > 0 && !Params["recurse"].UserTypedIn)
25: {
26: throw new SPException(
27: string.Format(
28: "Error deleting Web site \"{0}\". You can't delete a site that has subsites unless you pass the \"recurse\" flag into the command.",
29: web.ServerRelativeUrl));
30: }
31:
32: if (web.Webs.Count > 0 && Params["recurse"].UserTypedIn)
33: DeleteSubWebs(web.Webs);
34:
35: web.Delete();
36:
37: }
38:
39: return 1;
40: }
41:
42: #endregion
43:
44: /// <summary>
45: /// Deletes the sub webs.
46: /// </summary>
47: /// <param name="webs">The webs.</param>
48: private static void DeleteSubWebs(SPWebCollection webs)
49: {
50: foreach (SPWeb web in webs)
51: {
52: if (web.Webs.Count > 0)
53: DeleteSubWebs(web.Webs);
54:
55: web.Delete();
56: }
57: }
Use this command just like deleteweb but pass in "-recurse" if you want to delete a web with sub-webs (this keeps the action explicit so the user understands that it will delete all sub-webs). The syntax of the command can be seen below:
C:\>stsadm -help gl-deleteweb2
stsadm -o gl-deleteweb2
Deletes a web.
Parameters:
-url <url of web to delete>
[-recurse (delete all sub-sites)]
Here’s an example of how to delete a web recursively:
stsadm –o gl-deleteweb2 -url "http://intranet/WebWithChildren" -recurse



12 comments:
im used this command line delete subsite, but can't. that error showed "Cannot complete this action. Please try it again." How i can delete this subsite site?
Unfortunately I can't help you with this one. I've seen this error a few times though never when trying to delete a web. I've searched in vain to find something about this error but the error occurs within an unmanaged assembly so I can't see what would typically cause this error in code. You may want to try deleting all the sub-sites manually or deleting from the browser (that will at least tell you which site is specifically having issues). Beyond that you're best bet will be to contact Microsoft.
Thank,
is a good idea
Gary,
just used your extensions to delete a web with many many subsites (30+) - worked like a charm. Thank you for providing this valuable tool. It saved me a LOT of time....
:P
Dre
Hi, will this also work with WSS 2.0? Hope I don't sound too nooby, hehe.
Unfortunately no - all these commands are specific to WSS v3/MOSS 2007. However, some of the APIs are the or at least real close with WSS2 so it might be possible to refactor some of the code to work with v2 but you'd be on your own with that one :)
Hi,
Great work you've got here.
In this particular command (gl-deleteweb2) there is a memory leak in the DeleteSubWebs method. You're not disposing the deleted SPWeb object.
This is my rewrite of your method to dispose the deleted web.
private static void DeleteSubWebs(SPWebCollection webs)
{
int webCount = webs.Count;
for (int i = webCount - 1; i >= 0; i--)
{
using (SPWeb web = webs[i])
{
if (web.Webs.Count > 0)
DeleteSubWebs(web.Webs);
web.Delete();
}
}
}
Thanks for the feedback. I have a fix for that which will go out later today.
Where to paste the .cs code and compile? How can I change the stsadm.exe file?
Venkatx5 - download the WSP (from the downloads page) and deploy using the instructions provided on that page - there's no need to do anything with the source (I just provide that for reference).
Hi
Thanks for this tool, I'm sure it works but not for me.
I get the following:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>stsa
dm -o gl-deleteweb2 -url http://dslwnsharepoint/sysmgmt/css/mch/ -recurse
Error deleting Web site "/sysmgmt/css/mch/opp2". You can't delete a site that has subsites.
so same as before I loaded the command
Any suggestions
My code basically just does a recursive delete starting at the leaf webs and working it's way up the chain. If it isn't deleting a child then most likely you don't have access to the child or it's been orphaned so the Webs collection isn't getting populated correctly. Make sure you are the site collection admin and if so try running the databaserepair command.
Post a Comment