There was a lot of talk about how the User Profile memberships in SharePoint 2007 worked. The net effect was that the memberships were stored in a profile property MemberOf or internally SPS-MemberOf. This was driven by a timer job which ended with ‘User Profile to SharePoint Full Synchronization’. However, this changed slightly in 2010 – and the change mattered. In SharePoint 2010 the memberships got their own collection property off the UserProfile object. The Memberships became a full collection to store values.
This didn’t change the requirement that to be listed the user had to be a member of the Members group of the site – not the Owners – only the members. So the list still has its issues from a usability perspective. The memberships for a user shows up in profiles in two places: Memberships and Content. In Memberships it shows a listing of sites vertically. In Content you can navigate across a horizontal bar of sites and libraries:
In all honesty, I generally recommend that organizations replace the Memberships and Content functionality of a my site with a library in the user’s my site that contains links to the sites that they have permissions in. I’ve done this various ways – including opt-in from the user from the personal menu but no matter how it’s done we invariably find that users can actually understand it if they’re managing it and when it is being driven by their permissions to the site. However, in this case, the company didn’t consider replacing these and they were up against their deadline for implementing the Intranet.
The client was reporting that their memberships in their user profiles were out-of-date. There were sites that no longer existed that people were seeing, they were also getting access denied while trying to access some of the sites either through the memberships tabs or through the content tab. Upon digging I found that they had split their farm from a single global 2007 environment to a regionally deployed 2010 environment and the 2010 environment migrated the global 2007 profile service. The net effect of this was that they inherited the memberships for all of the sites across the globe – but the user profile service was only updating those memberships for the URLs that the local farm owned. So in this case there were numerous memberships for non-local SharePoint sites that were no longer being updated.
I should say that there are tons of longer term answers to the problem of managing a single user profile and memberships across a global organization, but for right now they decided they wanted to remove all of the memberships so it wouldn’t be wrong. As it turns out the code to do this is relatively simple:
SPServiceContext svcCtx = SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
UserProfileManager upm = new UserProfileManager(svcCtx);
foreach (UserProfile user in upm)
MembershipManager mm = user.Memberships;
Run the code above and all memberships will disappear. If you then run the timer sync job it will re-add the local sites to the farm.
This took an amazingly large amount of time to track down given the relative simplicity of the final answer.