Inside the SharePoint 2010 My Site Cleanup Timer Job

This post will discuss what the SharePoint 2010 My Site Cleanup Timer Job is, what it does, and how to manage it.  If you need to implement your own cleanup process, this post will also provide building blocks for implementing your own solution to manage deleted users and My Sites.

What is the My Site Cleanup Timer Job

The My Site Cleanup Job is responsible for deleting user profiles and My Sites of those users.  This includes the following activities:

  1. Remove user profiles that are queued for deletion.
  2. If those users have a My Site, assign the  user’s manager as the SPSite.SecondaryContact.  Email the manager letting them know that the user’s My Site will be deleted in 14 days.
  3. 11 days after the first notification, email the manager again letting them know that the My Site will be deleted in 3 days. 
  4. After a total of 14 days, delete the MySite.

The first thing we need to understand is how a user profile is actually deleted.

How Is A User Profile Deleted?

A user profile is deleted when you either use the web UI in Central Administration to delete a user profile, or when a user who was included in a previous user profile import is no longer included in the import.  The second point bears a little more explanation. 

Suppose you delete a user account in Active Directory and then run an incremental or full user profile synchronization.  You would expect that this means the user profile is deleted, and in fact it is as Spence Harbar shows in his post Account Deletion and SharePoint 2010 User Profile Synchronization.  This is picked up as a delete from Active Directory and processed in the FIM, where SharePoint picks up the fact the user profile is deleted and deletes it.

Now, suppose you have already set up a connection filter for your user profile service application that excludes disabled users using useraccountcontrol bit on equals 2. 

Note: Before editing connections, make sure to disable the My Site Cleanup Timer Job.  


Right-click one of your users in Active Directory Users and Computers and disable the account.  Next, run an incremental user profile synchronization. 


This has the same meaning to SharePoint as if the user had been explicitly deleted… the user met the exclusion filter criteria where they did not previously, so this means “delete” to SharePoint.  Note that this doesn’t just apply to disabling or deleting accounts in Active Directory, it applies any time that the user is no longer part of the user profile synchronization. 

Let’s look at this a slightly different way... any time an existing user suddenly meets the exclusion criteria, it is considered a delete.  To demonstrate this, I added a connection filter for “Department = Fired”.  Make sure to use the “Or” option so that it reads “exclude any account that is either disabled OR department = ‘Fired’”. 


Make sure to click the Add button to actually add the filter, and click OK on the page to actually save the filter.


We first make sure that we have a few My Sites that we want to test with, and we find that some of the 1099 Contractors in our organization created My Sites.  We then go to Active Directory and change a few of the contractors’ department to “Fired” to illustrate the point of meeting exclusion filter criteria.


Since we’ve changed the connection filter, we should run a Full Synchronization.  If we open MIISClient (located at C:\Program Files\Microsoft Office Servers\14.0\Synchronization Service\UIShell\miisclient.exe on the server that is running user profile sync) and look at the last run, we can see that the users are processed as deletes by the MOSS management agent.  I highlighted the relevant portions showing it is the MOSS MA, there are 2 deletes, and I clicked on the Deletes in the summary to show the deleted objects. 


Note: MIISClient can be a useful tool for monitoring user profile synchronization, but it is unsupported to make changes using the tool. See Support for modifications to the user profile configuration settings via the FIM Client (MIISClient.exe) that ships with SharePoint.

If you go into the UserProfile_Full table (completely unsupported, do not do this in production, this is a bad idea but is shown here for illustrative purposes) and look for records with bDeleted = 1, you will find our two suspects.


Note: It is unsupported to directly read from SharePoint’s databases, and doing so can cause significant performance problems in your SharePoint environment. I did this for educational purposes only, do not do this in a production environment. See Support for changes to the databases that are used by Office server products and by Windows SharePoint Services for more information.

These users are now considered queued for deletion.  We’ll get to that in a second.  In the meantime, the guidance here is to make sure you have your exclusion filters correct when you add new ones, because any users that are not included in the import and had been previously are considered deletes. 

The point of this section is that it is easy to mess up the exclusion filters and accidentally filter out the wrong users.  Make sure to disable the My Site Cleanup Timer Job when editing connections, the reason for this will become abundantly clear in the next section.

What Happens When the User Profile Cleanup Timer Job Runs?

When you delete a user profile, you are not only deleting their profile properties (such as Department, Preferred Name, email address, interests, and keywords), but also associated profile data such as their quick links and user profile picture.  You are also deleting their My Site.  None of this happens immediately, this is the domain of the My Site Cleanup Timer Job. 

Cleaning Up User Profiles

The My Site Cleanup Timer Job runs by default once per hour.  When the timer job first executes, it queries the UserProfile_Full table in the User Profile database for any profiles queued for deletion by filtering on bDeleted=1, via the Profile_GetDeletedUserList stored procedure.  You can independently verify this by running a SQL trace and kicking off the My Site Cleanup Timer Job manually, but trust me on this one.  Given a list of users queued for deletion, it determines if the user has a My Site.  If they do have a My Site, the My Site is queued for deletion, an email is sent to the user’s manager, and the user profile is deleted.  If the user does not have a My Site, then their profile is simply deleted.

Cleaning Up My Sites   

My Site reassignment and deletion is managed in the MySiteDeletionStatus table in the user profile database.  Upon first processing the deleted user profile, the My Site Cleanup Timer Job adds a record into the MySiteDeletionStatus table with today’s date and a flag of 1, indicating that the first notification was sent.  Remember that querying SQL directly is unsupported, shown here for educational purposes only.


Check the manager’s inbox, and we see two new emails that let us know the My Site is going to be deleted in 14 days.


Click the link in the email, and we see that we now have access to the My Site.  We are logged in as Brian Groth, but accessing Dan Bacon’s personal site.  Note also that we have access to the Shared Documents as well as the Personal Documents folder for the user. 


Note:   This only works if the My Site host is in classic authentication mode.  If you are using claims (Windows or SAML), then you will see the following error in ULS:

06/13/2012 01:33:01.95 OWSTIMER.EXE (0x1BB0) 0x063C SharePoint Portal Server User Profiles oggw Unexpected MySiteCleanup: Unable to change owner of MySite for user profile (SharePoint\davidd).  Exception: Microsoft.SharePoint.SPException: User cannot be found.     at Microsoft.SharePoint.SPUserCollection.get_Item(String loginName)     at Microsoft.Office.Server.UserProfiles.MySiteProfileHandler.SetMySiteOwner(UserProfile profile, String newOwner)     at Microsoft.Office.Server.UserProfiles.MySiteProfileHandler.PreProfileDeleted(UserProfile profile) 05d8cd84-e4a0-479c-9833-77151c8895f9

In this case, the manager will not be assigned as the SecondaryContact for the SPSite, and the manager will not receive an email.  No record is written to the MySiteDeletionStatus table, so the My Site will not be deleted.  Again, this scenario only happens if the My Site host is using claims authentication.  A workaround is presented at the end of this article.

Now that the cleanup job has executed, we can inspect things to see what happened.  We query the UserProfile_Full table where bDeleted = 1, and no records are there because the My Site Cleanup Timer Job deleted them.  If we go to the User Photos list in the root of the My Site host, we see that the user’s picture has been deleted, too.  

After 11 days have passed, the My Site Cleanup Timer Job runs again and sees that 11 days have passed since the initial processing.  It updates the NotificationStatus to 2 and sends another email.


We view the manager’s email again, this time it says 3 days left.


After 3 more days pass (a total of 14 days), the My Site is quietly deleted. 

You’re On the Clock

  The Configure Profile Synchronization docs on TechNet call out an important point:

You must disable the My Site cleanup timer job before you create or modify connections. For information about this timer job, see the Timer job reference (SharePoint Server 2010) and for information about the Windows PowerShell cmdlets that you use to enable and disable this timer job, see Timer jobs cmdlets (SharePoint Server 2010).

Let’s say that you are working with exclusion filters, and you accidentally set the filter such that it will delete a LOT of users. You run the user profile sync, and notice that a bunch of users are now gone that shouldn’t be. No worries, you think, I’ll just correct the filter. However, while you are working, the My Site Cleanup Timer Job runs in the background, finds all those deletes, deletes the user profiles (their picture, profile data such as interests and keywords, colleagues, and queues up the My Sites for deletion. The next time you sync, the profiles are added back in (of course only with the data you pulled from sync) but the My Sites will remain queued for deletion. Even though the user profile is created once you correct the filter and run a sync, the My Site is still queued for deletion and in 11 days the manager receives a nag email that the My Site will be deleted in 3 days.  Remember to disable the My Site Cleanup Timer Job when working with connections to prevent this situation from occurring.

If you find yourself in this situation where the My Site is queued for deletion, simply back up the site collection using Central Administration, then restore it after the My Site Cleanup Timer Job deletes it. 


As an alternative, you can use PowerShell to back up the site collection and then restore the site collection after the My Site Cleanup Timer Job deletes it, see the section on archiving My Sites at the end of this post for an example.  Another alternative is to restore from database. 

A little prevention prevents a lot of work later.  Simply disable the My Site Cleanup Timer Job when editing connections, and test your changes in a non-production environment to ensure they produce the results that you expect.


No Manager?

When you set up My Sites with your User Profile Service Application, you should have noticed the paragraph at the bottom of the page.


The text reads:

When a user is no longer in the User Profile Database, the My Site Cleanup Job tries to assign ownership of that user's My Site to the user's manager. If the user does not have a manager, ownership of that user's My Site is assigned to the Secondary My Site Owner.
The My Site in question gets deleted two weeks after this reassignment of ownership. This gives the manager or the Secondary My Site Owner an opportunity to retrieve content from the My Site before its deletion.

What if you do not map the Manager property, or it is not populated in your organization?  What if there are certain types of users, such as contractors, that you do not set a Manager property for? 

If you do not populate the Manager user profile property, then the My Site is assigned to the Secondary My Site Owner.  If the user does not have a manager, and the Secondary My Site Owner is not configured, then no email notifications are sent and the My Site is left alone for you to decide what to do with later.

To sum up, here is a table that explains it more clearly.

Manager Profile Property Populated

Secondary Contact Configured

Email Sent

Site Queued for Deletion



Yes, to manager




Yes, to manager




Yes, to secondary contact






Now let's move on to the actual deletion of the site.

UserProfileManager.RemoveUserProfile(id) and SPSite.Delete()

If you are reading this, chances are that you have seen Joel Oleson’s post, “SharePoint Profile Cleanup and the My Site Cleanup”, which indicates that the My Site Cleanup Timer Job does not delete sites.  This is not true, the My Site Cleanup Timer Job actually deletes the site.  His post mentions Site Use Confirmation, which is an entirely different process and has no relation on the process described in this post.

Joel’s post also quotes Spence Harbar, saying the timer job bails out if a My Site Host is not configured and the user profiles are not deleted.  Spence confirmed that this was the behavior at the time of writing.  As of the current CU this is no longer the case.  The timer job checks to see if a My Site Host is configured on the user profile service application, and if it is not configured then it skips the logic for queuing My Sites for deletion and just deletes the user profiles.  It is no longer necessary to configure a My Site Host just to get the user profiles cleaned up. 


To emphasize the previous section, the timer job really does call SPSite.Delete().  If you are going to terminate a large number of users, plan ahead with the directory services admins on when the deletions will be performed and how that aligns with your synchronization schedule.  Since the timer job iterates the user profiles and deletes the site collection for each, consider the potential performance impact to your farm.  If you want to experiment, start a load test in your environment and measure the baseline performance, then try deleting a few hundred site collections in a tight loop… you’ll see performance is severely impacted for the duration of the delete operations.  Instead of relying on the My Site Cleanup Timer Job to perform this work, you should proactively delete the site collections in batches and do this before the 14 day period expires.  In a mass termination scenario with SharePoint 2010, consider disabling the timer job for a period of time and managing this process yourself.  See the section at the end of this post that discusses the Gradual Site Delete timer job and how to leverage it using object model code or PowerShell.


People Picker, Organization Browser, Search, and User Profiles

We now turn our attention to other parts of the product that rely in part on the My Site Cleanup Timer Job for deletion of user profiles. If you turn off the My Site Cleanup Timer Job, be aware of what is left behind.  You should also understand the additional processes that may need to be run in addition to deleting profiles.

The deleted users still show in people search results until cleaned. To demonstrate this, I changed two more users to the “Fired” department and then ran an incremental user profile sync.


When we search for those two users, and they are still in the search results.


When you think about it, this makes sense because they are still in the search index. However, do another incremental search, and they still show up despite having UserProfile_Full.bDeleted = 1. The fix for this is to delete the user profile and then do an incremental search crawl. You can delete the user profile by simply running the My Site Cleanup Timer Job, or you can manually purge the user profile (read below for more information). Once the profile is deleted, run another incremental search crawl and the users no longer appear in people search.

Another place that the user profiles queued for deletion continue to show is through the Organization Browser Silverlight control. If we go to the manager’s Organization Browser Silverlight control, a user profile queued for deletion (UserProfile_Full.bDeleted = 1) still show in there.


The fix to have users removed from the organization browser is to either run the My Site Cleanup Timer Job to delete the user profiles, or to purge them yourself (read below for more information).

User profiles also play a part in the People Picker. I created an enterprise search site, and used the People Picker to grant permissions to the site. The deleted user still shows in the People Picker, too.


In short, there are a few places where the deleted user profiles will continue to show up for about an hour until the My Site Cleanup Timer Job runs, or until the user profile is purged. If you plan on disabling the timer job, understand that means that you need to implement additional procedures to maintain the environment.

Non-Imported Objects

Remember our discussion earlier about a deleted user. This is different than a user who was not part of the synchronization to begin with. I can log into SharePoint as a user who is not in the OU that is being synchronized, and view my profile. A record is written to the UserProfile_Full table for that user, and this user is now considered a non imported object.

To demonstrate, I added a user Joe User to the Users OU in my domain, which is not part of my profile import.  Log in as that user and access the My Site host, viewing the user’s profile, and you will see the user now has a record in the UserProfile_Full table.  Run the following PowerShell, and you can see that this account is now considered a non-imported object.

 Set-SPProfileServiceApplication $upa -GetNonImportedObjects $true

The output will look something like:

 These objects will be marked for deletion.
User SHAREPOINT\spsetup
User sharepoint\joeuser

The spSetup account is the account that I used to install SharePoint and use for maintenance, such as applying patches and making topology changes to the farm.  It is not part of the profile import, either, so it makes sense that it would be there as well. 

Why do you care about any of this?  The docs on Maintain profile synchronization indicate that the following should clean up deleted users if the My Site Cleanup Timer Job is disabled:

 Set-SPProfileServiceApplication $upa –PurgeNonImportedObjects $true

The article is correct in that it marks the non-imported profiles for deletion, however it does not do the same thing as the My Site Cleanup Timer Job.  PurgeNonImportedObjects simply sets UserProfile_Full.bDeleted = 1.  After running the command, you can see this in the UserProfile_Full table. 


Recall that if we had the My Site Cleanup Timer Job enabled, then it would sweep those users.  If the My Site Cleanup Timer Job is disabled, the users will remain in the UserProfile_Full table with bDeleted = 1, and we saw earlier that users who are queued for deletion continue to show in the Organization Browser Silverlight control, in search results, and in the People Picker until the deletion is finalized.  Understand that if you choose to disable the My Site Cleanup Timer Job, purging the non imported objects does not actually delete the user profiles, and it does nothing to user profiles that were part of the import.  If you choose to disable this timer job, you should implement custom processes to maintain your environment.

Implementing Your Own Cleanup Process

I have heard from a few customers who wanted different behavior than what the My Site Cleanup Timer Job provides, so they simply disabled it.  Read the rest of this article and understand what doesn’t happen if this job is disabled.  If the timer job is disabled, then we need to purge the profiles ourselves, and we need to control what happens with My Sites.

What’s really cool about this is that it opens a bunch of different possibilities for managing what happens to My Sites.  You can implement your own business processes such as a custom disposition workflow that requires approval prior to assignment or deletion, or even processes workflows based on a user’s employment status or position within the company.  There are a lot of opportunities for customizations here depending on your requirements.  In this section I present a few building blocks for creating your own process.

Purging User Profiles

To actually delete user profiles (not just queue them for deletion, but really delete them), you can use a script similar to the one below. Beware: this actually deletes the user profiles… there is no “undo” operation here. Also know that this does nothing with the My Sites, so you might want to reassign My Sites for the users prior to running this because once the user profile is gone, there’s no way for the My Site to be automatically reassigned to a user’s manager, you’ll have to manage that yourself.

 function Remove-SPUserProfile([Microsoft.Office.Server.UserProfiles.UserProfileManager]$upm, [string]$accountName)
        $userProfile = $upm.GetUserProfile($accountName)
        $id = $userProfile.ID
        Write-Host $accountName " does not exist"

function Process-DeletedUserProfiles([string]$siteUrl, [string[]]$users)
    $gc = Start-SPAssignment
    $site = ($gc | Get-SPSite $siteUrl)
    $context = ($gc | Get-SPServiceContext -Site $site)
    $upm = new-object Microsoft.Office.Server.userProfiles.UserProfileManager($context)
    foreach($user in $users)
        Remove-SPUserProfile $upm $user
    Stop-SPAssignment $gc

$users = "sharepoint\anneliz", "i:0#.f|fbamembership|fbamember1", "sharepoint\hugog"
Process-DeletedUserProfiles http://my.sharepoint.lab $users

This is the operation that you will need to run when you see deleted users in the Organization Browser, search results, and the People Picker.  Note that if you have the My Site Cleanup Timer Job enabled, you don’t have to do this because the timer job does this for you. 

Querying for Deleted Users

Let’s say you want to implement your own process to automatically archive deleted My Sites.  The first task is to figure out what users were deleted.  You can do this with the UserProfileManager class.  Fortunately the code is very straightforward and bears little explanation. 

Note: In order for this code to work, the account that it is running as needs to be granted Full Control on the user profile service application AND be added as an administrator with full control to the user profile service application.  Otherwise you’ll receive a NullReferenceException in the constructor to the UserProfileManager class.

 $gc = Start-SPAssignment 
$mySiteHost = ($gc | Get-SPSite "")
$context = ($gc | Get-SPServiceContext -Site $mySiteHost)
$upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$query = new-object Microsoft.Office.Server.UserProfiles.UserProfileChangeQuery
$query.Delete = $true;
$query.DistributionListMembership = $false
$query.UpdateMetadata = $false
$query.Add = $false;    
$d = get-date            
$query.ChangeTokenStart = 
  new-object Microsoft.Office.Server.UserProfiles.UserProfileChangeToken($d.AddDays(-5));
Stop-SPAssignment $gc

This bit of code allows you to query for user profiles that have been deleted in the past 5 days.  The output of this:

 SharePoint\danield Delete 6/13/2012 3:21:03 PM 4342
SharePoint\danb Delete 6/13/2012 3:21:17 PM 4343

Gary Lapointe wrote a great article, Monitor SharePoint User Profile Changes, that goes into a little more depth on this.  If you don’t want to run code on the SharePoint server itself, you can also accomplish this with the UserProfileChangeService Web Service

An important point to remember with this API is that there is another cleanup timer job, the User Profile Change Cleanup Job, that runs daily by default and deletes user profile change data that is older than 7 days.  If you are trying to find changes from several months ago and cannot find it, this is the job responsible for cleaning up the old change data.

Assigning My Sites to Someone Else

The next part that you want to handle is what to do with the My Site.  You can assign a secondary contact of your choosing.  This should also allow a workaround for the Classic Authentication issue I mentioned previously.

 $gc = Start-SPAssignment 
$mySiteHost = ($gc | Get-SPSite "")
$context = ($gc | Get-SPServiceContext -Site $mySiteHost)
$upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

$u = $upm.GetUserProfile("sharepoint\davids1");
Write-Host $u.PersonalSite

$mySite = ($gc | Get-SPSite $u.PersonalSite)
$newOwner = $mySite.RootWeb.SiteUsers["sharepoint\kirkevans"];
$mySite.SecondaryContact = $newOwner;
Stop-SPAssignment $gc

This is just one example of how this could be managed.  You will need to review your privacy rules before implementing this as privacy rules may differ between companies or even between countries. 

Archiving Sites

If your requirements include archiving, then you could easily add this into your custom process.  One approach is to use PowerShell to simply back up the SPSite to long form storage.  This is no different than archiving a typical SPSite.

 $gc = Start-SPAssignment 
$mySiteHost = ($gc | Get-SPSite "")
$context = ($gc | Get-SPServiceContext -Site $mySiteHost)
$upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

$u = $upm.GetUserProfile("sharepoint\davids1");
$siteId = $u.PersonalSite.Id
Backup-SPSite $u.PersonalSite -Path C:\Backup\$siteId.bak
Write-Host "Backed up " C:\Backup\$siteId.bak
Stop-SPAssignment $gc

Another approach is to leverage database backups. 

Deleting Sites

Once you are done you need to determine how you will handle deletion, but that is as simple as calling SPSite.Delete or using the PowerShell cmdlet Remove-SPSite.  The part to understand is what parameters to use.  If you call SPSite.Delete() with no overloads, then the site collection is immediately deleted, which is OK for a few sites.  If you are deleting 30,000 sites at once, this can cause a significant performance impact on your farm.  Instead, you can use SPSite.Delete(false, true) or use the GradualDelete $true parameter with PowerShell to delete the site collection.  This will defer the deletion of the site collection to the Gradual Site Delete timer job.  See Bill Baer’s post, Gradual Site Delete in SharePoint 2010, to better understand the Gradual Site Delete timer job.


This is a ton of information, the post became much longer than I originally planned.  As I asked peers to review it, I realized more opportunity to provide insight.  Working in Microsoft’s Premier Field Engineering organization provides unique opportunities to see and research complex problems.  You may find a huge amount of value in bringing in a Microsoft PFE for a health check of your environment and to help with planning changes to your environment, helping to avoid some of the issues highlighted in this post.  To learn more about PFE, visit

For More Information

Account Deletion and SharePoint 2010 User Profile Synchronization

Creating User Profile Synchronization Exclusion Filters using the userAccountControl attribute

UserProfileChangeService Web Service

Monitor SharePoint User Profile Changes





Support for modifications to the user profile configuration settings via the FIM Client (MIISClient.exe) that ships with SharePoint

Support for changes to the databases that are used by Office server products and by Windows SharePoint Services

Gradual Site Delete in SharePoint 2010

Configure Profile Synchronization

Timer Job Reference (SharePoint 2010)

contact Microsoft Support.

Special Thanks

Special thanks to colleagues who helped review this post or provide additional information on topics covered:  Eric Adams, Chris Gideon, Keith Bendure, Luca Bandinelli, Spence Harbar, Bob Fox, Jimmie Thompson.