Link to home
Start Free TrialLog in
Avatar of Edge IT Systems
Edge IT SystemsFlag for United Kingdom of Great Britain and Northern Ireland

asked on

VBScript to update User Accounts by copying description to department

We have 800 user accounts and I'm trying to copy the description to the department in the User Accounts. This is on a Windows 2000 server which has a 3rd party product that needs the department to be set.

However the .VBS file runs without error but does not update the department.

What am I doing wrong ?
On Error Resume Next
Const ADS_PROPERTY_CLEAR   = 1 
Const ADS_PROPERTY_UPDATE = 2 
 
Set objComputer = GetObject("WinNT://sjf.local")
 
For Each objUser In objComputer
    WScript.Echo "Name: " & objUser.Name & " " & objuser.description
    objuser.department = objuser.description
 
'   None of the following work either
'   objUser.Put "Department", description
'   objUser.PutEx ADS_PROPERTY_CLEAR, "department", 0
'   objUser.PutEx ADS_PROPERTY_UPDATE, "department", "test value"
 
    objUser.SetInfo
Next

Open in new window

Avatar of RobSampson
RobSampson
Flag of Australia image

Hi, that's not working because you're binding to the WinNT instance of the user object, not the LDAP instance.  The code below will use LDAP to bind to each user. You may want to specifiy a test ou with strOU first, just for testing....

Regards,

Rob.
Const ADS_SCOPE_SUBTREE = 2
 
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
 
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
 
strOU = "OU=Users,"
If Trim(strOU) <> "" Then
	If Right(strOU, 1) <> "," Then strOU = strOU & ","
Else
	strOU = ""
End If
 
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
objCommand.CommandText = _
    "SELECT adsPath FROM 'LDAP://" & strOU & strDNSDomain & "' WHERE objectClass='person' AND objectCategory='user'"
Set objRecordSet = objCommand.Execute
 
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
	Set objUser = GetObject(objRecordSet.Fields("adsPath").Value)
    WScript.Echo "Name: " & objUser.Name & " " & objuser.description
    If TypeName(objUser.Description) <> "Emptry" Then
    	If TypeName(objUser.Description) = "String" Then
    		objuser.department = objuser.description
    	Else
    		objuser.department = Join(objuser.description)
    	End If
    End If
    objUser.SetInfo
    objRecordSet.MoveNext
Loop
MsgBox "Finished."

Open in new window

@RobSampson: you have a mistake on line 29 on spelling "Emptry", should be
"Empty" (see http://msdn.microsoft.com/en-us/library/y58s1cs6(VS.85).aspx)

Now to the subject: you can't get the description of the user because is an array
You should change script like this

arrUserDescription = Array("objuser.description")
objuser.department = arrUserDescription(0)
objUser.SetInfo
>> @RobSampson: you have a mistake on line 29 on spelling "Emptry"

Ha ha, yeah, thanks for the catch!

>> you can't get the description of the user because is an array

But that's why I use this:
    If TypeName(objUser.Description) <> "Empty" Then
          If TypeName(objUser.Description) = "String" Then

Just in case, for whatever reason, the Description is only a String, and not an array....but if it is, it uses Join(objUser.Description) anyway to make it a string.

Regards,

Rob.
Avatar of Edge IT Systems

ASKER

Thank you Rob I will test it later today.

Regards,

Chris
No problem Chris. Let me know how it goes.

Rob.
Hello Rob,

Sorry, I have finally resurfaced and tested the script.

However I am getting "table does not exist" on the "Set objRecordSet = objCommand.Execute" line. See VB-error.gif attached.

So I've attached a MsgBox of the "objCommand.CommandText". See VBS-debig.gif

Best regards,

Chris


VBS-debug.gif
VB-error.gif
Hi there, if you're specifying the built-in Users OU that exists at the root of your domain, try using
strOU = "CN=Users,"

The OU path to enumerate must be provided backwards. For example, if you want to query
domain.com/Sites/Main Office/Users
then you would use
strOU = "OU=Users,OU=Main Office,OU=Sites,"

To enumerate the entire AD, just leave
strOU = ""

Regards,

Rob.
Hi Rob,

Thank you, CN=Users helped.

However the "objUser.SetInfo" line crashes with a "contraint viloation occured" error when it tries to process CN=IUSR_SJF0099 which is the anon. account for IIS.

What is the correct syntax for excluding this account I unsuccessfully tried with following which did not detect IUSR_SJF0099 :
    If objUser.Name <> "IUSR_SJF0099" Then
         ....
    End If

Best regards,

Chris
Should be something like next lines, starting from line 26
Do Until objRecordSet.EOF
	Set objUser = GetObject(objRecordSet.Fields("adsPath").Value)
    WScript.Echo "Name: " & objUser.Name & " " & objuser.description
    If objUser.Name = "IUSR_SJF0099" Then
    	WScript.Echo "Skiping user " objUser.Name
    Else
	    If TypeName(objUser.Description) <> "Empty" Then
	    	If TypeName(objUser.Description) = "String" Then
	    		objuser.department = objuser.description
	    	Else
	    		objuser.department = Join(objuser.description)
	    	End If
	    End If
	    objUser.SetInfo
    End If
    objRecordSet.MoveNext
Loop
MsgBox "Finished."

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of RobSampson
RobSampson
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial