29 December 2010

SharePoint 2010 People Picker de-mystified!

The problem with most demos and classes is that the presenters use straight Active Directory for the configurations and though this most certainly has the desired effect of making the demo run smoothly because everything “just works”, it doesn’t help you and me in the REAL WORLD where more often that not, we encounter a blended environment.  If you are fortunate enough to work in a straight AD shop, count your blessings every night!
For the rest of us, we have to make that “blend” work for the customer because at the end of the day, they don’t care, nor should they, about the technical difficulty behind the scenes to make it work… they just want it to work… first time… every time. 🙂
Such is the case when you’re dealing with a Forms Auth/LDAP environment.  My client has a huge deployment in SP2007 under LDAP.  We deployed SP2010 under Claims Auth which meant a shift away from our old SiteMinder LDAP authentication scheme.  Of course, under Forms Auth, we controlled the database against which the authentication and searching was done ala the source against which the PeoplePicker control was searching.  Under claims, AD is the source and that adds new technical challenges to the mix in order to ensure that your customer search experience remains the same.  Thus my search for information about the PeoplePicker in 2010 began…
There are lots of links out there related to PeoplePicker and custom AD searches.  The first and most obvious is this MSDN link that gives us the basic overview.  It even provides some basic examples, but it doesn’t actually EXPLAIN how to use it.  Joel posted on his old blog on the topic, but it was basically a collection of what’s on MSDN so I was still looking for more detail.  There were lots of other posts on the “peoplepicker-searchadcustomquery” switch in STSADM, but they were all either references to the MSDN article or copy and paste jobs. 🙁
In the end, I was left to decipher the problem the old fashion way… through trial and error.  After many attempts, I finally managed to get a good read on how it actually works and was able to explain it to my colleagues as well.  Now I’m hoping this blog post saves someone some time in the future when they have to work through this.  I’ll begin with my Powershell script:
 1:  clear-host
   2:  write-host -f green "========================="
   3:  write-host -f green "========= BEGIN ========="
   4:  write-host -f green "========================="
   5:  write-host ""
   6:  $snapin = "Microsoft.SharePoint.PowerShell"
   7:  if (get-pssnapin $snapin -ea "silentlycontinue")
   8:  {
   9:    write-host -f green "PSsnapin $snapin is loaded"
  10:    write-host ""
  11:  }
  12:  else
  13:  {
  14:    if (get-pssnapin $snapin -registered -ea "silentlycontinue")
  15:    {
  16:      write-host -f green "PSsnapin $snapin is registered"
  17:      Add-PSSnapin $snapin
  18:      write-host -f green "PSsnapin $snapin is loaded"
  19:      write-host ""
  20:    }
  21:    else
  22:    {
  23:      write-host -f Red "PSSnapin $snapin not found"
  24:      write-host ""
  25:    }
  26:  }
  27:  [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
  28:  $webapps = get-spwebapplication
  29:  foreach ($webapp in $webapps)
  30:  {
  31:    write-host -f yellow $webapp.displayname;
  32:    write-host -f yellow $webapp.url;
  33:    stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadcustomquery -pv "(userPrincipalName={0}*)(givenName=*{0}*)(sn=*{0}*)(displayName=*{0}*))";
  34:    stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadforests -pv "domain:<<>>.com";
  35:  }
  36:  write-host ""
  37:  write-host -f green "========================="
  38:  write-host -f green "========== END =========="
  39:  write-host -f green "========================="
  Lines 1-5 simply clears the screen and writes a starting header. Line 6 sets a local variable ($snapin) to “Microsoft.SharePoint.PowerShell”. Lines 7-11 checks if the snapin is loaded already.  If it is, it writes a message on screen noting that.
Lines 12-26 kicks in if the snapin is not already loaded.  In this case, it gets the registration info for the snapin and then tries to load the snapin.
Line 27 loads the Microsoft.SharePoint.dll in order to access the SharePoint object model. Line 28 sets a local variable ($webapps) to the return value of the “get-spwebapplication” PowerShell cmdlet.
Lines 29-30 sets up an iteration loop for each object in the $webapps variable.  It temporarily sets the current object to another local variable ($webapp) for processing in subsequent lines.
Lines 31-32 writes the Display Name and the URL values of the web application being processed.
Lines 33-34 is where the magic happens.  These lines call STSADM and passes the needed values to it in order to set SharePoint’s metadata properties for the people picker.
Line 35 closes the loop.
Lines 36-39 simply writes to closing a closing footer.
Now let’s look at the two STSADM commands in more detail.
stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadcustomquery -pv "(userPrincipalName={0}*)(givenName=*{0}*)(sn=*{0}*)(displayName=*{0}*))";
The key is the “setproperty” operation in STSADM.  Since these properties are stored by SharePoint on a web application basis which is why this command is issued for each web application in SharePoint.
The first switch we provide to the operation is the URL of the web application.
The second switch is the property name and in this case, we’re targeting the “peoplepicker-searchadcustomquery” property.
The third switch is the property value.  The value we pass here is the search values that is appended and passed into Active Directory for the search query.  This is where the available documentation is lacking.  The format to use is as follows:
(<AD Name>=<wildcard>{0}<wildcard>)
where <AD Name> is replace by the Active Directory property name you’re targeting and <wildcard> is replaced by either a star (*) if you want to wildcard on that side of the query or nothing if you don’t want the wildcard on that side.
In our example, we are targeting 4 Active Directory properties.  The first is “userPrincipalName” which is the user ID e.g. “cjvandyk@crayveon.com”.  In this example, we are using a wildcard at the back of the query so a search such as just using “cjvandyk” or “cjvan” should yield a match.
The second property is “givenName” which is a user’s fist name.  We are using front and back wildcards here so any part of the user’s name would yield a match.
The third property is “sn” which is the user’s last name.  Again, we’re using front and back wildcards in order to yield a match on any part of the user’s last name.
The last property is “displayName”.  This field is populated with the commonly used name of the user.  In most cases, a user’s name is registered for a match on the default query passed to Active Directory as “First MI Last” for example, a user would be matched as “Robert E. Doe” within the system.  For a user to locate him in a people picker they’d have to use “Robert E. Doe”.  In person he may be known as “Bob Doe” instead.  A user trying to find Bob in the people picker with “Bob Doe” won’t get a match, but if the Active Directory property for “displayName” is populated with this value i.e. “Bob Doe”, our fourth property would yield a match for the user.
The second STSADM property we are setting for the web application is that of the “peoplepicker-searchadforests”.  This is used when you have a very large Active Directory and wish to limit the AD query down to just a specific sub set instead of searching the entire directory.  Doing this, can result in some major performance gains in your people picker.  The syntax is:
stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadforests -pv "domain:<<<CHANGEME>>>.com";
As before, our first switch passed is the URL of the target web application.
The second switch is again the property name which as we’ve already mentioned is “peoplepicker-searchadforests”.
The third switch is the property value.  In this switch, simply replace the “<<<CHANGEME>>>” with your target domain you wish to limit the search to.
The last thing you need to do, is ensure that your Active Directory team configure indexes on all the properties that you have specified in your search query.  Having indexes on these properties within AD will also give you a good boost in the performance of the people picker control.
Provided that your AD is populated correctly, using this script, you can configure the people picker for optimal results for the end user.  For your convenience, you can download the PowerShell script from my downloads library located here:


No comments:

Post a Comment

Comments are moderated only for the purpose of keeping pesky spammers at bay.

SharePoint Remote Event Receivers are DEAD!!!

 Well, the time has finally come.  It was evident when Microsoft started pushing everyone to WebHooks, but this FAQ and related announcement...