|
|
You can verify the accuracy of the created attributes and classes by using either the Active Directory Schema Manager or ADSI Edit snap-ins. Make sure that the tools are connected to the Schema Master. Do not forget to reload or refresh the schema if these tools have been opened before a creation operation.
Note | Remember that the Active Directory Schema Manager snap-in, when it starts, always connects to the Schema FSMO operation master. |
To understand the entire procedure of extending the schema and its requirements and restrictions better, you may first create a sample attribute or class interactively by using the features of the Active Directory Schema Manager snap-in (see Chapter 7, "Domain Manipulation Tools"). It is possible also to use the ADSI Edit snap-in, but this tool is not as straightforward as the aforementioned snap-in.
The following script creates a new string attribute. All defined properties except adminDescription are mandatory. Notice that this script always connects to the Schema Master!
Listing 17.25. newAttribute.vbs — Creating a New String Attribute in the Schema
Dim objSchema 'As IADsContainer Dim objRoot 'As IADs Dim objNewAttr 'As IADs Dim strl 'As String Dim strSchema 'As String ' Retrieve the Schema context: Set objRoot = GetObject ("LDAP: //RootDSE") strSchema = objRoot.Get ("schemaNamingContext") ' Bind to the Schema context: Set objSchema = GetObject ("LDAP: //" + strSchema) ' Find the Schema Master: str1 = objSchema.Get ("fSMORoleOwner") Set objRoot = GetObject ("LDAP: //" + strl) str1 = objRoot.Parent Set objRoot = GetObject (strl) ' Get the DNS name of the Schema Master: str1 = objRoot.Get ("dNSHostName") ' Bind to the Schema context on the Schema Master: Set objSchema = GetObject("LDAP://" + strl + "/" + strSchema) objSchema.GetInfo ' Create the attribute object: Set objNewAttr = objSchema. Create ("attributeSchema", _ "cn=My-Corp-TEST-String-Attribute") objNewAttr.Put "cn", "My-Corp-TEST-String-Attribute" objNewAttr.Put "lDAPDisplayName", "myCorp-TEST-StringAttribute" objNewAttr.Put "attributeID", "1.2.840.113556.1.4.7000. ... .1" objNewAttr.Put "attributeSyntax", "2.5.5.12" objNewAttr.Put "oMSyntax", 64 objNewAttr.Put "isSingleValued", True objNewAttr.Put "adminDescription", "My test attribute" On Error Resume Next ' Commit the changes: objNewAttr.SetInfo If Hex(Err.Number) = 0 Then WScript.Echo "The attribute has been successfully created!" ElseIf Hex (Err.Number) = "80072035" Then WScript.Echo "Error (LDAP_UNWILLING _TO_PERFORM) " ElseIf Hex (Err.Number) = "80071392" Then WScript.Echo "Error (LDAP_ALREADY_EXIST)" Else WScript.Echo "Error:" + Hex (Err.Number) End If Set objSchema = Nothing Set objRoot = Nothing Set objNewAttr = Nothing
When a new attribute has been created, how will you use it? In order to do so, you must perform one more step in extending the schema: add the new attribute to an existing class. (It either can be a standard or newly created class.) The Active Directory Schema Manger snap-in is the best tool for this purpose.
Open the Class folder in the snap-in's window and find the class you want to extend. Suppose we choose the user class.
Open the Properties window and select the Attributes tab (Fig. 17.3).
Fig. 17.3: In this window, you can view mandatory and view/add optional attributes of an object class
Click Add and choose a new attribute in the Select Schema Object window (multiple selection is not possible). Click OK.
Until you click Apply, you can remove the attributes that have been added incorrectly. When the selection is done, click Apply and close the window.
Point to the root in the tree pane and select Reload the Schema to write the changes from the memory cache to disk.
Now you can open the Properties window for a user in the ADSI Edit snap-in and verify whether the new attribute(s) has appeared in the list of optional properties. Either this snap-in or a custom script can be used for setting the values of that attribute.
The script presented below creates a structural class inherited from — and is a subclass of — the Person abstract class. Objects of a new class can be created (instantiated) in organizational units (the possible superiors). The mustContain, defaultSecurityDescriptor, and adminDescription properties are not mandatory in this case. (Remember that an object of a class always inherits all attributes of both its own class and parent classes.)
Listing 17.26. newClass.vbs — Creating a New Structural Class
Dim objSchema 'As IADsContainer Dim objRoot 'As IADs Dim objNewAttr 'As IADs Dim strl 'As String Dim strSchema 'As String ' Retrieve the Schema context: Set objRoot = Getobject ("LDAP: //RootDSE") strSchema = objRoot. Get ("schemaNamingContext") ' Bind to the Schema context: Set objSchema = GetObject ("LDAP: //" + strSchema) ' Find the Schema Master: str1 = objSchema. Get ("fSMORoleOwner") Set objRoot = GetObject ("LDAP: //" + strl) str1 = objRoot.Parent Set objRoot = GetObject (strl) ' Get the DNS name of the Schema Master: str1 = objRoot.Get ("dNSHostName") ' Bind to the Schema context on the Schema Master: Set objSchema = GetObject("LDAP://" + strl + "/" + strSchema) objSchema.GetInfo ' Create a class object: Set objNewClass = objSchema.Create ("classSchema", _ "CN=MyCorp-TEST-My-Class") objNewClass. Put "cn", "MyCorp-TEST-My-Class" objNewClass. Put "lDAPDisplayName", "myCorp-TEST-MyClass" objNewClass. Put "governsID", "1.2.840.113556.1.5.7000. ... .1" ' 1 = ADS_CLASS_CATEGORY_STRUCTURAL objNewClass. Put "objectClassCategory", 1 ' 3 = ADS_PROPERTY_APPEND objNewClass. PutEx 3, "possSuperiors", Array ("organizationalUnit") objNewClass. Put "subClassOf", "2.5.6.6" 'Person objNewClass. PutEx 3, "mustContain", Array ("name", "description") objNewClass. Put "defaultSecurityDescriptor", _ "D: (A;;RPWPCRCCDCLCLOLORCWOWDSDDTDTSW;;;DA)" + _ "(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY) (A;;RPLCLORC;;;AU)" objNewClass. Put "adminDescription", "My test class" ' Commit the changes: On Error Resume Next objNewClass.SetInfo If Hex(Err.Number) = 0 Then WScript.Echo "The class has been successfully created!" ElseIf Hex (Err.Number) = "80072035" Then WScript.Echo "Error (LDAP_UNWILLING_TO_PERFORM)" ElseIf Hex (Err.Number) = "80072032" Then WScript.Echo "Error (LDAP_INVALID_DN_SYNTAX)" ElseIf Hex (Err.Number) = "80071392" Then WScript.Echo "Error (LDAP_ALREADY_EXIST) " Else WScript.Echo "Error:" + Hex (Err.Number) End If Set objSchema = Nothing Set objRootDSE = Nothing Set objNewClass = Nothing
To configure the defaultSecurityDescriptor property, use the Security Descriptor Definition Language (SDDL) (see the Platform SDK) or use the default value shown in the listing. This security descriptor provides the following default (i.e., directly defined, not inherited) permissions on objects of the new class:
Authenticated Users — Read
Domain Admins — Full Control
System — Full Control
Usually, you can only create objects of a custom class by using either the ADSI Edit snap-in or a script. For our sample class, the procedure will be the following:
Open the ADSI Edit snap-in and select an OU (since the only superior of the sample class is organizationalunit), where the new object will be created.
Click New | Object on the context or Action menu. Select the class from the list (Fig. 17.4).
Fig. 17.4: You can create objects of any class listed in this window
Enter the name of the new object and the values of all mandatory attributes (directly defined or inherited). You may also click More Attributes and define the values of necessary optional attributes.
Click Finish. The new object of the selected class will be created. Check its type (myCorp-TEST-MyClass) in the Class column.
You can also make possible adding objects of a custom class through the UI of the Active Directory Users and Computers snap-in. See details in the "ADSI Edit Snap-in" section (Example 2) of Chapter 7, "Domain Manipulation Tools." (You might need to restart administrative snap-ins if you have made any schema changes concerning appearance of objects in the UI.)
|
|