Discussion:
Updating AD with a script
(too old to reply)
Tcs
2009-04-05 23:28:09 UTC
Permalink
I've been trying to update our AD with a script. ( We currently run
ws2k3, but our AD came from ws2k. ) At one time, it WAS working. But
along the way...I've managed to break it. The current error is a (
Type Mismatch ) error at the command ( objUser.SetInfo ). Here's my
script:
=====
'Global variables
' Const ADS_OPTION_SECURITY_MASK = 3
' Const ADS_SECURITY_INFO_DACL = 4

Const ADS_UF_ACCOUNTDISABLE = 2
Const ADS_PROPERTY_UPDATE = 2
Dim oContainer
Dim strUserToUpdate, strUpdateFlag, strScript
Dim strTelNmbr

'Initialize global variables
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Open "Provider=ADsDSOObject;"
objCommand.ActiveConnection = objConnection

objCommand.CommandText = _
"<GC://dc=EastPointCity,dc=org>;(objectCategory=User)" & _
";userAccountControl," & _
"department," & _
"description," & _
"sn," & _
"givenName," & _
"displayName," & _
"streetAddress," & _
"physicalDeliveryOfficeName," & _
"title," & _
"mailNickname," & _
"mail," & _
"IpPhone," & _
"telephoneNumber," & _
"mobile," & _
"facsimileTelephoneNumber," & _
"info," & _
"l," & _
"st," & _
"postalCode," & _
"c," & _
"distinguishedName," & _
"ProfilePath," & _
"ScriptPath," & _
"HomeDirectory," & _
"HomeDrive" & _
";subtree"
Set objRecordSet = objCommand.Execute

'Wscript.Echo "Profile Path: " & objUser.ProfilePath
'Wscript.Echo "Script Path: " & objUser.ScriptPath
'Wscript.Echo "Home Directory: " & objUser.HomeDirectory
'Wscript.Echo "Home Drive: " & objUser.HomeDrive

'On Error Resume Next

intCounter = 0
Do Until objRecordset.EOF
strUpdateFlag = "N"
intUAC=objRecordset.Fields("userAccountControl")
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
If objRecordset.Fields("sn") > Null Or
objRecordset.Fields("sn") > "" Then
If objRecordset.Fields("givenName") > Null Or
objRecordset.Fields("givenName") > "" Then

If objRecordset.Fields("displayName") <> "Cliff Gibson" Then
If objRecordset.Fields("displayName") <> "Hollis Mason"
Then
' If intCounter < 6 Then
Set strUserToUpdate =
objRecordset.Fields("distinguishedName")
' WScript.Echo "strUser....( " & strUserToUpdate & ")"
' WScript.Echo "distName...( " &
objRecordset.Fields("distinguishedName") & ")"

Set objUser = GetObject _
( "LDAP://" &
objRecordset.Fields("distinguishedName") )

' strTelNmbr = objRecordset.Fields("telephoneNumber")
' WScript.Echo "telephoneNumber...(" & strTelNmbr & ")"
' If Len( strTelNmbr ) > 4 Then
' If strTelNmbr > "000" Then
' If strTelNmbr < "10000" Then

' WScript.Echo Right( strTelNmbr, 4 )
' objUser.Put "IpPhone", Right( strTelNmbr, 4 )

' End If
' End If
' End If

If objRecordset.Fields("department") = "Finance (
Accounting )" Then

Call ShowMe

objUser.Put "streetAddress", "1526 E Forrest Ave, Ste
400"
objUser.Put "physicalDeliveryOfficeName", "Accounting"

Call ShowMe

End If

If objRecordset.Fields("department") = "Finance ( Admin
)" Then

Call ShowMe

objUser.Put "streetAddress", "2777 East Point St" &
vbCrLf & "City Hall (3rd Floor)"
objUser.Put "physicalDeliveryOfficeName", "Finance"

Call ShowMe

End If


If objRecordset.Fields("department") = "Property Tax"
Then

Call ShowMe

objUser.Put "streetAddress", "1526 E Forrest Ave, Ste
400"
objUser.Put "physicalDeliveryOfficeName", "Property
Tax"

Call ShowMe

End If

If strUpdateFlag = "Y" Then

objUser.Put "company", "City of East Point"
objUser.Put "l", "East Point"
objUser.Put "st", "Georgia"
objUser.Put "postalCode", "30344"
objUser.Put "c", "United States"

' WScript.Echo "Updating...(" &
objRecordset.Fields("displayName") & ")"

' WScript.Echo _
' "Title..........(" & objRecordset.Fields("title") &
")" & vbCrLf & _
' "Profile Path..(" &
objRecordset.Fields("ProfilePath") & ")" & vbCrLf & _
' "ScriptPath....(" &
objRecordset.Fields("ScriptPath") & ")" & vbCrLf & _
' "HomeDir......(" &
objRecordset.Fields("HomeDirectory") & ")" & vbCrLf & _
' "HomeDrive...(" & objRecordset.Fields("HomeDrive") &
")"

' obj.put "ntsecuritydescriptor",oSD
' obj.SetOption ADS_OPTION_SECURITY_MASK,
ADS_SECURITY_INFO_DACL<BR/>

objUser.SetInfo
' intCounter = intCounter + 1

End If

' End If
End If
End If

End If
End If
End If
objRecordset.MoveNext
Loop

'Clean up
objConnection.Close
Set oContainer = Nothing
WScript.Echo "Updated...(" & intCounter & ")...records."
WScript.Echo "Finished"
WScript.Quit(0)

'+-----------------------------------------------------------------------------+
'| |
'+-----------------------------------------------------------------------------+
Function ShowMe

' intCounter = intCounter + 1

strUpdateFlag = "Y"

WScript.Echo _
"Updating.......(" & objRecordset.Fields("displayName") & ")" &
vbCrLf & vbCrLf & _
"Department.....(" & objRecordset.Fields("department") & ")" &
vbCrLf & _
"LastName.......(" & objRecordset.Fields("sn") & ")" & vbCrLf
& _
"FirstName......(" & objRecordset.Fields("givenName") & ")" &
vbCrLf & _
"DisplayName....(" & objRecordset.Fields("displayName") & ")"
& vbCrLf & _
"StreetAddress..(" & objRecordset.Fields("streetAddress") &
")" & vbCrLf & _
"OfcLocation....(" &
objRecordset.Fields("physicalDeliveryOfficeName") & ")" & vbCrLf & _
"Title..........(" & objRecordset.Fields("title") & ")" &
vbCrLf & _
"EmailAlias.....(" & objRecordset.Fields("mailNickname") & ")"
& vbCrLf & _
"EmailAddr......(" & objRecordset.Fields("mail") & ")" &
vbCrLf & _
"IpPhone........(" & objRecordset.Fields("IpPhone") & ")" &
vbCrLf & _
"TelNumber......(" & objRecordset.Fields("telephoneNumber") &
")" & vbCrLf & _
"Cell...........(" & objRecordset.Fields("mobile") & ")" &
vbCrLf & _
"Fax............(" &
objRecordset.Fields("facsimileTelephoneNumber") & ")" & vbCrLf & _
"'info'.........(" & objRecordset.Fields("info") & ")" &
vbCrLf & _
"City...........(" & objRecordset.Fields("l") & ")" & vbCrLf &
_
"State..........(" & objRecordset.Fields("st") & ")" & vbCrLf
& _
"ZipCode........(" & objRecordset.Fields("postalCode") & ")" &
vbCrLf & _
"Country........(" & objRecordset.Fields("c") & ")" & vbCrLf &
_
"distName.......(" & objRecordset.Fields("distinguishedName")
& ")" & vbCrLf & _
"ProfilePath....(" & objRecordset.Fields("ProfilePath") & ")"
& vbCrLf & _
"ScriptPath.....(" & objRecordset.Fields("ScriptPath") & ")" &
vbCrLf & _
"HomeDirectory..(" & objRecordset.Fields("HomeDirectory") &
")" & vbCrLf & _
"HomeDrive......(" & objRecordset.Fields("HomeDrive") & ")"

' For Each strValue in objUser.description
' WScript.Echo "Description..(" & strValue & ")"
' Next

' "Description....(" & objRecordset.Fields("description") & ")"

'objUser.PutEx ADS_PROPERTY_UPDATE, _
' "description", Array("Management staff")

End Function
'
' End of script
'
=====

Also, I can't seem to see the Description. That was generating an
error also, so I unhooked it. The important part is that I can't
update anyone now. I can silence the error by enabling ( On error
resume next ), but it still doesn't update anyone.

Any suggestions/ideas/thoughts would be apreciated.

Thanks a lot,

Tom
Richard Mueller [MVP]
2009-04-06 19:56:21 UTC
Permalink
Post by Tcs
I've been trying to update our AD with a script. ( We currently run
ws2k3, but our AD came from ws2k. ) At one time, it WAS working. But
along the way...I've managed to break it. The current error is a (
Type Mismatch ) error at the command ( objUser.SetInfo ). Here's my
=====
'Global variables
' Const ADS_OPTION_SECURITY_MASK = 3
' Const ADS_SECURITY_INFO_DACL = 4
Const ADS_UF_ACCOUNTDISABLE = 2
Const ADS_PROPERTY_UPDATE = 2
Dim oContainer
Dim strUserToUpdate, strUpdateFlag, strScript
Dim strTelNmbr
'Initialize global variables
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Open "Provider=ADsDSOObject;"
objCommand.ActiveConnection = objConnection
objCommand.CommandText = _
"<GC://dc=EastPointCity,dc=org>;(objectCategory=User)" & _
";userAccountControl," & _
"department," & _
"description," & _
"sn," & _
"givenName," & _
"displayName," & _
"streetAddress," & _
"physicalDeliveryOfficeName," & _
"title," & _
"mailNickname," & _
"mail," & _
"IpPhone," & _
"telephoneNumber," & _
"mobile," & _
"facsimileTelephoneNumber," & _
"info," & _
"l," & _
"st," & _
"postalCode," & _
"c," & _
"distinguishedName," & _
"ProfilePath," & _
"ScriptPath," & _
"HomeDirectory," & _
"HomeDrive" & _
";subtree"
Set objRecordSet = objCommand.Execute
'Wscript.Echo "Profile Path: " & objUser.ProfilePath
'Wscript.Echo "Script Path: " & objUser.ScriptPath
'Wscript.Echo "Home Directory: " & objUser.HomeDirectory
'Wscript.Echo "Home Drive: " & objUser.HomeDrive
'On Error Resume Next
intCounter = 0
Do Until objRecordset.EOF
strUpdateFlag = "N"
intUAC=objRecordset.Fields("userAccountControl")
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
If objRecordset.Fields("sn") > Null Or
objRecordset.Fields("sn") > "" Then
If objRecordset.Fields("givenName") > Null Or
objRecordset.Fields("givenName") > "" Then
If objRecordset.Fields("displayName") <> "Cliff Gibson" Then
If objRecordset.Fields("displayName") <> "Hollis Mason"
Then
' If intCounter < 6 Then
Set strUserToUpdate =
objRecordset.Fields("distinguishedName")
' WScript.Echo "strUser....( " & strUserToUpdate & ")"
' WScript.Echo "distName...( " &
objRecordset.Fields("distinguishedName") & ")"
Set objUser = GetObject _
( "LDAP://" &
objRecordset.Fields("distinguishedName") )
' strTelNmbr = objRecordset.Fields("telephoneNumber")
' WScript.Echo "telephoneNumber...(" & strTelNmbr & ")"
' If Len( strTelNmbr ) > 4 Then
' If strTelNmbr > "000" Then
' If strTelNmbr < "10000" Then
' WScript.Echo Right( strTelNmbr, 4 )
' objUser.Put "IpPhone", Right( strTelNmbr, 4 )
' End If
' End If
' End If
If objRecordset.Fields("department") = "Finance (
Accounting )" Then
Call ShowMe
objUser.Put "streetAddress", "1526 E Forrest Ave, Ste
400"
objUser.Put "physicalDeliveryOfficeName", "Accounting"
Call ShowMe
End If
If objRecordset.Fields("department") = "Finance ( Admin
)" Then
Call ShowMe
objUser.Put "streetAddress", "2777 East Point St" &
vbCrLf & "City Hall (3rd Floor)"
objUser.Put "physicalDeliveryOfficeName", "Finance"
Call ShowMe
End If
If objRecordset.Fields("department") = "Property Tax"
Then
Call ShowMe
objUser.Put "streetAddress", "1526 E Forrest Ave, Ste
400"
objUser.Put "physicalDeliveryOfficeName", "Property
Tax"
Call ShowMe
End If
If strUpdateFlag = "Y" Then
objUser.Put "company", "City of East Point"
objUser.Put "l", "East Point"
objUser.Put "st", "Georgia"
objUser.Put "postalCode", "30344"
objUser.Put "c", "United States"
' WScript.Echo "Updating...(" &
objRecordset.Fields("displayName") & ")"
' WScript.Echo _
' "Title..........(" & objRecordset.Fields("title") &
")" & vbCrLf & _
' "Profile Path..(" &
objRecordset.Fields("ProfilePath") & ")" & vbCrLf & _
' "ScriptPath....(" &
objRecordset.Fields("ScriptPath") & ")" & vbCrLf & _
' "HomeDir......(" &
objRecordset.Fields("HomeDirectory") & ")" & vbCrLf & _
' "HomeDrive...(" & objRecordset.Fields("HomeDrive") &
")"
' obj.put "ntsecuritydescriptor",oSD
' obj.SetOption ADS_OPTION_SECURITY_MASK,
ADS_SECURITY_INFO_DACL<BR/>
objUser.SetInfo
' intCounter = intCounter + 1
End If
' End If
End If
End If
End If
End If
End If
objRecordset.MoveNext
Loop
'Clean up
objConnection.Close
Set oContainer = Nothing
WScript.Echo "Updated...(" & intCounter & ")...records."
WScript.Echo "Finished"
WScript.Quit(0)
'+-----------------------------------------------------------------------------+
'| |
'+-----------------------------------------------------------------------------+
Function ShowMe
' intCounter = intCounter + 1
strUpdateFlag = "Y"
WScript.Echo _
"Updating.......(" & objRecordset.Fields("displayName") & ")" &
vbCrLf & vbCrLf & _
"Department.....(" & objRecordset.Fields("department") & ")" &
vbCrLf & _
"LastName.......(" & objRecordset.Fields("sn") & ")" & vbCrLf
& _
"FirstName......(" & objRecordset.Fields("givenName") & ")" &
vbCrLf & _
"DisplayName....(" & objRecordset.Fields("displayName") & ")"
& vbCrLf & _
"StreetAddress..(" & objRecordset.Fields("streetAddress") &
")" & vbCrLf & _
"OfcLocation....(" &
objRecordset.Fields("physicalDeliveryOfficeName") & ")" & vbCrLf & _
"Title..........(" & objRecordset.Fields("title") & ")" &
vbCrLf & _
"EmailAlias.....(" & objRecordset.Fields("mailNickname") & ")"
& vbCrLf & _
"EmailAddr......(" & objRecordset.Fields("mail") & ")" &
vbCrLf & _
"IpPhone........(" & objRecordset.Fields("IpPhone") & ")" &
vbCrLf & _
"TelNumber......(" & objRecordset.Fields("telephoneNumber") &
")" & vbCrLf & _
"Cell...........(" & objRecordset.Fields("mobile") & ")" &
vbCrLf & _
"Fax............(" &
objRecordset.Fields("facsimileTelephoneNumber") & ")" & vbCrLf & _
"'info'.........(" & objRecordset.Fields("info") & ")" &
vbCrLf & _
"City...........(" & objRecordset.Fields("l") & ")" & vbCrLf &
_
"State..........(" & objRecordset.Fields("st") & ")" & vbCrLf
& _
"ZipCode........(" & objRecordset.Fields("postalCode") & ")" &
vbCrLf & _
"Country........(" & objRecordset.Fields("c") & ")" & vbCrLf &
_
"distName.......(" & objRecordset.Fields("distinguishedName")
& ")" & vbCrLf & _
"ProfilePath....(" & objRecordset.Fields("ProfilePath") & ")"
& vbCrLf & _
"ScriptPath.....(" & objRecordset.Fields("ScriptPath") & ")" &
vbCrLf & _
"HomeDirectory..(" & objRecordset.Fields("HomeDirectory") &
")" & vbCrLf & _
"HomeDrive......(" & objRecordset.Fields("HomeDrive") & ")"
' For Each strValue in objUser.description
' WScript.Echo "Description..(" & strValue & ")"
' Next
' "Description....(" & objRecordset.Fields("description") & ")"
'objUser.PutEx ADS_PROPERTY_UPDATE, _
' "description", Array("Management staff")
End Function
'
' End of script
'
=====
Also, I can't seem to see the Description. That was generating an
error also, so I unhooked it. The important part is that I can't
update anyone now. I can silence the error by enabling ( On error
resume next ), but it still doesn't update anyone.
Any suggestions/ideas/thoughts would be apreciated.
My theory is that you added a contact to your AD. Your filter
(objectCategory=user) will return return all user and contact objects in the
domain, but contact objects do not have a userAccountControl attribute. This
should raise an error. Assuming no other problems, the fix would be to use
the filter (&(objectCategory=person)(objectClass=user)). For example:

objCommand.CommandText = _
"<GC://dc=EastPointCity,dc=org>;(&(objectCategory=person)(objectClass=user))"
& _

A few other points. I'm not sure this would work:

intUAC=objRecordset.Fields("userAccountControl")
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then

I would instead use:

intUAC=objRecordset.Fields("userAccountControl")
If (intUAC And ADS_UF_ACCOUNTDISABLE = 0) Then

This ensures that only accounts not disabled are processed. Also, objUser.c
should be "US" instead of "United States". When you assign the proper two
letter abbreviation to the c attribute, AD assigns "United States" to the co
attibute and "840" to the CountryCode attribute.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--
Tcs
2009-04-07 00:28:21 UTC
Permalink
Thank you sir. I'll try your suggestions as soon I get a chance. I
appreciate it. And I'll let you know.

On Mon, 6 Apr 2009 14:56:21 -0500, "Richard Mueller [MVP]"
Post by Richard Mueller [MVP]
Post by Tcs
I've been trying to update our AD with a script. ( We currently run
Any suggestions/ideas/thoughts would be apreciated.
My theory is that you added a contact to your AD. Your filter
(objectCategory=user) will return return all user and contact objects in the
domain, but contact objects do not have a userAccountControl attribute. This
should raise an error. Assuming no other problems, the fix would be to use
objCommand.CommandText = _
"<GC://dc=EastPointCity,dc=org>;(&(objectCategory=person)(objectClass=user))"
& _
intUAC=objRecordset.Fields("userAccountControl")
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
intUAC=objRecordset.Fields("userAccountControl")
If (intUAC And ADS_UF_ACCOUNTDISABLE = 0) Then
This ensures that only accounts not disabled are processed. Also, objUser.c
should be "US" instead of "United States". When you assign the proper two
letter abbreviation to the c attribute, AD assigns "United States" to the co
attibute and "840" to the CountryCode attribute.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
Tcs
2009-04-12 03:41:19 UTC
Permalink
I made all three (3) changes. And the script ran all the way thru. It
also did NOT find anyone to modify. So I put back:

If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then

This time it found five (5) users to modify...then errored out at:

Set objUser = GetObject _
( "LDAP://" & objRecordset.Fields("distinguishedName") )

Error: 0x80005000
Code: 80005000
Source: (null)

So then I changed:

If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then

To:

If ( intUAC <> 514 And ADS_UF_ACCOUNTDISABLE = 0 ) Then

And it went back to finding NO ONE to change. So...

I changed:

If ( intUAC <> 514 And ADS_UF_ACCOUNTDISABLE = 0 ) Then

To:

If ( intUAC And Not ADS_UF_ACCOUNTDISABLE ) Then

This time it found five (5) users to modify...then errored out at:

Set objUser = GetObject _
( "LDAP://" & objRecordset.Fields("distinguishedName") )

Error: 0x80005000
Code: 80005000
Source: (null)

It did modify the five (5) that it found, the way I wanted. So...it
WAS an improvement. Now if I could just fix the remaining 250+
users... :)

Any ideas?

Thanks again,

Tom

On Mon, 6 Apr 2009 14:56:21 -0500, "Richard Mueller [MVP]"
Post by Richard Mueller [MVP]
Post by Tcs
I've been trying to update our AD with a script. ( We currently run
My theory is that you added a contact to your AD. Your filter
(objectCategory=user) will return return all user and contact objects in the
domain, but contact objects do not have a userAccountControl attribute. This
should raise an error. Assuming no other problems, the fix would be to use
objCommand.CommandText = _
"<GC://dc=EastPointCity,dc=org>;(&(objectCategory=person)(objectClass=user))"
& _
intUAC=objRecordset.Fields("userAccountControl")
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
intUAC=objRecordset.Fields("userAccountControl")
If (intUAC And ADS_UF_ACCOUNTDISABLE = 0) Then
This ensures that only accounts not disabled are processed. Also, objUser.c
should be "US" instead of "United States". When you assign the proper two
letter abbreviation to the c attribute, AD assigns "United States" to the co
attibute and "840" to the CountryCode attribute.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
Richard Mueller [MVP]
2009-04-12 18:06:32 UTC
Permalink
The only situation I am aware of that will cause the error on this statement
(where the DN is retrieved by ADO):

Set objUser = GetObject _
( "LDAP://" & objRecordset.Fields("distinguishedName") )

is when the DistinguishedName has a forward slash character, "/". In
VBScript this must be escaped with the backslash escape character, "\". For
example:

strUserDN = objRecordset.Fields("distinguishedName").Value
strUserDN = Replace(strUserDN, "/", "\/")
Set objUser = GetOBject("LDAP://" & strUserD)

For more on escaping characters in VBScript, see this link:

http://www.rlmueller.net/CharactersEscaped.htm

I've recently learned that two other characters must also be escaped, a
leading blank and a trailing blank (for example, if the Common Name is " Jim
Smith" or "Jim Smith "). However, the only character that is not already
escaped by ADO (so that you must test for it and escape it yourself) is the
forward slash. It is an unfortunate quirk that only arises in methods that
use ADSI (like VBScript). As for the statement:

If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then

I had no idea what that would do (it is not clear at all), so I had to test.
It does not result in the script operating on all users that are not
disabled. Instead, the script will operate on all users where intUAC is not
514. This will include some disabled users who have other bits (flags) of
the userAccountControl attribute set (like password never expires).

I believe your clause is equivalent to:

If (intUAC <> 514) And (intUAC And ADS_UF_ACCOUNTDISABLE <> 0) Then

Which is exactly the same as:

If (intUAC <> 514) Then

In my domain, the script will not operate on the krbtgt account, since
userAccountControl is 514. However, it will operate on the guest account
where userAccountControl is 66082. 514 means:

account disabled
default account for typical user

whereas 66082 means:

account disabled
no password required
default account for typical user
password does not expire

The userAccountControl attribute is a "flag" attribute. It is an integer
value that indicates the status of several flags. It is tested using bit
masks, one bit mask for each setting. The proper way to test for a given
setting is to AND the value of the attribute with the corresponding bit
mask. Any non-zero result means the flag is set, a zero result means the
flag is NOT set. You set a bit using the OR operator. If you OR the value
with a bit mask, you set the corresponding flag. The XOR operator toggles
the corresponding bit (from on to off, or from off to on). To unset a flag,
you first must test if the bit is set (using the AND operator), then use the
XOR operator to toggle the bit off. For example, to test if an account is
disabled:

Const ADS_UF_ACCOUNTDISABLE = &H02
intUAC = objUser.userAccountControl
If (intUAC And ADS_UF_ACCOUNTDISABLE <> 0) Then
' The account is disabled.
End If

If (intUAC And ADS_UF_ACCOUNTDISABLE = 0) Then
' The account is NOT disabled (the account is enabled).
End If

To disable an account:

Const ADS_UF_ACCOUNTDISABLE = &H02
intUAC = objUser.userAccountControl
intUAC = intUAC Or ADS_UF_ACCOUNTDISABLE
objUser.userAccountControl = intUAC
objUser.SetInfo

Finally, to enable an account:

intUAC = objUser.userAccountControl
If (intUAC And ADS_UF_ACCOUNTDISABLE <> 0) Then
intUAC = intUAC Xor ADS_UF_ACCOUNTDISABLE
objUser.userAccountControl = intUAC
objUser.SetInfo
End If

One source of confusion is that the AND operator has two meanings. It can
mean the bitwise And'ing of two values, or it can mean the combining of two
conditional clauses so that both must be True for the whole to be True.
Remember also that in VBScript 0 is False, anything else is True.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--
Post by Tcs
I made all three (3) changes. And the script ran all the way thru. It
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
Set objUser = GetObject _
( "LDAP://" & objRecordset.Fields("distinguishedName") )
Error: 0x80005000
Code: 80005000
Source: (null)
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
If ( intUAC <> 514 And ADS_UF_ACCOUNTDISABLE = 0 ) Then
And it went back to finding NO ONE to change. So...
If ( intUAC <> 514 And ADS_UF_ACCOUNTDISABLE = 0 ) Then
If ( intUAC And Not ADS_UF_ACCOUNTDISABLE ) Then
Set objUser = GetObject _
( "LDAP://" & objRecordset.Fields("distinguishedName") )
Error: 0x80005000
Code: 80005000
Source: (null)
It did modify the five (5) that it found, the way I wanted. So...it
WAS an improvement. Now if I could just fix the remaining 250+
users... :)
Any ideas?
Thanks again,
Tom
On Mon, 6 Apr 2009 14:56:21 -0500, "Richard Mueller [MVP]"
Post by Richard Mueller [MVP]
Post by Tcs
I've been trying to update our AD with a script. ( We currently run
My theory is that you added a contact to your AD. Your filter
(objectCategory=user) will return return all user and contact objects in the
domain, but contact objects do not have a userAccountControl attribute. This
should raise an error. Assuming no other problems, the fix would be to use
objCommand.CommandText = _
"<GC://dc=EastPointCity,dc=org>;(&(objectCategory=person)(objectClass=user))"
& _
intUAC=objRecordset.Fields("userAccountControl")
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
intUAC=objRecordset.Fields("userAccountControl")
If (intUAC And ADS_UF_ACCOUNTDISABLE = 0) Then
This ensures that only accounts not disabled are processed. Also, objUser.c
should be "US" instead of "United States". When you assign the proper two
letter abbreviation to the c attribute, AD assigns "United States" to the co
attibute and "840" to the CountryCode attribute.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
Tcs
2009-04-18 12:42:46 UTC
Permalink
Thank you. I'll take another stab at it.

I do appreciate your time and effort.

On Sun, 12 Apr 2009 13:06:32 -0500, "Richard Mueller [MVP]"
Post by Richard Mueller [MVP]
The only situation I am aware of that will cause the error on this statement
Set objUser = GetObject _
( "LDAP://" & objRecordset.Fields("distinguishedName") )
is when the DistinguishedName has a forward slash character, "/". In
VBScript this must be escaped with the backslash escape character, "\". For
strUserDN = objRecordset.Fields("distinguishedName").Value
strUserDN = Replace(strUserDN, "/", "\/")
Set objUser = GetOBject("LDAP://" & strUserD)
http://www.rlmueller.net/CharactersEscaped.htm
I've recently learned that two other characters must also be escaped, a
leading blank and a trailing blank (for example, if the Common Name is " Jim
Smith" or "Jim Smith "). However, the only character that is not already
escaped by ADO (so that you must test for it and escape it yourself) is the
forward slash. It is an unfortunate quirk that only arises in methods that
If ( intUAC <> 514 And Not ADS_UF_ACCOUNTDISABLE ) Then
I had no idea what that would do (it is not clear at all), so I had to test.
It does not result in the script operating on all users that are not
disabled. Instead, the script will operate on all users where intUAC is not
514. This will include some disabled users who have other bits (flags) of
the userAccountControl attribute set (like password never expires).
If (intUAC <> 514) And (intUAC And ADS_UF_ACCOUNTDISABLE <> 0) Then
If (intUAC <> 514) Then
In my domain, the script will not operate on the krbtgt account, since
userAccountControl is 514. However, it will operate on the guest account
account disabled
default account for typical user
account disabled
no password required
default account for typical user
password does not expire
The userAccountControl attribute is a "flag" attribute. It is an integer
value that indicates the status of several flags. It is tested using bit
masks, one bit mask for each setting. The proper way to test for a given
setting is to AND the value of the attribute with the corresponding bit
mask. Any non-zero result means the flag is set, a zero result means the
flag is NOT set. You set a bit using the OR operator. If you OR the value
with a bit mask, you set the corresponding flag. The XOR operator toggles
the corresponding bit (from on to off, or from off to on). To unset a flag,
you first must test if the bit is set (using the AND operator), then use the
XOR operator to toggle the bit off. For example, to test if an account is
Const ADS_UF_ACCOUNTDISABLE = &H02
intUAC = objUser.userAccountControl
If (intUAC And ADS_UF_ACCOUNTDISABLE <> 0) Then
' The account is disabled.
End If
If (intUAC And ADS_UF_ACCOUNTDISABLE = 0) Then
' The account is NOT disabled (the account is enabled).
End If
Const ADS_UF_ACCOUNTDISABLE = &H02
intUAC = objUser.userAccountControl
intUAC = intUAC Or ADS_UF_ACCOUNTDISABLE
objUser.userAccountControl = intUAC
objUser.SetInfo
intUAC = objUser.userAccountControl
If (intUAC And ADS_UF_ACCOUNTDISABLE <> 0) Then
intUAC = intUAC Xor ADS_UF_ACCOUNTDISABLE
objUser.userAccountControl = intUAC
objUser.SetInfo
End If
One source of confusion is that the AND operator has two meanings. It can
mean the bitwise And'ing of two values, or it can mean the combining of two
conditional clauses so that both must be True for the whole to be True.
Remember also that in VBScript 0 is False, anything else is True.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
Loading...