Using PowerShell to Delete a Site with Subsites in SharePoint Server 2010


When using the “DR.DADA” approach to SharePoint development, I often find myself deleting sites (in DEV and TEST environments) and subsequently re-activating features or running some migration utility to recreate the site hierarchy.

In fact, a few years ago this became such a common task on the Agilent Technologies project that I wrote a simple “DeleteWeb” program to overcome the fact that stsadm.exe -o deleteweb doesn’t work on sites that have subsites.

Note that there really wasn’t much to the DeleteWeb program. Almost all of the work was performed by the DeleteHelper class:

using System;
using System.Diagnostics;
using System.Globalization;

using Microsoft.SharePoint;

namespace DeleteWeb
{
    public sealed class DeleteHelper
    {
        private DeleteHelper() { } // all members are static

        public static void DeleteWeb(
            string siteUrl)
        {
            using (SPSite site = new SPSite(siteUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    if (string.Compare(web.Url, siteUrl, true,
                        CultureInfo.InvariantCulture) != 0)
                    {
                        throw new InvalidOperationException(
                            "Invalid Web URL. Verify the URL and try again.");
                    }

                    DeleteWeb(web);
                }
            }
        }

        public static void DeleteWeb(
            SPWeb web)
        {
            SPWebCollection subwebs = web.GetSubwebsForCurrentUser();

            if (subwebs.Count > 0)
            {
                foreach (SPWeb subweb in subwebs)
                {
                    DeleteWeb(subweb);
                    subweb.Dispose();
                }
            }

            Debug.WriteLine("Deleting web: " + web.ServerRelativeUrl);
            web.Delete();
            return;
        }
    }
}

I was hoping that SharePoint Server 2010 would address this scenario out-of-the-box, but that doesn’t appear to be the case.

Suppose that you have a site (e.g. http://foobar/Test) that has subsites (e.g. http://foobar/Test/foo and http://foobar/Test/bar). If you attempt to use the Remove-SPWeb cmdlet in SharePoint Server 2010 to delete the site…

Remove-SPWeb “http://foobar/Test” -Confirm:$false

…then you will encounter an error similar to the following:

Remove-SPWeb : Error deleting Web site “/Test”. You can’t delete a site that has subsites.
At line:1 char:13
+ Remove-SPWeb <<<< “http://foobar/Test” -Confirm:$false
+ CategoryInfo : InvalidData: (Microsoft.Share…CmdletRemoveWeb:SPCmdletRemoveWeb) [Remove-SPWeb], SPException
+ FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletRemoveWeb

In order to delete a site that has subsites using PowerShell, we simply need to convert the C# code shown above into a corresponding PowerShell function, as shown below:

# Completely deletes the specified Web (including all subsites)

function RemoveSPWebRecursively(
    [Microsoft.SharePoint.SPWeb] $web)
{
    Write-Debug "Removing site ($($web.Url))..."
    
    $subwebs = $web.GetSubwebsForCurrentUser()
    
    foreach($subweb in $subwebs)
    {
        RemoveSPWebRecursively($subweb)
        $subweb.Dispose()
    }
    
    $DebugPreference = "SilentlyContinue"
    Remove-SPWeb $web -Confirm:$false
    $DebugPreference = "Continue"
}

$DebugPreference = "SilentlyContinue"
$web = Get-SPWeb "http://foobar/Test"
$DebugPreference = "Continue"

If ($web -ne $null)
{
    RemoveSPWebRecursively $web
    $web.Dispose()
}

Note that the script handles the case where $web is null — in other words, when the specified Web doesn’t exist (for example, when running the script a second time).

Comments (2)

  1. ok says:

    you're awesome.  That was a great script to delete the webs.  

    Greg

  2. Need ur favour says:

    Hi Jameson,

    This is a nice script,However I have a small requirement like,I need the List of MySites which are currently existing and What all users have those MySites and they belong to which OU in AD.

    Could you please post any links you have?