(2014-07-16) Active Directory Schema Deactivations (Defunct)
Posted by Jorge on 2014-07-16
When thinking about adjusting the AD schema (also applies to the ADLDS schema) you can categorize those adjustments into the following categories:
The most common schema adjustment is a schema extension. With a schema extension, new attribute and object class definitions are added to the schema, to be able to store data with specific requirements. A schema extension is easier and has a lower impact as it does not affect existing applications. However, it does have higher risk, as schema extensions cannot be undone. It must be done correctly the first time. TEST!
Schema modifications are less common than schema extensions. Changing, the schema definition of either object classes or attributes can adversely affect the application(s) using those definitions. For example, if an application expects to find specific information about all users in the enterprise by querying a GC, the application will be negatively impacted if the corresponding attributes are suddenly configured not to replicate to GCs. However, depending on the type of change, it can positively improve the functioning of application(s). For example, if one or more applications are using one or more specific attributes in queries and those attributes are not (yet) indexed, configuring those attributes to be indexed will improve the performance of those applications. Any change of any kind to existing schema definitions must carefully be evaluated and tested to fully understand all the consequences! TEST!
It is not possible to delete schema definitions. However, when running at least W2K3 DCs, it is possible to deactivate schema definitions (attributes and object classes) if those are not required anymore. Are you even running at least forest functional level "Windows Server 2003", then you will be able to reuse the object identifier (governsId and attributeId values), the ldapDisplayName, and the schemaIdGUID that were associated with the defunct attribute or object class. This allows you to redefine the schema definition if it was mistakenly added to the schema.
Only custom schema definitions (non-default AD) can be deactivated. It is not possible to deactivate default AD schema definitions. To be able to deactivate an attribute, the attribute must not be defined on any active object class in any way (mayContain, mustContain, systemMayContain, systemMustContain, rDNAttId). To be able to deactivate an object class, the object class must not be defined on any other active object class in any way (auxiliaryClass, possSuperiors, systemAuxiliaryClass, systemPossSuperiors, subClassOf).
When an attribute or object class is deactivated, the corresponding data stored in AD is not removed automatically. Although data can be deleted afterwards, it is preferred to remove it manually prior to the deactivation as it cannot be edited (except deletion) anymore afterwards. Therefore, before deactivating an attribute, make sure to clear all attribute values on any object using that attribute. When deactivating an abstract or auxiliary object class, make sure to also clear all attribute values on any object using that abstract or auxiliary object class, and when also those attributes are not used in another object class in any way. When deactivating an structural object class, make sure to delete all instances of that object class from the directory service.
For additional information about adjusting the AD schema, please see:
In this blog post I’m going to focus on schema deactivations, and the effects when querying for information.
In any of three articles, available through the links above, you will read something similar to:
Effects of deactivating a schema object on schema updates
After a class salesUser is deactivated, any subsequent addition or modification of instances of salesUser fails as if salesUser has been deleted from the system; the same error codes are returned as if salesUser never existed at all. For example, creating a new instance of salesUser fails, and trying to modify or rename an existing instance of salesUser fails. Similarly, if an attribute hasPager is deactivated, hasPager is treated as nonexistent for new object creations, and attempting to modify (add or replace) the value of hasPager in an existing object fails.
However, you can still search for and delete existing instances of deactivated schema objects. For example, you can still search for all existing instances of salesUser and delete them, if necessary. Note that what you are doing is searching for and deleting objects that were created in the directory using the deactivated class, salesUser, not deleting the actual class definition from the schema. Similarly, you can search for all instances that have a value for the attribute hasPager and delete hasPager from the existing objects. This facilitates cleanup after a schema object is deactivated. If you decide that a class is not needed anymore, you can deactivate it so that no one can use it for any modifications. You can then clean up the existing instances of the class by searching for all instances and deleting them. Active Directory does not perform any automatic cleanup of data instances after a schema object is deactivated.
Similarly, you can deactivate an attribute and clean up all its instances. Note that, for a deactivated attribute, you can delete only the entire attribute from an object, not certain values of the attribute. For example, if hasPager is a multivalue attribute and an object has more than one value for hasPager, you cannot delete only one value of hasPager from the object.
I do not fully agree with the statements above! And….I’m going to explain WHY! Keep reading as I’m going to use examples.
I extend the AD schema with:
- An attribute called "xTRAOccupation" and configured it on the user objectClass
- An objectClass called "car" and configured it with attributes already existing in AD
See the schema definitions below…
Figure 1: AD Schema Extended With New Attribute Called "xTRAOccupation"
Figure 2: AD Schema Extended With New Object Class Called "car"
Querying AD for all instances of the "user" objectClass with any value in the new attribute definition, results in….
Figure 3: All Instances Of The "user" Object Class With Any Value In The New Attribute Called "xTRAOccupation" (8 Objects)
Querying AD for all instances of the "car" objectClass, results in….
Figure 4: All Instances Of The "car" Object Class (2 Objects)
Now lets start and deactivate the newly created "car" objectClass, by setting isDefunct to TRUE, refresh/reload the AD schema and then perform the same query as shown in figure 4.
Now, querying AD for all instances of the "car" objectClass, results in….
Figure 5: All Instances Of The "car" Object Class After Deactivation (0 Objects)
The objectClass has been deactivated, so you cannot query AD anymore for its name. The only way to query for those instances is to not use the the lDAPDisplayName, but rather use the OID defined in the "governsID" attribute (see figure 2). Combining ADFIND with ADMOD to delete the instances found will succeed. Of course you can use any other tool/script to perform the same actions
Figure 6: All Instances Of The "car" Object Class After Deactivation (Using The OID Instead Of The lDAPDisplayName) (2 Objects)
Now lets start and deactivate the newly created "xTRAOccupation" attribute, by setting isDefunct to TRUE, refresh/reload the AD schema and then perform the same query as shown in figure 3.
Now, querying AD for all instances of the "user" objectClass with any value in the "xTRAOccupation" attribute definition, results in….
Figure 7: All Instances Of The "user" Object Class With Any Value In The Deactivated "xTRAOccupation" Attribute (0 Objects)
Although the existing instances of the "user" objectClass have the data/values in the attribute "xTRAOccupation", you cannot query AD for that attribute because it has been unassociated from the "user" objectClass, which was a requirement to be able to deactivate the attribute.
So, the moral of the story here is:
- Clean up your data of attributes to be deactivated BEFORE deactivating the corresponding attributes!!!
- Clean up your data of objectClasses to be deactivated BEFORE deactivating the corresponding objectClasses by using the lDAPDisplayName of the objectClass in the query OR clean up your data of objectClasses to be deactivated AFTER deactivating the corresponding objectClasses by using the OID of the deactivated objectClass in the AD query!!!
Figure 8: Deleting All Instances Of The "car" Object Class Using The OID Of The Deactivated Object Class IN The AD Query
Querying for the deleted objects that have a deactivated objectClass….
Figure 9: Querying All Deleted Instances Of The "car" Object Class Using The OID Of The Deactivated Object Class In The AD Query
Now….lets say I want to reanimate the deleted object instances of the deactivated objectClass. Is that possible? No, because the objectClass is deactivated it cannot be reused again! See below!
Figure 10: Reanimating All Instances Of The "car" Object Class Using The OID Of The Deactivated Object Class IN The AD Query
After reactivating the objectClass called "car" by configuring the attribute isDefunct to <NOT SET>, refreshing/reloading the AD schema and then trying the undelete, results in…
Figure 11: Reanimating All Instances Of The "car" Object Class Using The lDAPDisplayName Of The Reactivated Object Class In The AD Query
NOTE: You could also have used the OID of the reactivated objectClass in the AD query!
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/
############### Jorge’s Quest For Knowledge #############
######### http://JorgeQuestForKnowledge.wordpress.com/ ########