Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ADO Computer Description Name from AD 1

Status
Not open for further replies.

Keyster86

IS-IT--Management
Jul 23, 2008
50
US
ALL,

This portion of code is not working for me...why?
Code:
[COLOR=red]adoRecordset.Fields("description").Value[/color]

I am trying to extract the "Description" field of computer objects out of Active Directory (AD) utilizing ADO language.

I keep getting an
Line: 94
Char: 5
error: "Item cannot be found in the collection corresponding to the requested name or ordinal."
Code: 800A0CC1
SOURCE: ADODB.Recordset

If I use an "ON ERROR GOTO NEXT" lines of code, wscript.echo turns out empty and script works with no errors.

Please help me.

Code:
OPTION EXPLICIT

DIM objFSO, objFile, objRootDSE, objShell, objDate, objTargetOU, objComputer, objRootLDAP
DIM strFilePath, strDNSDomain, strFilter, strQuery, strComputerDN, strTargetOU, strScriptName, strParentFolder, strDescription
DIM intDays, intTotal, intInactive, intNotMoved, intNotDisabled
DIM adoConnection, adoCommand, adoRecordset
DIM lngBiasKey, lngBias
DIM dtmPwdLastSet
DIM arrDesc
DIM k

strScriptName = wscript.ScriptFullName
SET objFSO = CreateObject("Scripting.FileSystemObject")
SET objFile = objFSO.GetFile(strScriptName)
strParentFolder = objFSO.GetParentFolderName(objFile) 

strFilePath = strParentFolder & "\OldComputers.log"

intDays = 30

strTargetOU = "OU=COMPUTERS" 'I have removed the full OU path for privacy reasons.
Set objRootDSE = GetObject("LDAP://rootDSE")
Set objTargetOU = GetObject("LDAP://" & strTargetOU & _
objRootDSE.Get("defaultNamingContext")) 

IF (Err.Number <> 0) THEN
    Wscript.Echo "Organization Unit not found: " & strTargetOU
    Wscript.Quit
END IF

' Open the log file for write access. Append to this file.
SET objFSO = CreateObject("Scripting.FileSystemObject")
SET objFile = objFSO.OpenTextFile(strFilePath, 8, True, 0)
IF (Err.Number <> 0) THEN
    Wscript.Echo "File " & strFilePath & " cannot be opened"
    SET objFSO = NOTHING
    Wscript.Quit
END IF

' 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

' Use ADO to search the domain for all computers.
SET adoConnection = CreateObject("ADODB.Connection")
SET adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOOBject"
adoConnection.Open "Active Directory Provider"
SET adoCommand.ActiveConnection = adoConnection

' Determine the DNS domain from the RootDSE object.
SET objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")

' Filter to retrieve all computer objects.
strFilter = "(objectCategory=computer)"

' Retrieve Distinguished Name and date password last set.
strQuery = "<LDAP://" & strTargetOU & strDNSDomain & ">;" & strFilter _
    & ";distinguishedName,pwdLastSet;subtree"

adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = FALSE

' Write information to log file.
objFile.WriteLine "Search for Inactive Computer Accounts"
objFile.WriteLine "Start: " & Now
objFile.WriteLine "Base of search: " & strTargetOU & strDNSDomain
objFile.WriteLine "Log File: " & strFilePath
objFile.WriteLine "Inactive if password not set in days: " & intDays
objFile.WriteLine "----------------------------------------------"
objFile.WriteLine

' Initialize totals.
intTotal = 0
intInactive = 0
intNotMoved = 0
intNotDisabled = 0

' Enumerate all computers and determine which are inactive.
SET adoRecordset = adoCommand.Execute
Do Until adoRecordset.EOF
    strComputerDN = adoRecordset.Fields("distinguishedName").Value
	
		[COLOR=red]'ON ERROR RESUME NEXT
		'arrDesc = adoRecordset.Fields("description").Value
		'If (TypeName(arrDesc) = "Variant()") Then
		'strDescription = arrDesc(0)
		'Else
		'strDescription = ""
		'End If
		'wscript.echo strDescription[/color]
	
    ' Escape any forward slash characters, "/", with the backslash
    ' escape character. All other characters that should be escaped are.
    strComputerDN = Replace(strComputerDN, "/", "\/")
    intTotal = intTotal + 1
    ' Determine date when password last set.
    SET objDate = adoRecordset.Fields("pwdLastSet").Value
    dtmPwdLastSet = Integer8Date(objDate, lngBias)
    ' Check if computer object inactive.
    IF (DateDiff("d", dtmPwdLastSet, Now) > intDays) THEN
        ' Computer object inactive.
        intInactive = intInactive + 1
		
	objFile.WriteLine "Inactive: " & Right(Left(strComputerDN,18),15) _
            & " - password last set: " & dtmPwdLastSet & strDescription
        IF (Err.Number <> 0) THEN
            intNotDisabled = intNotDisabled + 1
            objFile.WriteLine "Cannot disable: " & strComputerDN
        END IF
    END IF
    adoRecordset.MoveNext
Loop
adoRecordset.Close

' Write totals to log file.
objFile.WriteLine
objFile.WriteLine "----------------------------------------------"
objFile.WriteLine "Finished: " & Now
objFile.WriteLine "Total computer objects found:   " & intTotal
objFile.WriteLine "Inactive:                       " & intInactive
objFile.WriteLine "----------------------------------------------"

' Display summary.
'Wscript.Echo "Computer objects found:         " & intTotal
IF intInactive <> 0 THEN MsgBox "Inactive:                       " & intInactive,64,"Inactive Computer Objects"
MsgBox "COMPLETE!" & vbcrlf & vbcrlf & "See log file for details: " & vbcrlf & strFilePath,64,"Inactive Computer Objects"

' Clean up.
objFile.Close
adoConnection.Close
SET objFile = NOTHING
SET objFSO = NOTHING
SET objShell = NOTHING
SET adoConnection = NOTHING
SET adoCommand = NOTHING
SET objRootDSE = NOTHING
SET adoRecordset = NOTHING
SET objComputer = NOTHING

'Wscript.Echo "Done"

FUNCTION Integer8Date(objDate, lngBias)
    ' FUNCTION to convert Integer8 (64-bit) value to a date, adjusted for
    ' time zone bias.
    DIM lngAdjust, lngDate, lngHigh, lngLow
    lngAdjust = lngBias
    lngHigh = objDate.HighPart
    lngLow = objDate.LowPart
    ' Account for bug in IADsLargeInteger property methods.
    IF (lngHigh = 0) And (lngLow = 0) THEN
        lngAdjust = 0
    END IF
    lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
        + lngLow) / 600000000 - lngAdjust) / 1440
    Integer8Date = CDate(lngDate)
END FUNCTION

V/r,

SPC Key
United States Army
 
If you want to read an attribute, you have to include it in the return set.

>strQuery = "<LDAP://" & strTargetOU & strDNSDomain & ">;" & strFilter _
& ";distinguishedName,pwdLastSet;subtree"

[tt]strQuery = "<LDAP://" & strTargetOU & strDNSDomain & ">;" & strFilter _
& ";distinguishedName,pwdLastSet[red],description[/red];subtree"[/tt]
 
Thanks tsuji - it worked like a charm.

Final product:
Code:
OPTION EXPLICIT

DIM objFSO, objFile, objRootDSE, objShell, objDate, objTargetOU, objComputer, objRootLDAP, objTest
DIM strFilePath, strDNSDomain, strFilter, strQuery, strComputerDN, strTargetOU, strScriptName, strParentFolder, strDescription
DIM intDays, intTotal, intInactive, intNotMoved, intNotDisabled
DIM adoConnection, adoCommand, adoRecordset
DIM lngBiasKey, lngBias
DIM dtmPwdLastSet
DIM arrDesc
DIM k

strScriptName = wscript.ScriptFullName
SET objFSO = CreateObject("Scripting.FileSystemObject")
SET objFile = objFSO.GetFile(strScriptName)
strParentFolder = objFSO.GetParentFolderName(objFile) 

strFilePath = strParentFolder & "\OldComputers.log"

intDays = 30

strTargetOU = "OU=COMPUTERS" ' Note: The full OU has been left out for privacy purpose.
Set objRootDSE = GetObject("LDAP://rootDSE")
Set objTargetOU = GetObject("LDAP://" & strTargetOU & _
objRootDSE.Get("defaultNamingContext")) 

IF (Err.Number <> 0) THEN
    Wscript.Echo "Organization Unit not found: " & strTargetOU
    Wscript.Quit
END IF

' Open the log file for write access. Append to this file.
SET objFSO = CreateObject("Scripting.FileSystemObject")
SET objFile = objFSO.OpenTextFile(strFilePath, 8, True, 0)
IF (Err.Number <> 0) THEN
    Wscript.Echo "File " & strFilePath & " cannot be opened"
    SET objFSO = NOTHING
    Wscript.Quit
END IF

' 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

' Use ADO to search the domain for all computers.
SET adoConnection = CreateObject("ADODB.Connection")
SET adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOOBject"
adoConnection.Open "Active Directory Provider"
SET adoCommand.ActiveConnection = adoConnection

' Determine the DNS domain from the RootDSE object.
SET objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")

' Filter to retrieve all computer objects.
strFilter = "(objectCategory=computer)"

' Retrieve Distinguished Name and date password last set.
strQuery = "<LDAP://" & strTargetOU & strDNSDomain & ">;" & strFilter _
    & ";distinguishedName,pwdLastSet,description;subtree"

adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = FALSE

' Write information to log file.
objFile.WriteLine "Search for Inactive Computer Accounts"
objFile.WriteLine "Start: " & Now
objFile.WriteLine "Base of search: " & strTargetOU & strDNSDomain
objFile.WriteLine "Log File: " & strFilePath
objFile.WriteLine "Inactive if password not set in days: " & intDays
objFile.WriteLine "----------------------------------------------"
objFile.WriteLine

' Initialize totals.
intTotal = 0
intInactive = 0
intNotMoved = 0
intNotDisabled = 0

' Enumerate all computers and determine which are inactive.
SET adoRecordset = adoCommand.Execute
Do Until adoRecordset.EOF
    strComputerDN = adoRecordset.Fields("distinguishedName").Value
		arrDesc = adoRecordset.Fields("description").Value
		If (TypeName(arrDesc) = "Variant()") Then
		strDescription = arrDesc(0)
		Else
		strDescription = ""
		End If
		'wscript.echo strDescription
			
    ' Escape any forward slash characters, "/", with the backslash
    ' escape character. All other characters that should be escaped are.
    strComputerDN = Replace(strComputerDN, "/", "\/")
    intTotal = intTotal + 1
    ' Determine date when password last set.
    SET objDate = adoRecordset.Fields("pwdLastSet").Value
    dtmPwdLastSet = Integer8Date(objDate, lngBias)
    ' Check if computer object inactive.
    IF (DateDiff("d", dtmPwdLastSet, Now) > intDays) THEN
        ' Computer object inactive.
        intInactive = intInactive + 1
		
	objFile.WriteLine "Inactive: " & Right(Left(strComputerDN,18),15) _
            & " - " & strDescription & " - " & "password last set: " & dtmPwdLastSet
        IF (Err.Number <> 0) THEN
            intNotDisabled = intNotDisabled + 1
            objFile.WriteLine "Cannot disable: " & strComputerDN
        END IF
    END IF
    adoRecordset.MoveNext
Loop
adoRecordset.Close

' Write totals to log file.
objFile.WriteLine
objFile.WriteLine "----------------------------------------------"
objFile.WriteLine "Finished: " & Now
objFile.WriteLine "Total computer objects found:   " & intTotal
objFile.WriteLine "Inactive:                       " & intInactive
objFile.WriteLine "----------------------------------------------"

' Display summary.
'Wscript.Echo "Computer objects found:         " & intTotal
IF intInactive <> 0 THEN MsgBox "Inactive:                       " & intInactive,64,"Inactive Computer Objects"
MsgBox "COMPLETE!" & vbcrlf & vbcrlf & "See log file for details: " & vbcrlf & strFilePath,64,"Inactive Computer Objects"

' Clean up.
objFile.Close
adoConnection.Close
SET objFile = NOTHING
SET objFSO = NOTHING
SET objShell = NOTHING
SET adoConnection = NOTHING
SET adoCommand = NOTHING
SET objRootDSE = NOTHING
SET adoRecordset = NOTHING
SET objComputer = NOTHING

'Wscript.Echo "Done"

FUNCTION Integer8Date(objDate, lngBias)
    ' FUNCTION to convert Integer8 (64-bit) value to a date, adjusted for
    ' time zone bias.
    DIM lngAdjust, lngDate, lngHigh, lngLow
    lngAdjust = lngBias
    lngHigh = objDate.HighPart
    lngLow = objDate.LowPart
    ' Account for bug in IADsLargeInteger property methods.
    IF (lngHigh = 0) And (lngLow = 0) THEN
        lngAdjust = 0
    END IF
    lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
        + lngLow) / 600000000 - lngAdjust) / 1440
    Integer8Date = CDate(lngDate)
END FUNCTION

V/r,

SPC Key
United States Army
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top