View Single Post
Old 01-08-2009   #2 (permalink)
Richard Mueller [MVP]
Guest


 
 

Re: Bulk unlock user accounts


"John Renkar" <jrenkar@xxxxxx> wrote in message
news:uolclhacJHA.1532@xxxxxx
Quote:

> We have been hit by the W32.Downadup.B virus. While we are removing it
> from our network, our users are bing locked out. I patched together the
> following script from some sample on the Microsoft site. It is not
> working. Any suggestions as to what is wrong and how to get it to work?
>
> *********
> On Error Resume Next
>
> 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
>
> objCommand.CommandText = _
> "SELECT * FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectCategory='user'"
> Set objRecordSet = objCommand.Execute
>
> objRecordSet.MoveFirst
> Do Until objRecordSet.EOF
> Set objUser = GetObject ("LDAP://cn=" & objRecordSet.Fields("Name").Value
> & ",dc=NA,dc=fabrikam,dc=com")
>
> objUser.IsAccountLocked = False
> objUser.SetInfo
> objRecordSet.MoveNext
> Loop
> *********
I assume you substituted the DNS name of your domain for
"dc=fabrikam,dc=com". You should specify the specific attributes you want to
retrieve. It makes more sense to retrieve distinguishedName. Also, the
filter should be "objectCategory = 'person' and objectClass = 'user'". For
example:

objCommand.CommandText = _
"SELECT distinguishedName FROM 'LDAP://dc=fabrikam,dc=com' " _
& "WHERE objectCategory = 'person' AND objectClass = 'user'"

Then when you bind to the user object:

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

Finally, I would recommend not using "On Error Resume Next" throughout the
script. It makes troubleshooting very difficult. The only part that might
raise an error is where the accounts are unlocked (you may lack permission).
I would suggest using LDAP syntax. For example this should work:
==========
Option Explicit

Dim objRootDSE, strDNSDomain, adoConnection
Dim strBase, strFilter, strAttributes, strQuery, adoRecordset
Dim strDN, objUser

' Determine DNS domain name.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory.
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"

Set adoRecordset = CreateObject("ADODB.Recordset")
adoRecordset.ActiveConnection = adoConnection

' Search entire domain.
strBase = "<LDAP://" & strDNSDomain & ">"

' Filter on all user objects.
strFilter = "(&(objectCategory=person)(objectClass=user))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "distinguishedName"

' Construct the LDAP query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

' Run the query.
adoRecordset.Source = strQuery
adoRecordset.Open

' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve values.
strDN = adoRecordset.Fields("distinguishedName").Value
strDN = Replace(strDN, "/", "\/")
Set objUser = GetObject("LDAP://" & strDN)
On Error Resume Next
objUser.IsAccountLocked = False
objUser.SetInfo
If (Err.Number <> 0) Then
Wscript.Echo "Unable to unlock " & strDN
End If
On Error GoTo 0
adoRecordset.MoveNext
Loop

' Clean up.
adoRecordset.Close
adoConnection.Close

--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--


My System SpecsSystem Spec