SharePoint: People Picker shows disabled user accounts in domain migration scenario

This is one that has plagued SharePoint admins since SharePoint 2007 and earlier.  There are a few other posts out there that mention this behavior, but as far as I can tell, none of them offer a complete solution.

Consider the following scenario:

The SharePoint farm exists in DomainB.
You have users in DomainA.
You migrate users to DomainB, including SID history, and disable them in DomainB.
You use People Picker in your SharePoint farm to find a user that exists in DomainA.

In this case, People Picker may do one of the following unexpected things:

  • Show the active users in DomainA, but also show the disabled users in DomainB.
  • Only show the active user in DomainA, but when you select the user, it resolves to the disabled account in DomainB.
    • For example, you may find active user Contoso\Karl. However, when you select that user, it then resolves to disabled user Fabrikam\Karl.
  • Only show the disabled user in DomainB.

Note: This same behavior will also occur if you leave both accounts active at the same time in both domains It is not supported to leave both accounts active.  SharePoint does not appreciate it.  See this: https://support.microsoft.com/en-us/help/4033896/

 

That’s odd… why does this happen?

People Picker calls a Windows API (LsarLookupSids3) to resolve the user name by Security Identifier (SID). This goes to the local Domain Controller first (in DomainB), which finds the SID within the SID History of the disabled account and returns that account even though it is disabled.

 

What to do?

You can fix this by removing the SID History from the disabled / migrated accounts.
However, there are legitimate reasons to keep SID History during a domain migration. I don’t think I’ve heard of anyone that was willing to remove it to fix a People Picker issue.

Another option:

If you’re on SharePoint 2010, you must patch to at least August 2012 CU. I hope for your sake, that if you’re still running 2010 at this point, you’re patched well beyond that. If not, here’s the KB that calls the issue out: https://support.microsoft.com/kb/2687339 .

In SharePoint 2013, 2016, and above, the "fix" is included in every build, so no need to worry about patching.

On every version of SharePoint, you must enable the fix by running the following PowerShell:

 $myFarm = Get-SPFarm
$myFarm.Properties.Add(“HideInactiveProfiles”,"true")
$myFarm.update()

 

Or you can go old-school with STSADM:

 stsadm -o setproperty -propertyname “HideInactiveProfiles” -propertyvalue “true”

Note: Both the strings "HideInactiveProfiles" and "true" are case-sensitive and must be entered exactly as shown.

 

Authors note: I've always found the "HideInactiveProfiles" property to be very poorly named.  It has nothing to do with SharePoint user profiles, and it doesn't "hide" anything.  It simply changes the method SharePoint uses to resolve the user.  It's no longer done by SID.  Instead it's done by user account name by calling Win32.SPNtDsApi32.TranslateUserName.

 

Warning! The HideInactiveProfiles setting is not compatible / not supported in a one-way trust scenario.  Setting it will cause People Picker to fail finding users from one-way trusted domains.  See this: for details: https://blogs.msdn.microsoft.com/ahmedamin/2017/09/18/sharepoint-people-picker-is-not-resolving-users-in-one-way-trust/ 

 

After making this change, you also need to clear out a few caches. Failure to do so will make it look like the above change didn’t work.

  • All versions: LSA Cache on the web-front-ends
  • 2013 and above: Client-side People Picker cache

 

LSA Cache

In Services.msc, restart the Netlogon service on the web-front-ends.

Or, if you're adverse to restarting that service on a production server, you could Temporarily disable the LSA cache on the web-front-ends (WFEs) to clear out any “bad” SID to name mappings in the cache.
Follow the steps here to disable LSA cache on the WFEs:
https://support.microsoft.com/kb/946358
Important: Once you've disabled LSA cache and done at least one People Picker search, you should re-enable the cache by deleting the LsaLookupCacheMaxSize registry key. Failure to re-enable the LSA cache can result in SIDs being resolved to the wrong accounts again, and also inhibits SID resolution performance.

 

People Picker Cache

The 2013 and above People Picker is rendered client-side, and caches user account suggestions within the client browser. So even after making the above changes, it can appear that People Picker is still finding the disabled user, but it’s actually being fetched from your local browser cache. Try a different browser, a different client machine, or search for a different user than the ones you’ve been testing with.
You can also clear the browser cache. See this: https://wp.ahcheng.com/2015/07/14/how-to-clear-sharepoint-people-picker-suggestion-cache/
The methods to clear the cache vary by browser. With Internet Explorer, you can even disable this cache altogether by unchecking “Enable DOM Storage” in the Advanced settings.  You can probably do something similar with other browsers as well.

 

Anything else to know?

Yes.

-- Setting the "HideInactiveProfiles" property is meant to be a temporary solution that should be reversed when your domain migration is complete and you've cut your users over to their new accounts. Functionally, there's nothing wrong with leaving it set, but it doesn't perform as well (it's slower) as the default behavior of resolving the user by SID. You can revert to the default behavior like this:

 $myFarm.Properties.Remove("HideInactiveProfiles")
$myFarm.update()

 

-- Another thing to consider in a domain migration scenario is importing / synchronizing user profiles.  You want to be careful to only import a single copy of a given user at any given time.  If you set your Sync connections to filter out disabled accounts, and you only have one account active at any given time in AD, this should not be a problem.   This is one of the reasons that leaving both accounts active with SID History is not supported.  Importing both accounts can result in the Sync process automatically migrating (like move-spuser) one account to the other and then back again, which can lead to permission loss and general chaos.