Re: need last logged on time for computer object, not user

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



thank you! i was trying that but had the category wrong



"Richard Mueller" <rlmueller-NOSPAM@xxxxxxxxxxxxxxxxxxxx> wrote in message
news:%23IpZ77ZFGHA.2300@xxxxxxxxxxxxxxxxxxxxxxx
> Jimmy D wrote:
>
>>i have the following script that gets me the last logged on time for all
>>users in a 2000 domain. i need this to give me computers instead... we
>>want
>>to delete computer accounts that have been inactive for 30 days. can
>>anyone
>>help? i tried but cant make it happen
>>
>> thank you!
>> *********************************
>>
>>
>> Option Explicit
>>
>> Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
>> Dim objRecordSet, objDC
>> Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
>> Dim strDN, dtmDate, objDate, lngDate, objList, strUser
>> Dim strBase, strFilter, strAttributes
>> Dim fso, output
>>
>> Set fso = CreateObject("Scripting.FileSystemObject")
>> Set output = fso.OpenTextFile("c:\output.txt", 8, True)
>>
>> ' Use a dictionary object to track latest LastLogon for each user.
>> Set objList = CreateObject("Scripting.Dictionary")
>> objList.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 and DNS domain from RootDSE object.
>> Set objRootDSE = GetObject("LDAP://RootDSE";)
>> strConfig = objRootDSE.Get("ConfigurationNamingContext")
>> strDNSDomain = objRootDSE.Get("DefaultNamingContext")
>>
>> ' Use ADO to search Active Directory for ObjectClass nTDSDSA.
>> ' This will identify all Domain Controllers.
>> Set objCommand = CreateObject("ADODB.Command")
>> Set objConnection = CreateObject("ADODB.Connection")
>> objConnection.Provider = "ADsDSOObject"
>> objConnection.Open "Active Directory Provider"
>> objCommand.ActiveConnection = objConnection
>>
>> strBase = "<LDAP://"; & strConfig & ">"
>> strFilter = "(ObjectClass=nTDSDSA)"
>> strAttributes = "AdsPath"
>> strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
>>
>> objCommand.CommandText = strQuery
>> objCommand.Properties("Page Size") = 100
>> objCommand.Properties("Timeout") = 60
>> objCommand.Properties("Cache Results") = False
>>
>> Set objRecordSet = objCommand.Execute
>>
>> ' Enumerate parent objects of class nTDSDSA. Save Domain Controller
>> ' AdsPaths in dynamic array arrstrDCs.
>> k = 0
>> Do Until objRecordSet.EOF
>> Set objDC = _
>> GetObject(GetObject(objRecordSet.Fields("AdsPath")).Parent)
>> ReDim Preserve arrstrDCs(k)
>> arrstrDCs(k) = objDC.DNSHostName
>> k = k + 1
>> objRecordSet.MoveNext
>> Loop
>>
>> ' Retrieve LastLogon attribute for each user on each Domain Controller.
>> For k = 0 To Ubound(arrstrDCs)
>> strBase = "<LDAP://"; & arrstrDCs(k) & "/" & strDNSDomain & ">"
>> strFilter = "(& (ObjectCategory=person)(ObjectClass=user))"
>> 'strFilter = Array("computer")
>> strAttributes = "DistinguishedName,LastLogon"
>> strQuery = strBase & ";" & strFilter & ";" & strAttributes _
>> & ";subtree"
>> objCommand.CommandText = strQuery
>> On Error Resume Next
>> Err.Clear
>> Set objRecordSet = objCommand.Execute
>> If Err.Number <> 0 Then
>> Err.Clear
>> On Error GoTo 0
>> Wscript.Echo "Domain Controller not available: " & arrstrDCs(k)
>> Else
>> On Error GoTo 0
>> Do Until objRecordSet.EOF
>> strDN = objRecordSet.Fields("DistinguishedName")
>> lngDate = objRecordSet.Fields("LastLogon")
>> On Error Resume Next
>> Err.Clear
>> Set objDate = lngDate
>> If Err.Number <> 0 Then
>> Err.Clear
>> dtmDate = #1/1/1601#
>> Else
>> If (objDate.HighPart = 0) And (objDate.LowPart = 0 ) Then
>> dtmDate = #1/1/1601#
>> Else
>> dtmDate = #1/1/1601# + (((objDate.HighPart * (2 ^ 32)) _
>> + objDate.LowPart)/600000000 - lngBias)/1440
>> End If
>> End If
>> On Error GoTo 0
>> If objList.Exists(strDN) Then
>> If dtmDate > objList(strDN) Then
>> objList(strDN) = dtmDate
>> End If
>> Else
>> objList.Add strDN, dtmDate
>> End If
>> objRecordSet.MoveNext
>> Loop
>> End If
>> Next
>>
>> ' Output latest LastLogon date for each user.
>> For Each strUser In objList
>>
>> output.WriteLine(strUser & " ; " & objList(strUser))
>>
>> 'Wscript.Echo strUser & " ; " & objList(strUser)
>> Next
>>
>> ' Clean up.
>> output.Close
>> Set output = Nothing
>> Set fso = Nothing
>> Set objRootDSE = Nothing
>> Set objConnection = Nothing
>> Set objCommand = Nothing
>> Set objRecordSet = Nothing
>> Set objDC = Nothing
>> Set objDate = Nothing
>> Set objList = Nothing
>> Set objShell = Nothing
>>
>> msgbox "done"
>
> Hi,
>
> In place of:
>
> strFilter = "(& (ObjectCategory=person)(ObjectClass=user))"
>
> which filters on user objects, use:
>
> strFilter = "(ObjectCategory=computer)"
>
> This will return the lastLogon dates for all computer objects in the
> domain.
> Note that in AD, the system resets the passwords for all computer objects
> every 30 days. This allows you to use the pwdLastSet attribute to find old
> computer objects. This has the advantage of being a replicated attribute
> (unlike lastLogon), so you don't need to query every DC. The disadvantage
> is
> that you don't know exactly when the computer was last connected, but you
> know within 30 days. This is fine for identifing old computers. A program
> that finds old computer objects using this method, disables the old
> accounts, and moves them to another OU is linked here:
>
> http://www.rlmueller.net/MoveOldComputers.htm
>
> In most networks, either method works about the same, but in large
> networks
> with slow links querying every DC can be slow.
>
> --
> Richard
> Microsoft MVP Scripting and ADSI
> Hilltop Lab - http://www.rlmueller.net
>
>
>
>


.



Relevant Pages

  • Re: last login script
    ... Without actually reading your adaptation of the script, ... a domain controller other than what one would expect. ... > Dim objRootDSE, strConfig, objConnection, objCommand, strQuery ... > On Error GoTo 0 ...
    (microsoft.public.scripting.vbscript)
  • Re: need last logged on time for computer object, not user
    ... > Dim objRootDSE, strConfig, objConnection, objCommand, strQuery ... > ' Retrieve LastLogon attribute for each user on each Domain Controller. ... > On Error GoTo 0 ... This will return the lastLogon dates for all computer objects in the domain. ...
    (microsoft.public.windows.server.scripting)
  • Re: Last Login Time - question about Script I have
    ... > Dim objRootDSE, strConfig, objConnection, objCommand, strQuery ... > Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs ... > ' Retrieve lastLogon attribute for each user on each Domain Controller. ... On Error GoTo 0 ...
    (microsoft.public.scripting.wsh)
  • Re: Domain Logonserver
    ... If you want the name of the Domain Controller that authenticated the ... Dim objRootDSE, strConfig, adoConnection, adoCommand, strQuery ... Dim dtmDate, objDate, objList ... On Error GoTo 0 ...
    (microsoft.public.scripting.vbscript)
  • Re: Last Login Time - question about Script I have
    ... > ' Controller in the domain must be queried to find the latest LastLogon ... Then, for each Domain Controller, ADO is used to search the ... > Dim objRootDSE, strConfig, objConnection, objCommand, strQuery ... > On Error GoTo 0 ...
    (microsoft.public.scripting.wsh)