People search (Peter's rambling project retrospective/takeaways):
People Search Comes with MOSS Standard and MOSS Enterprise. The MOSS Enterprise "People Search with Tabs" is different from/better than the MOSS Standard "People Search" site definition.
User Profiles are updated by default by Active Directory. If at all possible, have someone set up a process to update all your people search data in Active Directory, which will then be pulled into MOSS. Aside from the built-in AD fields, you get 15 custom fields if desired. Beware of adding large blobs of data into AD as I vaguely remember there are intermittent catastrophic problems if your AD objects go over 32KB.
Bonus benefit is that all data in Active Directory is also populated into Exchange, which powers Outlook's Global Address List.
Bonus benefit #2 is that the data is populated in Office Communicator (if you use it.)
All employee data in Active Directory = people search nirvana. That's what I assume anyway.
Beware of the very real possibility that your Active Directory is missing employees. Security policies dictate that after a period of inactivity, AD accounts should be deactivated. There are entire categories of employees that seldom or never log into Active Directory, so if you rely on the "deactivated account = terminated employee" convention, as does SharePoint out-of-the-box, you'll be horribly wrong.
It's also important to note that you need to let your AD administrators know that they shouldn't delete AD accounts so long as the employee remains employed.
This brings up a new issue of determining how to configure your profile import to bring in only 'active' employees. Assuming you have similar conventions for AD accounts, the out-of-the-box AD import settings in SharePoint won't cut it.
If at all possible, (and assuming you can't fit it all in AD), use a BDC-tool friendly data source. Once I discovered my data source broke both BDC MetaMan and the MOSS SDK's BDC Definition Editor tool, I immediately discarded the BDC option and dropped into code. Proficiency with BDC XML is possibly the least transferrable skill on this earth.
Another note: I was thankful I dropped into code as I was immediately asked to "fix up a few fields here and there," including the ever-dreaded "please properly-capitalize these ALLCAPS names" request. This would have been impossible using a pure BDC connection.
You cannot store images in the User Profile, only links to images. Specifically this is stored in _userProfile[PropertyConstants.PictureUrl]. Note also that updating the User Profile via the Object Model is an expensive operation (on the order of ~1 second) so only do a Commit() if something changed.
Beware storing all the images in one folder of a document library, I had unrecoverable errors even rendering a view when ~12000 pictures existed in the same root folder. Solution was to break the images up into subfolders. Yes I am aware of the 3000/container recommendation.
We update the PictureUrl links via a nightly timer job. I believe this property may be updated via the standard User Profile import connections/either AD or the BDC, if you have the URL available to you in that way.
User Profile properties (AKA "the fields"):
Review the existing list of User Profile properties, especially whether you want your employees editing their own data (or more importantly, if you want to add user-editable fields to the list.)
I found I had a need to insert URL fields in each user profile. Instead of using the built-in URL property type, which I attempted to customize to suit my needs (and failed), I went with a rich text field and manually built my anchor tags (which allowed ultimate flexibility). This trick works in custom lists too by the way.
Try your best to ignore the presence of the "User List" that is created in every site collection. It exists, but try and fight the urge to use it in any way.
The built in People Search is great...so long as you keep it mostly the same. Before going in to get requirements, BEFORE, figure out which parts of the peopleresults.aspx page are easy to change and which aren't.
Thankfully, the People Search Results use XSL to render. This means you can customize the look-and-feel...
I wasn't able to figure out how to render custom fields using the built-in Results web part. This is available via the KeywordSearch object via the Object Model, but not the People Results Web Part.
Custom sorting is not an option. Apparently everyone asks for alphabetical sorting using the built-in web part. Try and sell your customer on the Web 2.0-ness of relevance sorting (I don't know, make it up on the spot). Or just be honest and tell them that alphabetical sorting necessitates a complete rewrite of the peopleresults.aspx page (!).
The people search box's Advanced link (available only on Enterprise?) is customizable and is an excellent place to work in custom field search.
peopleresults.aspx runs a Keyword search entirely powered by the ?k=yoursearch querystring. Note that if you're creating a custom front-end, you'll have to use the Keyword syntax (laid out well on Chapter 8 of this book by Patrick Tisseghem: "http://www.microsoft.com/MSPress/books/authors/auth12195.aspx") - advanced search boxes in particular rely on Keyword syntax. So if you want to go with a FullTextSqlSearch query, at least implement a search that somehow deals with the "k" querystring (the easiest way to handle it is to just use a KeywordQuery.)
Note that each User Profile property is given a "Managed Name" which is what is used for your Keyword search. E.g. "LastName:Sm Department:IT"
Note that property-specific Keyword searches are prefix wildcard. Meaning that if you're searching for "Smith" you can type "LastName:Smi" and it will find all Smiths, Smithnesses, Smiiis, Sminiards, Smiangelos, etc. ("Smi" may have been a bad example...you get the idea)
You cannot do full wildcard searches, as far as I know, with the Keyword syntax.
person.aspx on the My Site page:
GOTCHA: this page cannot be viewed with Anonymous credentials
Web controls have custom properties that you can change, so before you dig into code and completely rewrite a control, look for a property on the web control that lets you change what you need to change.
Most of the page is laid out via controls, not web parts. You must either dig into SP Designer to customize this page or (allegedly, the better practice) create a custom my site host with a custom person.aspx page.
I'm going to be the luddite and say there's no reason to create a custom my site host site definition just to customize the page. At worst, create a Feature that overwrites person.aspx in the content database and (if you need to revert) use SPD (or the Feature deactivating event!) to revert the page to site definition. All the benefits, none of the "oops what happened to the other stuff this Site Definition Did and oops this doesn't upgrade to vNext and now involves CAML" downsides.
None of the page is documented, so break into Reflector if you need to customize a specific part of it. Pulling user details was surprisingly hard. Here's a code snippet that may help point the way:
return ProfilePropertyLoader.FindLoader(this.Page).ProfileLoaded["LastName"].Value as string ?? "unknown";
My Sites are not required to display the person.aspx page, so if you don't want to roll out My Sites, you don't have to.
Web Parts on the person.aspx page can be removed. We removed a bunch.
UGLY GOTCHA: IE has a problem with the SharePoint JavaScript image resize code (Firefox has no such problem). An ugly workaround to this problem is listed on comment #4 here: http://www.endusersharepoint.com/?p=129- without the fix, images sporadically appear broken. Even with the fix, IE may take 10 seconds or so to finish resizing the images. I have no desire to figure out why this is a problem so haven't investigated it at all. We removed the images from the people search results page because of this problem.
This resize trick is necessary on both peopleresults.aspx and person.aspx, and yes, everywhere else in the portal.
I had an awful time synchronizing user profile properties (the properties themselves, not the data) between dev/QA until I automated the process. Try and reorder the properties via the web UI and you'll know what I mean.
Because I didn't use the BDC, I was able to add a little more flexibility to my user profile import. Also instead of running a timer job, I opted to create a console app. You heard me, console app. This console app does the following:
Kicks off a full import from Active Directory and waits for the full import to finish (takes about 3 minutes)
Deletes any service accounts we oops! just imported from Active Directory, ...or anything not identified as someone we want in the people search: another 1 minute.
Runs my custom user profile update process (long).
Kicks off a full crawl on the isolated profiles content source and waits for it to finish. This is the last step. If any previous step fails,we will never reach this step.
This is important because if for whatever reason, the update process fails, we will still be able to search on yesterday's search index. Full crawl takes ~5-15 minutes (I don't remember).
Last step: updates a custom list with a "success" message, or logs error message to the same list if an exception is thrown. We have a view on the list set to show only successful entries within the last 24 hours.
With all this set up, we're able to run an automated health check to check this page for a "success" message, that will immediately inform us if the update failed in any way. I'm not sure how the update will fail yet, but with this in place at least I'll know it failed almost immediately.
Note: if we had SCOM I might try to do health monitoring "the better way," but it's a moot point. We don't have SCOM. If you do, maybe you'll set this up "the better way."
Again, feel free to edit anything or add your own gotchas or add your own project retrospective/takeaways.