This post was published to Jimmie's Sharings at 9:42:27 AM 4/5/2008
Deleting User Profiles
The out-of-the-box UI provides a means to manually remove user profiles. Navigate to SSP Admin > User Profile and Properties > View User Profiles. Search for the user’s profile, and then click the “Delete” context menu item or the Delete toolbar button..

This is fine for an occasional profile deletion; but what if you need to delete thousands of profiles? We recently ran into this situation. A large customer had a separate Active Directory (AD) forest, referred to as the staging forest, for development and integration testing. This separate AD forest kept development and testing activities from impacting the live AD infrastructure. Needless to say, the domain names in the staging AD environment were different live AD names. Before moving the application to production, the customer wanted to do a full profile import from the production AD domain controllers to test the import duration, and the load on the domain controllers.
To establish a good baseline, we needed to remove the existing user profiles from the SSP database so their presence wouldn’t distort the import. Manually deleting thousands of user profiles was unrealistic. We could delete and recreate the SSP, but this also involves a lot of manual effort. So we took the approach of using the WSS OM to write a simple console application to delete user profiles. It took less code than you might expect.
The logic first iterates all user profiles, adding the profiles to be deleted into a List object. The selection of the user profiles deleted could be based on any property. In this situation, the code just checks the domain portion of the user account. If the domain name matches the name we want to delete, the account name is added to the list.
if (ParseCommandLine(args))
{
using (SPSite searchSite = new SPSite(String.Format("http://{0}/", _site)))
{
// Use the ServerContext to get the SSP associated to the site collection of interest
// (remember, a farm could have up to 20 SSPs, not to mention external farm SSP associations)
Microsoft.Office.Server.ServerContext context = Microsoft.Office.Server.ServerContext.GetContext(searchSite);
// Get the user profile enumerator for the targeted SSP
UserProfileManager profileManager = new UserProfileManager(context);
long count = profileManager.Count;
IEnumerator enumerator = profileManager.GetEnumerator();
// Get a list account names for use in the following while loop
List<String> profileAccountNameList = GetUserProfileAccountNameList(searchSite, enumerator);
int removedCount = 0;
// Iterate all user profiles.
// NOTE: 80000 is just a sanity check. It is not necessary for this logic to work
while (enumerator.MoveNext() && profileAccountNameList.Count < 80000)
{
UserProfile userProfile = enumerator.Current as UserProfile;
if(userProfile != null)
{
string accountName = userProfile[PropertyConstants.AccountName].ToString();
int i = accountName.IndexOf('\\');
if (i > 0)
{
// Extract the domain name from the full account name
string domainName = accountName.Substring(4, _domain.Length);
// Is this user in the domain we want to delete?
if (String.Compare(domainName, _domain, true) == 0)
{
profileAccountNameList.Add(accountName);
}
}
}
}
The logic then iterates through the list, deleting each user profile contained in the list. The logic also writes out a simple text file, containing the list of user profiles deleted, so there would be an audit record.
private static List<String> GetUserProfileAccountNameList(SPSite searchSite, IEnumerator enumerator)
{
List<String> profileAccountNameList = null;
// Get a list account names for use in the following while loop
List<String> profileAccountNameList = GetUserProfileAccountNameList(searchSite, enumerator);
int removedCount = 0;
// Create a log file to record all actions taken by this application
using (StreamWriter sw = new StreamWriter(String.Format(@"D:\temp\{0}", _file)))
{
foreach (string accountName in profileAccountNameList)
{
// Write the audit log record
sw.WriteLine("Removing user profile:\t" + accountName);
// Delete the user profile
profileManager.RemoveUserProfile(accountName);
// Keep a running account
removedCount++;
}
sw.WriteLine("Removed user profiles:\t" + removedCount.ToString());
sw.Close();
}
// Sort here after conversion to Int,
// since the profile data is string datatype, which doesn't sort property as a numeric
profileAccountNameList.Sort();
return profileAccountNameList;
}
The code ran quickly and smoothly. You can download a copy and modify the selection logic to delete user profiles based on any profile property.