Active Directory / ADAM provisioning can be tricky (and same may apply to other LDAP directories) when you attempt to provision objects using potentially non-unique things like names, surnames or object descriptions (such as “CN=John Smith”).

There are a few things you need to consider for best results and less errors during bulk provisioning:

  • RDNs have to be unique within the same container. If you have two “CN=John Smith” to get provisioned to the same container, you need to generate some sort of tie braker to rename one of them. In ILM Developer Reference there is a sample code snippet that shows how to handle this situation, by building an initial DN for the object, attempt to commit the connector, and if you get ObjectAlreadyExistsException then try to build an alternative DN using RDN with suffixes.
  • RDN is limited to 64 characters. You can extend this length (using ADSIEdit MMC to inspect the schema and changing the rangeUpper attribute value), but I would rather not change this particular length as other Windows components may have problems if you do so. Therefore, when building your RDN for provisioning, you will have check its length and shorten it if needed. If you apply the suffixing technique for RDNs, consider that when a collision occurs and you add a suffix, you may be hitting the 64 limit just by the suffix length, so another length to check :).
  • Accented RDNs generate collisions. If you provision “CN=John Müller” in a given container, trying to provision “CN=John Muller” works in your provisioning code (no ObjectAlreadyExistsException raises), but you will get export errors because the object already exists. So you may need some normalization.
  • RDN renames. If, like I do sometimes, your provisioning logic uses some kind of OU assignment (ie. based on countries, departments, business units and such), and your “CN=John Smith – johnd” (because you decided to use uid as suffix for example) moves away from the same OU where “CN=John Smith” lives, now both objects could be named “CN=John Smith” without collisions, so you may apply the same RDN building logic both on Connectors.Count==0 and Connectors.Count==1 (to apply RDN renames). Also same checks are needed.
  • Provisioining in containers. When the provisioning logic has to “calculate” the AD OU, I normally assume that the OU has being previously created in AD/ADAM from a given data source (i.e. a Departments MA). However, you may find that the “Departments Table” does not contain your “DeptXYZ”, while your “Users Table” says that “John Smith” is in “DeptXYZ”. In this case, your provisioning logic will attempt to create the object in a non-existing OU, so it will raise a MissingParentObjectException. So to handle this, your provisioning logic will need to catch both ObjectAlreadyExistsException (to change the RDN) and MissingParentObjectException (to change the “calculated” container with a default provisoining container). And again, the same logic needs to be included both with 0 or 1 connectors, to apply a proper "OU move” whenever the OU comes into your AD MA.
  • sAMAccountName. This is another fighting element. This attribute has to be unique across a given domain, and has characters and length restrictions. If you build this attribute based on names and surnames, you will have to apply normalization (again, jmüller and jmuller are considered the same user), length checks (max. is 20 characters) and characters validations so your provisioning logic works fine. I was not able to find detailed technical information, but these are some invalid characters and conditions:
    • It accepts unicode characters, but accented characters generate collisions. So you can provision jmüller today and if tomorrow you try to provision jmuller, you will get a collision. So better normalize your sAMAccountNames.
    • The same sAMAccountName is valid across multiple domains (while better to avoid migration/consolidation issues later). This point leads to handling sAMAccountName uniqueness, but that is another story.
    • These characters are invalid: \/:*?\"<>|=;
    • Blanks (space) are allowed.
    • The sAMAccountName cannot end with . (dot, full stop, period).
  • mailNickname. If you happen to provision Exchange mailboxes too, mailNickname is another interesting attribute. Again, if you build this attribute based on names and surnames, you will have to apply normalization, length and characters validations so your provisioning logic works fine. This attribute has to conform the following:
    • Ensure contains only format and lengh (up to 64)
    • May use any of these ASCII characters:
      • Uppercase and lowercase English letters (a-z, A-Z)
      • Digits 0 through 9
      • Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~
      • Character . (dot, period, full stop), provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively.
    • mailNickname uniqueness is important too. While it does not have to be unique by itself as sAMAccountName, it is used by Exchange to build the primary SMTP address. So it is very likely that you get SMTP address collisions if you have repeated mailNickname values. Again, uniqueness story here :)