Delete All Users from a Site Collection

Posted on Posted in SharePoint 2007, STSADM Commands

I was chatting with my buddy and fellow MVP, Todd Klindt, the other day and he was asking if I had a custom command that would allow him to quickly delete all the users added to a site collection.  For his purposes he needed this to troubleshoot an issue he was having with a site collection that contained many thousands of users.

I figured this would be pretty easy to do – a simple while loop with a conditional check for site administrators to prevent them from being deleted so I quickly typed out the following code during our IM conversation:

using (SPSite site = new SPSite(url))
using (SPWeb web = site.OpenWeb())
{
    int offsetIndex = 0;
    while (web.SiteUsers.Count > offsetIndex)
    {
 
        if (web.SiteUsers[offsetIndex].IsSiteAdmin || web.SiteUsers[offsetIndex].ID == web.CurrentUser.ID)
        {
            offsetIndex++;
            continue;
        }
        web.SiteUsers.Remove(offsetIndex);
    }
}

We can’t use a for loop for this because we’re modifying the collection and that would result in an error so we need to use a while loop and just keep deleting until there’s no more to delete.  But, we have to watch out for site administrators as we can’t directly delete them in this fashion (and it’s a good idea to keep them regardless) so we use an offset that gets incremented whenever we hit an administrator.  We also can’t delete the current user so I check for that as well.

One thing to note is that if you have a lot of users (Todd was dealing with 17,000) then it will run real slow – he was seeing about 300 deleted per hour with progressively more as the size dwindled – so be patient 🙂

I figured since I had the code that I might as well turn it into a new stsadm command so I created gl-deleteallusers.  There’s not really much to this command – it just takes in a single URL parameter which points to your site collection.  I thought about adjusting this so that you could delete users from a specific web that had broken inheritance but I didn’t really have time.  Here’s the help output:

C:\>stsadm -help gl-deleteallusers

stsadm -o gl-deleteallusers


Deletes all site collection users.  Will not delete site administrators.

Parameters:
        -url <site collection url>

The following tables summarizes the command and its parameters:

Command Name Availability Build Date
gl-deleteallusers WSS v3, MOSS 2007 7/23/2008
Parameter Name Short Form Required Description Example Usage
url   Yes The URL of the site collection of which the users will be deleted.  If a sub-site of the site collection is passed in it will only look at the site collection itself and ignore the sub-site information. -url http://portal/

Using the command is real simple – the following will delete all users, except site administrators, from the http://portal/sites/site1 site collection:

stsadm -o gl-deleteallusers -url http://portal/sites/site1

23 thoughts on “Delete All Users from a Site Collection

  1. Hi Gary, these commands are absolutely the best! Is it possible to delete all groups in a site collection?
    We are using the “gl-convertsubsitetositecollection” command for a largish deployment. Our issue is that the converted sites bring in over 200 groups from the previous top level site.

  2. I currently don’t have anything for the groups but you could easily delete them all with a simple powershell script that basically does what my code is doing for users but for groups instead.

  3. If you have MOSS download the MOSS version otherwise download the WSS version (the WSP files). Then use stsadm’s addsolution and deploysolution commands to deploy the WSP to your farm. The commands will then be available.

  4. Please Ignore my last post(!) after deploysolusion – it was there (told you I new here.. 🙂 )

    Thank you so much!!!
    (Did some one said a life saver? that was true…)

  5. Gary,
    I am a huge fan, like everyone else that posts here. One of my pet peeves is how many (17k doesn’t really surprise me) of these users turn into dead wood in a normal-sized org. So, I humbly submit a small code project I undertook that extends your code here with a lookup into an AD to find objects that have been removed/disabled in AD. Take a look and use it if it looks interesting.

    namespace WindowsApplication1
    {

    public partial class Form1 : Form
    {
    public ArrayList arrHold;

    public Form1()
    {
    InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)
    {
    lbUsers.Items.Clear();
    using (SPSite site = new SPSite(txtSCURL.Text))
    using (SPWeb web = site.OpenWeb()){
    int offsetIndex = 0;
    while (web.SiteUsers.Count > offsetIndex) {
    if (web.SiteUsers[offsetIndex].IsSiteAdmin || web.SiteUsers[offsetIndex].ID == web.CurrentUser.ID){
    offsetIndex++;
    continue; }

    string ThisUser = web.SiteUsers[offsetIndex].ToString();
    if (ThisUser.StartsWith(“DOMAIN\\”)){
    ThisUser = ThisUser.Substring(nn);
    if (arrValidUser(ThisUser)==null)
    lbUsers.Items.Add (web.SiteUsers[offsetIndex]);
    }
    offsetIndex++;
    }
    }
    if (lbUsers.Items.Count < 1)
    lbUsers.Items.Add(“–All Users are Valid!–“);
    }

    private string arrValidUser(string TheUser)
    {
    DirectoryEntry de = null;
    DirectorySearcher ds = null;
    SearchResult result = null;
    //SearchResultCollection results = null;
    string userInfo = String.Empty;
    using (de = new DirectoryEntry(
    “LDAP://dc=root,dc=domain,dc=foo”,
    null,
    null,
    AuthenticationTypes.Secure))
    {

    using (ds = new DirectorySearcher(de))
    {
    try
    {
    //ds.Filter = “(objectCategory=person)”;
    ds.PropertiesToLoad.Add(“samAccountName”);
    ds.Filter =”(SamAccountName=”+TheUser+”)”;
    result = ds.FindOne();
    if (null != result)
    return “DOMAIN\\” + result.Properties[“samAccountName”][0].ToString();
    else
    return null;
    }

    catch (Exception ex)
    {
    // log exception to the application event log
    string sEvent = ex.Message;

    }
    return null;
    }
    }

    }

    private void button2_Click(object sender, EventArgs e)
    {
    using (SPSite site = new SPSite(txtSCURL.Text))
    using (SPWeb web = site.OpenWeb()){
    int offsetIndex = 0;

    while (web.SiteUsers.Count > offsetIndex) {
    // don’t get to whack yourself! or an admin!
    if (web.SiteUsers[offsetIndex].IsSiteAdmin || web.SiteUsers[offsetIndex].ID == web.CurrentUser.ID){
    offsetIndex++;
    continue; }

    string ThisUser = web.SiteUsers[offsetIndex].ToString();
    if (ThisUser.StartsWith(“DOMAIN\\”)){
    ThisUser = ThisUser.Substring(nn);
    if (arrValidUser(ThisUser) == null)
    {
    //MessageBox.Show(“removing ” + ThisUser);
    web.SiteUsers.Remove(offsetIndex);
    offsetIndex–;
    }
    }
    offsetIndex++;
    }
    lbUsers.Items.Clear();
    }
    }
    }
    }

    1. Hi AlexMondale and all,
      can You please give some advice on how to use this script (I am a total novice on windows scripting). It would be very appreciated since this problem of dead accounts in Sharepoint sites is something very annoying for users.
      Ciao
      Guido

  6. Has anyone tried the UserGroup.RemoveUserCollectionFromSite() web service method? Might it perform faster? 300 users per hr is too slow for our need…

  7. We have the need to delete all user profiles from a well intended, but overwhelming AD setting in our Shared Services Administration. All users in the AD were imported…. Is there a process that can take care of this? I don’t want to delete the users from a site, but remove the imported profiles from our AD.

    Thanks

  8. Adjust your import settings to remove the unnecessary accounts and then run a full import 3 times – that “should” automatically delete the missing profiles (I’ve seen cases where it didn’t in which case we just manually deleted them via central admin by selecting the missing from import view).

  9. First off: Thanks Gary; your commands have helped us a ton.
    Second: in reply to an anonymous post about deleting all groups in a site collection, this is the PowerShell command I used:
    ([xml](stsadm -o enumgroups -url http://siteurl/)).Groups.Group | foreach {stsadm -o deletegroup -url http://siteurl/ -name $_.Name }.

    Not sure if it’s the best way, but it’s been working for me.

  10. First off I want to say Thanks to everyone on this thread. This is great stuff. I am currently trying to take AlexMondale code and scope it to the web application level. Has anyone done this already?
    I am trying to accomplish
    Goal:
    The removal of deleted AD accounts from SharePoint entirely.

    Our SharePoint Portal Contains a lot of site collections so I don’t want to go through each one.

  11. Alex,
    I am trying to run this code . I am getting bunch of error
    The name lbluser does not exist
    The type or namsespace SpSite could not be found and so on other couple.
    Can you please guide me

    Thanks

  12. Gary-
    This is an awesome post and thanks for that command. I wanted to run this by you and see your thoughts.

    Although I can see using the command you posted in the future, The assistance I need now is more torwards Duplicate AD Accounts in our Site Collection.

    Background: I’ve recently Migrated our 2007 farm to sharepoint 2010. 2007 was form based authentication and 2010 we’ve adjusted that to claims based authentication obviously using Kerberos. The problem I’m running into now and that we now see duplicate accounts in our 2010 enviroment one with the Moss 2010 Garbage AD ID and the other is showing the legacy Migrated Domain\username. We have several thousand accounts showing dup accounts and we are loking for ways to remove the legacy accounts.

    Thoughts?

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA

*