Richard
Thu Apr 24 17:28:03 CDT 2008
floyd wrote:
"floyd" <w> wrote in message
news:4810e401$0$24296$dbd41001@news.wanadoo.nl...
> Hi there,
>
> Can anybody help me with this script.
>
> I wanna read the Logondate - Create date - Modified date and the path in
> activedirectory for computer accounts .
> But i want also see the disabled computer accounts, i don`t no how to
> start in this script.
> Also i want to see only the date and not the time..
>
>
> Thank you very much for help
>
> Rob
>
>
>
> Option Explicit
>
> Const FOR_WRITING = 2
> Const strDomain = "dc=Connectie,dc=Local"
>
> Dim strAge, objConnection, ObjCommand, ObjRecordSet
> Dim objOU, objDomain, Tel
> Dim strExit, strDN, strLastPwSet, intLastPwSet, dtmLastLogon, dtmDateDiff,
> strName
> Dim objConnect, strLogoncount, strWhenChanged, strWhenCreated, bDebug,
> objAD, i, objApp
>
> strAge = 0
>
> '* Aanmaak tekstbestand
> Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
> Dim sLogFile : sLogFile = "output.txt"
> Dim oLogFile : Set oLogFile = oFSO.OpenTextFile
> (sLogFile,FOR_WRITING,true)
>
>
> Set objConnection = CreateObject("ADODB.Connection")
> objConnection.Open "Provider=ADsDSOObject;"
>
> Set ObjCommand = CreateObject("ADODB.Command")
> ObjCommand.ActiveConnection = objConnection
>
> 'ldap query
> ObjCommand.CommandText = _
> "<LDAP://" & strDomain & ">;(&(objectClass=Computer)" & _
> "(sAMAccountName=" & "*" &
> "));distinguishedName,name,logonCount,whenChanged,whenCreated,pwdlastset;subtree"
>
> Set ObjRecordSet = objCommand.Execute
>
>
> If ObjRecordSet.recordcount = 0 Then
> WScript.Echo "No Objects founds"
> WScript.Quit
> End If
>
> WScript.Echo " Computeraccounts in Domain " & strDomain & " Count : " &
> ObjRecordSet.recordcount
>
>
> Err.Clear
> Tel = 0
>
>
> Do Until objRecordSet.EOF
>
> strExit = ""
> strDN = ""
> strLastPwSet = ""
> strLogoncount = ""
> strWhenChanged = ""
> strWhenCreated = ""
> strName = ""
> intLastPwSet = ""
> dtmLastLogon = ""
> dtmDateDiff = ""
>
>
> Do Until strExit = "Yes"
>
> strDN = ObjRecordSet.Fields("distinguishedName")
> strLastPwSet = ObjRecordSet.Fields("pwdlastset")
> strName = ObjRecordSet.Fields("Name")
> strLogoncount = ObjRecordSet.Fields("logonCount")
> strWhenChanged = ObjRecordSet.Fields("whenChanged")
> strWhenCreated = ObjRecordSet.Fields("whenCreated")
>
>
> dtmDateDiff = DateDiff("d", dtmlastlogon, Now)
>
> If dtmDateDiff >= cdbl(strAge) Then
>
> End If
>
>
>
>
> Dim strPt1, strPt2, strPt3
> If Left (strDN, 3) = "CN=" Then
> strPt1 = instr(10, strDN, "=")
> strPt2 = instr(strPt1, strDN, ",")
> strPt3 = Mid(strDN, strPt1+1, strPt2+80)
>
> Else
>
> End If
>
> strExit = "Yes"
> Loop
>
> objRecordset.MoveNext
>
> SchrijfInLog strName & ";" & dtmLastLogon & ";" & strLogoncount & ";" &
> strWhenChanged & ";" & strWhenCreated & ";" & strPt3
>
> Loop
>
>
> '//// Subs
>
> Sub SchrijfInLog(sText)
> oLogFile.WriteLine sText
> If bDebug Then WScript.echo sText
> End Sub
>
>
>
> objConnection.Close
> oLogFile.Close
>
> Set objConnection = Nothing
> Set ObjCommand = Nothing
> Set ObjRecordSet = Nothing
> Set objOU = Nothing
> Set oLogFile = Nothing
> Set oFSO = Nothing
>
>
Some comments.
1. The filter for computer objects would be (objectCategory=computer).
2. The whenChanged attribute is not replicated. A different value is saved
on every DC. Unless you query every DC in the domain you should use
modifyTimeStamp instead.
3. The modifyTimeStamp attribute is constructed (operational), but ADO
prompts AD to calculate the value. Same for createTimeStamp.
4. You retrieve pwdLastSet, but seem to want lastLogon. Both are datatype
Integer8, so they require special code to convert to dates. I demonstrate
how below.
5. The lastLogon attribute is not replicated, so a different value is saved
on every DC in the domain. If your domain is at Windows Server 2003
functional level, you can use the lastLogonTimeStamp attribute instead. This
Integer8 attribute is replicated, but it is only updated during logon if the
old value is more than 14 days in the past. This should be good enough for
most purposes.
6. The userAccountControl attribute is a flag value, one bit of which
indicates if the object is enabled. I demonstrate below how to test the bit
with a bit mask.
7. You can code to have the VBScript program write values to a text file.
However, it would be easier to have the program output to the console, then
redirect the output to a text file.
The example below writes a header line, then for each computer outputs the
values delimited by semicolons. This is because the Distinguished Name has
embedded commas. If the output is redirected to a text file, it can be read
by a spreadsheet program; just specify ";" as the delimiter. My version of
the program, assuming lastLogonTimeStamp is available, follows:
==========
Option Explicit
Dim objRootDSE, strDNSDomain, adoCommand, adoConnection
Dim strBase, strFilter, strAttributes, strQuery, adoRecordset
Dim strDN, strNTName, objShell, lngBiasKey, lngTZBias
Dim objLast, dtmLast, dtmCreate, dtmModify, blnEnabled, lngFlag
Const ADS_UF_ACCOUNTDISABLE = &H02
' 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
lngTZBias = lngBiasKey
ElseIf UCase(TypeName(lngBiasKey)) = "VARIANT()" Then
lngTZBias = 0
For k = 0 To UBound(lngBiasKey)
lngTZBias = lngTZBias + (lngBiasKey(k) * 256^k)
Next
End If
Set objShell = Nothing
' Determine DNS domain name.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
' Use ADO to search Active Directory.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
' Search entire domain.
strBase = "<LDAP://" & strDNSDomain & ">"
' Search for all computer objects.
strFilter = "(objectCategory=computer)"
' Comma delimited list of attribute values to retrieve.
strAttributes = "distinguishedName,sAMAccountName,lastLogonTimeStamp," _
& "createTimeStamp,modifyTimeStamp,userAccountControl"
' Construct the LDAP query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
' Output headings
Wscript.Echo "Distinguished Name;NT Name;Date Created;Date
Modified;Enabled?"
' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve values.
strDN = adoRecordset.Fields("distinguishedName").Value
strNTName = adoRecordset.Fields("sAMAccountName").Value
dtmCreate = adoRecordset.Fields("createTimeStamp").Value
dtmModify = adoRecordset.Fields("modifyTimeStamp").Value
Set objLast = adoRecordset.Fields("lastLogonTimeStamp").Value
dtmLast = Integer8Date(objLast, lngTZBias)
lngFlag = CLng(adoRecordset.Fields("userAccountControl").Value)
If (lngFlag And ADS_UF_ACCOUNTDISABLE) <> 0 Then
blnEnabled = False
Else
blnEnabled = True
End If
Wscript.Echo strDN & ";" & strNTName & ";" & dtmCreate _
& ";" & dtmModify & ";" & CStr(blnEnabled) & ";" & CStr(dtmLast)
adoRecordset.MoveNext
Loop
' Clean up.
adoRecordset.Close
adoConnection.Close
Function Integer8Date(objDate, lngBias)
' Function to convert Integer8 (64-bit) value to a date, adjusted for
' local time zone bias.
Dim lngAdjust, lngDate, lngHigh, lngLow
lngAdjust = lngBias
lngHigh = objDate.HighPart
lngLow = objdate.LowPart
' Account for error in IADslargeInteger property methods.
If lngLow < 0 Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0) Then
lngAdjust = 0
End If
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
' Trap error if lngDate is ridiculously huge.
On Error Resume Next
Integer8Date = CDate(lngDate)
If Err.Number <> 0 Then
On Error GoTo 0
Integer8Date = #1/1/1601#
End If
On Error GoTo 0
End Function
==========
This demonstrates how to convert an Integer8 attribute, like
lastLogonTimeStamp, to a date in the current time zone. The same techniques
can be used with other Integer8 attributes, like pwdLastSet. If your domain
is not at Windows Server 2003 functional level, I have an example VBScript
program to retrieve lastLogon for all users in the domain linked here:
http://www.rlmueller.net/Last%20Logon.htm
You could modify this to document last logon for computers by changing
strFilter = "(&(objectCategory=person)(objectClass=user))"
to
strFilter = "(objectCategory=computer)"
It would not make sense to document lastLogon in the same program as the
other attributes. In all cases, the date/time values can be converted to
dates using the FormatDateTime function. For example, you can use:
Wscript.Echo strDN & ";" & strNTName _
& ";" & FormatDateTime(dtmCreate, vbShortDate) _
& ";" & FormatDateTime(dtmModify, vbShortDate) _
& ";" & CStr(blnEnabled) & ";" & FormatDateTime(dtmLast, vbShortDate)
--
Richard Mueller
Microsoft MVP Scripting and ADSI
Hilltop Lab -
http://www.rlmueller.net
--