Monday, March 19, 2012

Querying Active Directory from a CRM 2011 Form

Technorati Tags: ,,

How do you query Active Directory from a CRM 2011 form? The typical scenario is this. The user enters the username of a domain user. The system has to validate if the username is a valid AD user and respond appropriately.

My first instinct was to write a javascript web resource that connected to Active Directory and did the necessary checks. But on second thoughts, I recollected that Dynamics CRM did something similar when you add a user. I wanted to re-use as much of the code in CRM as possible and decided to check out how it was done in the New User form.

IE Developer toolbar was my best friend for this. I opened up the new user form in CRM 2011 and found the id of the user name field.


The next step was to search in the scripts what function was firing on domain name change.


After due validations, the function was instantiating a RemoteCommand object and making a call using that object to get the user properties.

The remote command is an object in the Global.ashx handler and luckily, this handler is loaded on every CRM form. Once I had made that assertion, it was a matter of writing the javascript to pass in the value from the field in my form and doing the same checks as the CRM script.

My code looks something like this

   1:       var oCommand=new RemoteCommand("UserManager","RetrieveADUserProperties");
   2:       if(oCommand!=null)
   3:        {
   4:                oCommand.SetParameter("domainAccountName",userName);
   5:                var oResult=oCommand.Execute();
   6:                if(oResult.Success&&!IsNull(oResult.ReturnValue)&&oResult.ReturnValue.length>0)
   7:                {
   8:                      var firstName = "";
   9:                      var lastName ="";    
  10:                      for(var oUserXmlDoc=loadXmlDocument(oResult.ReturnValue),oNodeList=oUserXmlDoc.documentElement.childNodes,i=0;i<oNodeList.length;i++)
  11:                      {
  12:                           var oNode=oNodeList.item(i);
  13:                           if (oNode.tagName == "firstname")
  14:                           {
  15:                                firstName = oNode.text;
  16:                           }
  17:                          else if(oNode.tagName == "lastname")
  18:                          {
  19:                                lastName = oNode.text;
  20:                          }
  21:              }
  22:                 }
  23:           }    

I use the RemoteCommand I discussed earlier and pass the username in question as a parameter. The return from the function is an XML with the properties of the AD User. The name of the property is the tag of the node. So I check for the properties I want and get the text of the node. As simple as that!!

Why do I like this approach? Because as a developer, I don’t have to be worried about which AD instance to connect and the permissions to connect to the AD from my code. CRM does most of the heavy lifting for me. I don’t have to worry about security or exposing my AD credentials.

This approach is not without its own pitfall. This approach doesn’t work if you want to invoke this from within a HTML web resource. Since a HTML web resource is always contained with an IFrame calling the CRM methods becomes  a challenge.