As long as ADS_NAME_INITTYPE_GC has been defined in a Const statement to be
equal to 3, I don't see how the objTrans.Init statement can raise an error.
I will investigate the error, but it seems strange.
The next error is because the string "LABPOLAR" is not in quotes, so the
interpreter assumes it is an undefined variable. Your statements should be:
strNetBIOSDomain = "LABPOLAR"
' Then these lines commented out (there is no trailing "\" to remove.
' objTrans.Get(ADS_NAME_TYPE_NT4)
' Remove trailing backslash.
' strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)
I hope this helps.
--
Richard Mueller
Microsoft MVP Scripting and ADSI
Hilltop Lab -
http://www.rlmueller.net
--
"Gustavo"
discussions.microsoft.com> wrote in message
news:7A698FB1-6293-461A-BEA1-49059644EFBA@microsoft.com...
>> If the error is on the "Set objTrans" line, then the only explanation I
>> can
>> think of is that the client is Windows 95 or 98 or NT and DSClient is not
>> installed.
>>
>> If the error is on "objTrans.Init", then the client was unable to contact
>> a
>> Global Catalog.
>>
>> If the error was on "objTrans.Set", then strDNSDomain is wrong, but that
>> was
>> retrieved from the objRootDSE object. Either you are not joined to a
>> domain,
>> or no DC is available. This makes no sense if you are running the program
>> on
>> a DC.
>>
>> The "objTrans.Get" statement only raises an error if there is no NetBIOS
>> name for the domain, which is not possible.
>>
>> What error message do you get, and on which line exactly? The only
>> realistic
>> explanation I can see is that the client (the computer you are running
>> the
>> script on) cannot find a Global Catalog.
>>
>> As a last resort you could hard code the NetBIOS name of the domain. You
>> would replace the code you posted with:
>>
>> strNetBIOSDomain = "MyDomain"
>>
>> where "MyDomain" is the NetBIOS name of your domain. However, the error
>> makes me think something serious is wrong.
>>
>> --
>> Richard Mueller
>> Microsoft MVP Scripting and ADSI
>> Hilltop Lab -
http://www.rlmueller.net
>> --
>>
>> "Gustavo"
discussions.microsoft.com> wrote in message
>> news:7E914145-456F-4792-A212-19370DC78C46@microsoft.com...
>>>>
>>>> The line in the program LockedUsers.vbs that I meant to replace is
>>>> further
>>>> down, in the "For" loop that loops through the DC's. The complete code
>>>> could
>>>> look similar to below. This assumes the ou of interest is "ou=Sales":
>>>> ==================
>>>> Option Explicit
>>>>
>>>> Dim objRootDSE, strConfig, adoConnection, adoCommand, strQuery
>>>> Dim adoRecordset, objDC
>>>> Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
>>>> Dim strDN, dtmDate, objDate, strUser, strNTName
>>>> Dim objList1, objList2, objList3, j, intBadCount
>>>> Dim strBase, strFilter, strAttributes, objWinNTUser
>>>> Dim objTrans, strNetBIOSDomain, objDomain, arrstrNTNames()
>>>> Dim lngHigh, lngLow
>>>>
>>>> ' Constants for the NameTranslate object.
>>>> Const ADS_NAME_INITTYPE_GC = 3
>>>> Const ADS_NAME_TYPE_NT4 = 3
>>>> Const ADS_NAME_TYPE_1779 = 1
>>>>
>>>> ' Determine DNS domain name.
>>>> Set objRootDSE = GetObject("LDAP://RootDSE")
>>>> strDNSDomain = objRootDSE.Get("defaultNamingContext")
>>>>
>>>> ' Use the NameTranslate object to convert the DNS domain name
>>>> ' to the NetBIOS domain name.
>>>> Set objTrans = CreateObject("NameTranslate")
>>>> objTrans.Init ADS_NAME_INITTYPE_GC, ""
>>>> objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain
>>>> strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
>>>> ' Remove trailing backslash.
>>>> strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)
>>>>
>>>> ' Find locked out user accounts in domain
>>>> ' create array of sAMAccountName's
>>>> Set objDomain = GetObject("WinNT://" & strNetBIOSDomain)
>>>> objDomain.Filter = Array("user")
>>>> k = 0
>>>> For Each objWinNTUser In objDomain
>>>> If (objWinNTUser.IsAccountLocked = True) Then
>>>> ReDim Preserve arrstrNTNames(k)
>>>> arrstrNTNames(k) =
objWinNTUser.name
>>>> k = k + 1
>>>> End If
>>>> Next
>>>>
>>>> If (k = 0) Then
>>>> Wscript.Echo "No user accounts locked out in domain"
>>>> Wscript.Quit
>>>> End If
>>>>
>>>> ' Use dictionary objects to track latest badPasswordTime,
>>>> ' badPwdCount, and Domain Controller for each locked out user.
>>>> Set objList1 = CreateObject("Scripting.Dictionary")
>>>>
objList1.CompareMode = vbTextCompare
>>>> Set objList2 = CreateObject("Scripting.Dictionary")
>>>>
objList2.CompareMode = vbTextCompare
>>>> Set objList3 = CreateObject("Scripting.Dictionary")
>>>>
objList3.CompareMode = vbTextCompare
>>>>
>>>> ' Obtain local Time Zone bias from machine registry.
>>>> Set objShell = CreateObject("Wscript.Shell")
>>>> lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\"
>>>> _
>>>> & "TimeZoneInformation\ActiveTimeBias")
>>>> If (UCase(TypeName(lngBiasKey)) = "LONG") Then
>>>> lngBias = lngBiasKey
>>>> ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
>>>> lngBias = 0
>>>> For k = 0 To UBound(lngBiasKey)
>>>> lngBias = lngBias + (lngBiasKey(k) * 256^k)
>>>> Next
>>>> End If
>>>>
>>>> ' Determine configuration context.
>>>> strConfig = objRootDSE.Get("configurationNamingContext")
>>>>
>>>> ' Use ADO to search Active Directory for ObjectClass nTDSDSA.
>>>> ' This will identify all Domain Controllers.
>>>> Set adoCommand = CreateObject("
ADODB.Command")
>>>> Set adoConnection = CreateObject("
ADODB.Connection")
>>>>
adoConnection.Provider = "ADsDSOObject"
>>>> adoConnection.Open = "Active Directory Provider"
>>>>
adoCommand.ActiveConnection = adoConnection
>>>>
>>>> strBase = "
"
>>>> strFilter = "(objectClass=nTDSDSA)"
>>>> strAttributes = "AdsPath"
>>>> strQuery = strBase & ";" & strFilter & ";" & strAttributes &
>>>> ";subtree"
>>>>
>>>> adoCommand.CommandText = strQuery
>>>> adoCommand.Properties("Page Size") = 100
>>>> adoCommand.Properties("Timeout") = 60
>>>> adoCommand.Properties("Cache Results") = False
>>>>
>>>> Set adoRecordset = adoCommand.Execute
>>>>
>>>> ' Enumerate parent objects of class nTDSDSA. Save Domain Controller
>>>> ' DNS host names in dynamic array arrstrDCs.
>>>> k = 0
>>>> Do Until adoRecordset.EOF
>>>> Set objDC = _
>>>>
>>>> GetObject(GetObject(adoRecordset.Fields("AdsPath").Value).Parent)
>>>> ReDim Preserve arrstrDCs(k)
>>>> arrstrDCs(k) = objDC.DNSHostName
>>>> k = k + 1
>>>> adoRecordset.MoveNext
>>>> Loop
>>>> adoRecordset.Close
>>>>
>>>> ' Use ADO to retrieve all user objects from each Domain Controller.
>>>> strFilter = "(&(objectCategory=person)(objectClass=user))"
>>>> strAttributes = "distinguishedName,sAMAccountName," _
>>>> & "badPasswordTime,badPwdCount"
>>>> For k = 0 To Ubound(arrstrDCs)
>>>> strBase = "
>>>> &
>>>> ">"
>>>> strQuery = strBase & ";" & strFilter & ";" & strAttributes _
>>>> & ";subtree"
>>>> adoCommand.CommandText = strQuery
>>>> On Error Resume Next
>>>> Set adoRecordset = adoCommand.Execute
>>>> If (Err.Number <> 0) Then
>>>> On Error GoTo 0
>>>> Wscript.Echo "Domain Controller not available: " &
>>>> arrstrDCs(k)
>>>> Else
>>>> On Error GoTo 0
>>>> Do Until adoRecordset.EOF
>>>> strNTName = adoRecordset.Fields("sAMAccountName").Value
>>>> ' Check each user to see if in array of locked out
>>>> accounts.
>>>> For j = 0 To UBound(arrstrNTNames)
>>>> If (UCase(strNTName) = UCase(arrstrNTNames(j))) Then
>>>> ' User locked out, retrieve badPasswordTime.
>>>> strDN =
>>>> adoRecordset.Fields("distinguishedName").Value
>>>> intBadCount =
>>>> adoRecordset.Fields("badPwdCount").Value
>>>> On Error Resume Next
>>>> Set objDate =
>>>> adoRecordset.Fields("badPasswordTime").Value
>>>> If (Err.Number <> 0) Then
>>>> On Error GoTo 0
>>>> dtmDate = #1/1/1601#
>>>> Else
>>>> On Error GoTo 0
>>>> lngHigh = objDate.HighPart
>>>> lngLow = objDate.LowPart
>>>> If (lngLow < 0) Then
>>>> lngHigh = lngHigh + 1
>>>> End If
>>>> If (lngHigh = 0) And (lngLow = 0 ) Then
>>>> dtmDate = #1/1/1601#
>>>> Else
>>>> dtmDate = #1/1/1601# + (((lngHigh * (2 ^
>>>> 32))
>>>> _
>>>> + lngLow)/600000000 - lngBias)/1440
>>>> End If
>>>> End If
>>>> If (objList1.Exists(strDN) = True) Then
>>>> If (dtmDate > objList1.Item(strDN)) Then
>>>> ' Later badBadPasswordTime found, save
>>>> info
>>>> from
>>>> this DC.
>>>> objList1.Item(strDN) = dtmDate
>>>> objList2.Item(strDN) = intBadCount
>>>> objList3.Item(strDN) = arrstrDCs(k)
>>>> End If
>>>> Else
>>>> ' First time user found, save info from this
>>>> DC.
>>>> objList1.Add strDN, dtmDate
>>>> objList2.Add strDN, intBadCount
>>>> objList3.Add strDN, arrstrDCs(k)
>>>> End If
>>>> End If
>>>> Next
>>>> adoRecordset.MoveNext
>>>> Loop
>>>> adoRecordset.Close
>>>> End If
>>>> Next
>>>>
>>>> ' Output information on each locked out user.
>>>> For Each strUser In objList1.Keys
>>>> Wscript.Echo strUser & " ; " & objList1.Item(strUser) & " ; " _
>>>> & objList2.Item(strUser) & " ; " & objList3.Item(strUser)
>>>> Next
>>>>
>>>> ' Clean up.
>>>> adoConnection.Close
>>>> Set objRootDSE = Nothing
>>>> Set adoConnection = Nothing
>>>> Set adoCommand = Nothing
>>>> Set adoRecordset = Nothing
>>>> Set objTrans = Nothing
>>>> Set objDomain = Nothing
>>>> Set objWinNTUser = Nothing
>>>> Set objDC = Nothing
>>>> Set objDate = Nothing
>>>> Set objList1 = Nothing
>>>> Set objList2 = Nothing
>>>> Set objList3 = Nothing
>>>> Set objShell = Nothing
>>>> ===============
>>>> In the statement:
>>>>
>>>> strBase = "
>>>> ">"
>>>>
>>>> you need to modify "ou=Sales" to match the OU you are interested in.
>>>> Everything else should stay the same.
>>>>
>>>> --
>>>> Richard Mueller
>>>> Microsoft MVP Scripting and ADSI
>>>> Hilltop Lab - http://www.rlmueller.net
>>>> --
>>>>
>>>>
>>>>