MIIS/ILM Code Experiment: Populating the Manager field in Active Directory

Hello again.  This post focuses on the manager attribute in Active Directory and using ILM to populate the field.  The manager attribute is a reference value.  So simply populating the name of the manager or some unique identifier is not enough.  Also, how do we know what manager goes with what person?  Well, without manual population I'd hope that ERP or a similar data source would provide the employeeID or an attribute like managerID that was a pointer back to the employeeID of the employee's manager.  Ideally the ERP would provide the manager field as a reference and you could flow the reference in directly, but in some scenarios you just can't get what you want.  This is a way to do it.  I don't claim that it is the best way, but this is an easy way.  

Why is the manager field important?  In Active Directory Users and Computers, it helps with the Organization tab on the user properties.  In populating a user's manager field, you also indirectly populate the manager's Direct Reports field.  This also helps enhance the Exchange GAL. 

This sample relies on having an employeeID that is unique for the enterprise and a managerID coming from somewhere.  I've also seen an attribute named similar to reportsTo used instead of managerID.    Two metaverse attributes need to be created managerID and adDN.  The managerID attribute would be flowed in from the ERP source and the adDN attribute would be a 1-1 mapping of the DN attribute in Active Directory.  We would set this in the MapAttributesForExport() function.  It relies on the manager having a correct, unique employee ID and looks back at the metaverse to see if the manager has an adDN attribute.  If the manager doesn't exist yet, the logic below will quietly fail.  The following attribute flows are:

ERP<----->MV<----->AD

ERP.person:managerID---(1-1 mapping)-->MV.person:managerID

MV.person:adDN<---(1-1 mapping)---AD.user: <dn>

MV.person:adDN(of the manager),managerID---> (rules extension mapping) --->AD.user:manager

Here is the rules extension of the Export Flow rule for populating AD.user:manager

 

                case "cd.user:manager<-mv.person:adDN,managerID":

                    if (mventry["managerID"].IsPresent)

                    {

                        MVEntry[] mveManager;

                        mveManager = Utils.FindMVEntries("employeeID", mventry["managerID"].Value); //performs a search

                        //on the managerID or reportsTo field coming in from ERP for entries with that corresponding employeeID

 

       if (mveManager.Length == 1)//if we get only one return (which we should)

                        {

                            if (mveManager[0]["adDN"].IsPresent)//if there is the DN on that return

                            {

         csentry["manager"].Value = mveManager[0]["adDN"].Value; //set the DN as the manager

                                break;

                            }

                          else

                            {

                 break;//dn may not be populated yet - it will occur on the next run

                            }

                        }

                       else

                        {

                            break;//should never happen (employeeID is unique)- we'll fall through if it does

                        }

 

                    }

                    else

                    {

                        break;

                    }

 

This method also works with a Secretary attribute.  You just need a secretaryID or similar and we reuse the adDN attribute.  WARNING!! FindMVEntries() does a search of the metaverse.  Make sure the attribute you are searching for is indexed in the metaverse.  In this case employeeID would need to be indexed. 

What if there is not a unique ID like employee ID?  You'll have to replace the trivial FindMVEntries backward lookup with logic similar to join rules for a manager.   Hopefully your ERP data provides enough to show who a person's manager is. 

Have a good day!

 

--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.