Sunday, February 20, 2011

Create custom AD attribute and map it to Sharepoint user profile property

In this post I would like to show the guide of how you can expand your AD schema with custom attributes and then map them on User Profile properties in Sharepoint. Although there is a lot of standard attributes which can be used for storing information in AD, this is common situation when they don’t match requirements of enterprise infrastructure. Imagine situation when company has various business units which should be stored in AD with other information about users and we need to make them searchable in the Sharepoint intranet (in this article by Sharepoint I mean Sharepoint 2010). Once user profiles have indexed business unit property Sharepoint will crawl them OTB and show in the people search result. So our goal is to map AD attribute, which is used for storing business units, on User Profile property.

There is no attribute “Business Unit” in standard AD schema. Of course there is a lot of other attributes and you can use them for storing business units information. The only thing you need to do is to find some suitable attribute (which name is more or less close to the real attribute purpose and which has appropriate data type), e.g. if we assume that business units are text data we can use standard Business-Category (businessCategory) attribute (Type = Unicode String). But this approach has own disadvantages: we introduce one more implicit solution into IT infrastructure of the company (how many such solutions already exist in your IT infrastructure? :) ), if in the future we will need to use business category attribute for its real purposes we will need to perform additional work: select another standard attribute (and we are also not saved from the same problems in the future with the new attribute), migrate existing data, reconfigure Sharepoint, etc.

Another solution is to expand your AD schema by creating new custom attribute and then map this attribute on Sharepoint user profile property. It will require more work from us, but solution will be explicit (data will be stored in the place where it is supposed to be) and we will not problems with attributes reusing in future.

First of all we need to create custom AD attribute. In order to do it I recommend to follow this article: Adding Custom Attributes in Active Directory. We don’t need to perform all steps from it, so I will put exact steps (steps 1-18) here (also I want to collect all steps in one article for future references) and add my comments to the steps:

  1. Ensure that you have enabled AD schema updates (parameter “Schema Update Allowed” = 1 of type REG_DWORD in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
  2. Install the Schema snap-in (Start > Run > regsvr32 schmmgmt.dll)
  3. Go to Start > Run > Type MMC and press Enter
  4. Go to File > Add/Remove Snap-in > click Add > Select “Active Directory Schema” (it will occur after step 2 only, i.e. after you installed Schema snap-in) and click Add
  5. Expand the Active Directory schema and Right Click Attributes
  6. Click “Create Attribute”
  7. Create New Attribute window will appear
  8. In Common name enter “Business Unit” (LDAP name as “businessUnit”)
  9. Get OID please refer http://msdn2.microsoft.com/en-us/library/ms677620.aspx. Shortly you need to obtain the basic ID using the script available here. You will get basic object identifier, which will look like sequences of digits separated by dots: “1.2.840.113556.1.6.1.8000.xxxx”. In order to create OID for attribute you can add “.2.1” suffix, so the final ID will be “1.2.840.113556.1.6.1.8000.xxxx.2.1”
  10. Select the Syntax = “Unicode String”
  11. Click Ok. After that new attribute will be created
  12. Now we need to add this attribute to “Person” class
  13. Expand Classes > Select Person
  14. Rick click Person and select Properties
  15. Click Attribute Tab and click Add
  16. Select the Attribute “businessUnit” and click OK (on this step in my environment snap-in shows exception, but after I reopen MMC console it shows that changes were saved successfully)

Now you can specify business units for users in AD. Go to Start > Administrative Tools > Active Directory Users and Computers. Enable advanced features in View > Advance Features. Now if you click on some user account you will find “Attribute Editor” tab. In the attributes list you will find added attribute “businessUnit” (it will occur here after you added attribute to the Person class – see above). In order to specify some value for new attribute select it and click Edit, then enter new value in the Value field.

Ok, we created custom AD attribute. Now we need to map it on User Profile property in Sharepoint User Profile Service application. There is another useful article which you can start with: Mapping User Profile Properties in SharePoint 2010 to LDAP Attributes. Unfortunately for my case it didn’t work like described in the article. The main problem is that new custom attribute was not shown in User Profile properties mappings (Central Administration > Manage service applications > User Profile Service Application > Manage User Properties > New property > Add new mapping section > Attribute list). Mentioned post says that in this case you need to run PowerShell script which will map attribute:

   1: function MapAttribute([string]$url, [string]$fimProperty, [string]$spsProperty, [string]$connectionName)
   2: {
   3:     $site = Get-SPSite $url 
   4:  
   5:     if ($site) 
   6:         {Write-Host "Successfully obtained site reference!"} 
   7:     else 
   8:         {Write-Host "Failed to obtain site reference"} 
   9:  
  10:     $serviceContext = Get-SPServiceContext($site) 
  11:  
  12:     if ($serviceContext) 
  13:     {Write-Host "Successfully obtained service context!"} 
  14:     else 
  15:         {Write-Host "Failed to obtain service context"} 
  16:     $upManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($serviceContext) 
  17:  
  18:     if ($upManager) 
  19:         {Write-Host "Successfully obtained user profile manager!"} 
  20:     else 
  21:         {Write-Host "Failed to obtain user profile manager"} 
  22:     $synchConnection = $upManager.ConnectionManager[$connectionName] 
  23:  
  24:     if ($synchConnection) 
  25:         {Write-Host "Successfully obtained synchronization connection!"} 
  26:     else 
  27:         {Write-Host "Failed to obtain user synchronization connection!"} 
  28:  
  29:     Write-Host "Adding the attribute mapping..." 
  30:     $synchConnection.PropertyMapping.AddNewMapping([Microsoft.Office.Server.UserProfiles.ProfileType]::User, $spsProperty, $fimProperty) 
  31:     Write-Host "Done!"
  32: }

If you will put this script into “map.attribute.ps1” file, then you can call it like this:

   1: $thisDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent;
   2: . ($thisDir + '\map.attribute.ps1')
   3:  
   4: $url = "http://example.com" #URL of any site collection that is associated to the user profile service application. 
   5: $spsProperty = "BusinessUnit" #Internal name of the SharePoint user profile property 
   6: $fimProperty = "businessUnit" #Name of the attribute in FIM/LDAP source 
   7: $connectionName = "MyConnection" #Name of the SharePoint synchronization connection
   8:  
   9: MapAttribute $url $fimProperty $spsProperty $connectionName

When I ran this script on my environment, new attribute didn’t appear in the available mapping list in the User Profile properties. However didn’t try to map without it, so I decided to put it here also for reference (may be on your environment it will work). In my case in order to get it work (i.e. in order to display “businessUnit” attribute in mappings list) I needed to recreate User Profile Service Application synchronization connection:

  1. Go to Central Administration > Manage service applications > User Profile Service Application > Configure Synchronization Connection
  2. Delete existing connection (in script above it is called “MyConnection”) and create a new one with the same name
  3. Perform full profile synchronization: Central Administration > Manage service applications > User Profile Service Application > Start Profile Synchronization
  4. After full synchronization will be finished go to User Profile properties. Now you should see “businessUnit” attribute in the attributes list available for mapping. Create new property and map it to the custom AD attribute. Check “Indexed” checkbox – in this case it will be available for Sharepoint crawler.

This is all what I wanted to say about creation of custom AD attribute and its mapping to the User Profile property. Hope this information will help you in your work.

Update 2011-04-09: in the following post I show how you can customize People search and display custom AD attributes on search result page: Add custom AD attributes to People search results in Sharepoint.

4 comments:

  1. I was completed first 5 Steps completely.. aftet that “Create Attribute” was disabled(not in enabled mode).

    I cant able to create a new new attribute...

    ReplyDelete
  2. Rasa Kumar V.K,
    do you configure AD in your individual dev env (separate domain controller) or on the computer which is part of your company domain? In the 2nd case try to contact your system administrator - may be you have domain policies or restrictions which prevent do it.

    ReplyDelete
  3. Any idea how to cope with User Profile Categories? i.e. using that scripts works fine (thank you!) but puts newly mapped attributes under "Custom Properties". I want to keep it in place i.e. I have an existing attribute under 'Basic Information' category. Once mapped, the attribute appears under category "Custom Properties". Tried using Category\Property, but no joy.

    ReplyDelete
  4. jimmy, not sure. Try to investigate code of user profile properties page in some .Net decompiler and see how it categorizes attributes. May be it will help.

    ReplyDelete