Active Directory Programming Guide - Part 1 (Modifying User Attributes)
There are probably occasions where you want to modify Active Directory properties
for existing accounts using a script. The following code demonstrates this process.
set objUser = getobject("LDAP://cn=test.3,cn=users,dc=wisesoft,dc=co,dc=uk")
objUser.put "displayName", "Test User Account"
objUser.setinfo |
The first line binds to the user object. "LDAP://" is the name of the provider and
the following text is the users distinguished name (DN). The distinguished name
comprises of the users common-name (CN) and the full path where the user object
resides in the directory. e.g.
CN=Test.3,CN=Users,DC=WiseSoft,DC=CO,DC=UK
Note: CN=Users is the default users container. An organizational unit is specified
as OU=OUName. In this case the domain name is wisesoft.co.uk, so the final part
of the string is DC=WiseSoft,DC=CO,DC=UK. DC stands for domain component.
If you get stuck finding a distinguished name for an object, a utility called ADSIEdit
will come in handy. Install the support tools from your Windows Server CD. ADSIEdit
looks similar to Active Directory Users and Computers. When you find the object
in ADSIEdit, the Distinguished Name will be listed in the display.
You might also want to build the DN dynamically from the Username. The username
(sAMAccountName) is unique throughout the domain, so you could easily write a query
to return the distinguished name of a user.
Click here for sample code.
You might also want to run a query and change
the properties of multiple user accounts in Active Directory - maybe to conform
to a company naming policy. For example, you might want the displayName property
to be changed to "<Surname>, <FirstName>" to conform to a company naming
policy. Equally, you might be writing a script to create new user accounts and simply
be wanting to set various properties for those user accounts.
Click here for sample code. In part 1 of this guide, I simply want to focus
on modifying the properties of user accounts.
The second line of code modifies the property. In this case we are modifying the
displayName property of the account. This is a single-valued attribute, and all
other single-valued attributes can be modified in much the same way, provided you
know the name of the attribute. Finding the name of the attribute can sometimes
be the hard part as they don't always correspond to the friendly names in Active
Directory Users and Computers. For Example, Last Name is actually
sn (for surname). Some are even more obscure - City
is defined simply as as l (L) .
Luckily I have an
Active Directory Schema Guide
on my website that will identify most the names for you as well as providing sample
code. Simply hover the mouse over the property to display a tool tip with the "real"
name. Click to view the sample code. Click the tabs at the top as you would normally
to move between the property pages.
Great, but what if you want to find the name for yourself? ADSIEdit comes in very
handy for this purpose. Find a test user account in active directory users and computers.
Enter a value into the property you are trying to identify. You will look for this
value in ADSIEdit to help you find the name of the attribute. Open ADSIEdit and
find the same user object. Right-click and select properties. Select "Show only
attributes that have values" to make the search easier. Search for the value entered
in the value column.
For example - I want to find the "real" name of the office field in the general
page of Active Directory Users and Computers. I locate my test user account in ADU&C
and modify the office property to "Office - adsi find". I apply the changes. I open
ADSIEdit and locate the same user account. I check the "Show only attributes that
have values" checkbox. I search the list for the entry with "Office - adsi find"
in the value column. From the screen print below you can see I have located it and
the real attribute name for office is physicalDeliveryOfficeName.
User as displayed in ADU&C:

User as displayed in ADSIEdit:
A word of warning - some properties in Active Directory Users and Computers are
stored in the same format as you entered the data in Active Directory Users and
Computers. This can be a little frustrating when looking for the attribute
you modified in ADSIEdit.
For example, all properties on the "Terminal Services Profile" tab are encoded in
a "userParametes" attribute. Fortunately, you don't need to decode the "userParameters"
attribute as the update functionality has been built-in to the IADsUser interface.
This allows us to use the following code:
<<<< Bind to the user object using the distinguished name >>>>
set objUser = getobject("LDAP://cn=test.3,cn=users,dc=wisesoft,dc=co,dc=uk")
objUser.TerminalServicesProfilePath="\\server\profile"
objUser.setinfo |
We could also have used similar code to update the displayName property:
set objUser = getobject("LDAP://cn=test.3,cn=users,dc=wisesoft,dc=co,dc=uk")
objUser.displayName = "Test User Account"
objUser.setinfo |
If we want to modify a property that has not been included in the IADsUser interface
(for example, the schema is extended), we must use the "put" method. In other cases,
the IADsUser interface can help simplify updates.
I recommend using my
Schema Guide
to find
the necessary code. The Microsoft Technet Script Center and google groups are also
an excellent source of information.
Multi-Valued Properties
Some properties in active directory are multi-valued. For example, telephoneNumber
is a single-valued attribute as it allows you to store a single telephoneNumber.
The otherTelephoneNumber attribute is multi-valued and it allows you to store an
infinite number of alternate telephone numbers.
Attributes are typically multi-valued when they enable you to store more than one
value. This is not always the case though - an exception to this rule is the userWorkstations
attribute. This attribute allows you to specify which workstations a user can logon
to. Although you would expect this to be a multi-valued attribute, it is actually
a single valued attribute. Multiple workstations are separated by commas and stored
as a string. Also, the description attribute looks like a single-valued attribute,
but it's actually a multi-valued attribute. (Mostly it's treated as a single valued
attribute)
If you want to find if an attribute is single or multi-valued, you can use the schema
snap-in, ADSIEdit or the following script.
ldapName = inputbox("Please enter the name of the attribute")
if ldapName = "" then wscript.quit
set objAttribute = GetObject("LDAP://" & ldapName & ",schema")
if objAttribute.MultiValued then
wscript.echo ldapName & " is a multivalued attribute"
else
wscript.echo ldapName & " is a singlevalued attribute"
end if
|
The script will prompt you for the name of the attribute and report is the attribute
is single or multi-valued.
Writing a script to modify a multi-valued attribute requires the use of the PutEx
function. This is demonstrated in the code below
Const ADS_PROPERTY_APPEND = 3
'<<<< Bind to the user object using the distinguished name >>>>
set objUser = getobject("LDAP://cn=test.3,cn=users,dc=wisesoft,dc=co,dc=uk")
'<<<< Add Values - APPEND will keep existing values >>>>
objUser.PutEx ADS_PROPERTY_APPEND, "otherTelephone", Array("5555","5567")
'<<<< Save the changes >>>>
objUser.setinfo |
The ADS_PROPERTY_APPEND constant is used to preserve existing items, whilst adding
the new items to the property. You can use the following constants to control the
behavior of the update:
Const ADS_PROPERTY_CLEAR = 1
Const ADS_PROPERTY_UPDATE = 2
Const ADS_PROPERTY_APPEND = 3
Const ADS_PROPERTY_DELETE = 4
ADS_PROPERTY_CLEAR is used to clear all the values from a multi-valued property
and can also be used to clear values from a single valued property. This is important
as you might want to set a property to null (nothing). You cannot pass an empty
string to the put method to clear a property.
|
'<<<< Does not Work ! >>>>
objUser.Put "displayName", ""
objUser.setinfo
|
To clear a property, use the following syntax:
|
Const ADS_PROPERTY_CLEAR = 1
'<<<< Bind to the user object using the distinguished name >>>>
set objUser = getobject("LDAP://cn=test.3,cn=users,dc=wisesoft,dc=co,dc=uk")
objUser.PutEx Const ADS_PROPERTY_CLEAR, "displayName", 0
objUser.setinfo
|
The ADS_PROPERTY_UPDATE constant can be used instead of ADS_PROPERTY_APPEND to replace
all values in the property with the the values specified. For example if you used
the code below to update the property, any existing telephone numbers would be replaced
by the two telephone numbers specified in the script.
|
Const ADS_PROPERTY_UPDATE = 2
'<<<< Bind to the user object using the distinguished name >>>>
set objUser = getobject("LDAP://cn=test.3,cn=users,dc=wisesoft,dc=co,dc=uk")
objUser.PutEx ADS_PROPERTY_UPDATE, "otherTelephone", Array("5555","5567")
objUser.setinfo
|
Finally we come to the ADS_PROPERTY_DELETE constant. This is used to remove specific
values from a multi-valued property. For example you might want to remove a specific
telephone number from the otherTelephone property. You can do this using the following
code:
|
Const ADS_PROPERTY_DELETE = 4
'<<<< Bind to the user object using the distinguished name >>>>
set objUser = getobject("LDAP://cn=test.3,cn=users,dc=wisesoft,dc=co,dc=uk")
objUser.PutEx ADS_PROPERTY_DELETE, "otherTelephone", Array("5555")
objUser.setinfo
|
In part 2 we will learn how to query active directory and to write scripts to modify
existing user accounts.
Part 2