Creating a custom attribute in AD

 

Although it has been described here, adding a custom attribute in an Active Directory can be intimidating, because it is an irreversible operation and documentation shows a full example which is not detailed step-by-step.

Scenario

In our very simple scenario, imagine you want to add a text string “CostCenter” to each user in the Active Directory so you can easily populate an accounting LOB application with it. You may do it an repeatable manner between your test and production environment, so you exclude the graphical tool for this.

For proper operation, you must be member of the schema admin group and operating on the domain controller which has the schema master role

Creating a Custom Attribute input file

Creating an AD Attribute basically needs three pieces of information to be known:

  • the name you want
  • the type of the attribute: will it be a string? a number?
  • the OID you will assign to this attribute

From a technical perspective, the name is easy, you can pick any set of letters, dashs and numbers you want. In an big enterprise environment, you may just face multiple meetings so every stakeholder has its word to say.

The type of attribute is in LDAP parlance the syntax you can find here. In most cases, you will use a string or a number.

The OID is a unique number written in a ASN.1 syntax; however you cannot choose all the numbers by yourself. Like for AD forest and domain names, where you’d better take names that your register and/or avoid names that also exist on the Internet a, you must use for OIDs numbers which are under a prefix you registered for your company or that Microsoft has reserved internally for such purposes.

Once you have gathered you can start to write a file. In our scenario, we will create a CostCenter string by using the following file:

  • OID has been generated by using the oidgen tool, and some numbers have been zeroed so you don’t take what the tool has generated for me
  • oMSyntax and attributeSyntax are set with the values for a string type
  • adminDescription is just a short help text
<pre class="lang:default decode:true" title="Creating a string CostCenter Attribute">dn: CN=costCenter,cn=schema,cn=configuration,dc=X
changetype: ntdsSchemaAdd
objectClass: top
objectClass: attributeSchema
cn: CostCenter
distinguishedName: CN=costCenter,cn=schema,cn=configuration,dc=X
instanceType: 4
attributeID: 1.2.840.113556.1.8000.2554.00000.00000.00000.00000.00000.0000000.000000.2.2
attributeSyntax: 2.5.5.4
isSingleValued: TRUE
showInAdvancedViewOnly: TRUE
adminDisplayName: costCenter
adminDescription: CostCenter As String
oMSyntax: 20
lDAPDisplayName: costCenter
name: costCenter
objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X

You may want to save this file as costcenter.ldf

Running a custom attribute creation command

The tool we’ll use is ldifde you may have used to dump existing data in the past. This time we will use the import feature.

As you may have seen in the previous snippet, nowhere we do specify the name of the forest we operate on. We will use the macro substitution feature of ldifde to replace the DC=X by the name of the forest.

<pre class="lang:default decode:true" title="Running the LDIFDE command to add an attribute">ldifde -i -f costcenter.ldf -c "cn=schema,cn=configuration,dc=X" "#schemaNamingContext"

Updating the schema with ldifde

Once the attribute is added, we may force the schema update forest-wide. For this, we will use ldifde again with a pseudo LDAP operation:

<pre class="lang:default decode:true " title="ldifde schema update script">dn: 
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-

Save this file as schemaupdate.ldf and run

<pre class="lang:default decode:true " title="Command to update schema with ldifde">ldifde -i -f schemaupdate.ldf

Possible Errors

If you obtain the error 0x202b with ldifde, it means that you didn’t run the command on the schema master. Either transfer the FSMO role on the machine you’re are on or launch the command again from there.

Adding the attribute to the user object

Once the attribute exists in the Active Directory, we will add it as an optional attribute of the user object. For this we will still use ldifde with the following file usercostcenter.ldf and command respectively.

<pre class="lang:default decode:true" title="Adding the CostCenter Attribute to the class user">dn: CN=User,CN=Schema,CN=Configuration,DC=X
changetype: modify
add: mayContain
mayContain: CostCenter
-
<pre class="lang:default decode:true" title="Running the LDIFDE command to add an optional attribute to a class ">ldifde -i -f usercostcenter.ldf -c "cn=schema,cn=configuration,dc=X" "#schemaNamingContext"

Do not forget to force the schema update once more.