MIIS/ILM Code Experiment: Generic AD/ADAM Provisioning Function

Here is a fairly simple function to provision a user in Active Directory or ADAM and can be used interchangably so long as ADAM uses the object class "user" 

 

This function is making the assumption that your design will determine the RDN, the LDAP container/OU that the object will sit and the string name of the management agent you are provisioning to. 

 

/*

* ProvisionLDAPUser - Generic Provisioning function

* mventry is the affected metaverse entry

* MAName is the name of the Destination Management Agent

* rdn is the formatted relative name (ex: CN=John Smith or CN=Smith, John)

* container is the formatted destination container (ex: OU=Sales,OU=East,DC=northamerica,DC=fabrikam,DC=com)

*

*/

private void ProvisionLDAPUser(MVEntry mventry, string MAName, string rdn, string container)

{

ConnectedMA ldapMA = mventry.ConnectedMAs[MAName];

        if (ldapMA.Connectors.Count == 0)//make sure we don't have any pre-existing connectors

{

CSEntry cseLDAP = ldapMA.Connectors.StartNewConnector(

"user");//generically start a new user

cseLDAP.DN = ldapMA.EscapeDNComponent(rdn).Concat(container);//Concatenate the RDN and Container, ensuring proper formatting

                cseLDAP.CommitNewConnector();//Commit the new connector

        }

}

 

 If you wanted to, you could bring the predetermination of the user object type out of the function, in case you wanted to bring the logic for the determination of object (ex: user vs. contact)

private void ProvisionLDAP(MVEntry mventry, string MAName, string rdn, string container, string objectType)

{

        ConnectedMA ldapMA = mventry.ConnectedMAs[MAName];

        if (ldapMA.Connectors.Count == 0)//make sure we don't have any pre-existing connectors

        {

                CSEntry cseLDAP = ldapMA.Connectors.StartNewConnector(objectType);//generically start a new object

                cseLDAP.DN = ldapMA.EscapeDNComponent(rdn).Concat(container);//Concatenate the RDN and Container, ensuring proper formatting

                cseLDAP.CommitNewConnector();//Commit the new connector

        }

}

 There isn't any error handling on CommitNewConnector, for handling duplicates or incorrect/missing container (OU).  I like to handle outside of this function as I predetermine the rdn variable and container and if there is a caught error, I can handle it accordingly

 

try

{

ProvisionLDAPUser(mventry,

"Test Active Directory", String.Concat("CN=", mventry["displayName"].Value), "OU=Exchange Users,DC=test,DC=fabrikam,DC=com" );

 }

catch (ObjectAlreadyExistsException)

...

 

}

 

This is helpful if there is a conflict on naming.  Notice in my case, the RDN is the string literal "CN=" and the displayName attribute.  I can ensure some uniqueness in the creation of that displayName attribute and not have to worry about ObjectAlreadyExistsException.  If I don't, I can append an integer value or maybe use another attribute to append to the constructed RDN to ensure uniqueness. 

 More to come on this concept.

--Shawn

This posting is provided "AS IS" with no warranties, and confers no rights.

And Just in case...

This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and distribute the object code form of the Sample Code, provided that You agree: (i) to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; (ii) to include a valid copyright notice on Your software product in which the Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise or result from the use or distribution of the Sample Code.

Comments

  • Anonymous
    February 05, 2009
    Hi, what if there is an object in CS which is not a connector? Is such case ldapMA.Connectors.Count also quals zero...

  • Anonymous
    December 23, 2009
    Hello there!  The initial time CommitNewConnector() is called, the object is commited to the connector space it is provisioned into, however it is not officially a connector until it is Exported into the Data Source and confirmed via Import.  So until the Export+Import are run, the ldapMA.Connectors.Count will be zero.   --Shawn This posting is provided "AS IS" with no warranties, and confers no rights.