Windows Vista Forums

return a list of all expired user accounts and its dates
  1. #1


    Chris Guest

    return a list of all expired user accounts and its dates

    does anyone have a script to search the whole domain and return a list of
    DISPLAY NAME and its expiration date?

    Thanks.



      My System SpecsSystem Spec

  2. #2


    Richard Mueller [MVP] Guest

    Re: return a list of all expired user accounts and its dates

    Chris wrote:

    > does anyone have a script to search the whole domain and return a list of
    > DISPLAY NAME and its expiration date?
    >
    You can use ADO in a VBScript program to find all user objects where the
    accountExpires attribute is a date in the past. See this link for
    information on using ADO:

    http://www.rlmueller.net/ADOSearchTips.htm

    You would need to convert the current date to the equivalent Integer8
    (64-bit) value. The page above includes a link to a program,
    DateToInteger8.vbs, to make the conversion. For example, 12:00 am August 19,
    2008 (in my time zone), corresponds to the Integer8 value:

    128635956000000000

    Using the syntax from the page I linked above, your filter would be (watch
    line wrapping):

    strFilter =
    "(&(objectCategory=person)(objectClass=user)(accountExpires<=128635956000000000)(!accountExpires=0))"

    You could retrieve the attribute values you want for the objects meeting the
    filter requirements with:

    strAttributes = "displayName,accountExpires"

    You could use the program Integer8ToDate.vbs linked on this page to convert
    the resulting values retrieved for accountExpires to dates in your time
    zone:

    http://www.rlmueller.net/Integer8Attributes.htm

    The resulting program (not tested) could be similar to below:
    =============
    ' 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

    ' Setup ADO objects.
    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection

    ' Search entire Active Directory domain.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<LDAP://" & strDNSDomain & ">"

    ' Filter on user objects expired before August 19, 2008.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
    & "(accountExpires<=128635956000000000)(!accountExpires=0))"

    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "displayName,accountExpires"

    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False

    ' Run the query.
    Set adoRecordset = adoCommand.Execute

    ' Enumerate the resulting recordset.
    Do Until adoRecordset.EOF
    ' Retrieve values and display.
    strName = adoRecordset.Fields("displayName").Value
    Set objDate = adoRecordset.Fields("accountExpires").Value
    dtmDate = Integer8Date(objDate, lngTZBias)
    Wscript.Echo "Display Name: " & strName & ", Expired: " & dtmDate
    ' Move to the next record in the recordset.
    adoRecordset.MoveNext
    Loop

    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    Function Integer8Date(ByVal objDate, ByVal 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
    ==========
    You would run the above at a command prompt with cscript. You can redirect
    the output to a text file.

    Note that the displayName attribute is not required and can be blank. You
    may want the value of the "cn" attribute (Common Name), or better yet, the
    "sAMAccountName" attribute instead. Both cn and sAMAccountName are
    mandatory, but only sAMAccountName uniquely identifies the object in the
    domain. The value of cn only needs to be unique in the OU or container.

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



      My System SpecsSystem Spec

  3. #3


    Chris Guest

    Re: return a list of all expired user accounts and its dates

    Thanks, Richard. Very hekpful.

    "Richard Mueller [MVP]" wrote:

    > Chris wrote:
    >

    > > does anyone have a script to search the whole domain and return a list of
    > > DISPLAY NAME and its expiration date?
    > >
    >
    > You can use ADO in a VBScript program to find all user objects where the
    > accountExpires attribute is a date in the past. See this link for
    > information on using ADO:
    >
    > http://www.rlmueller.net/ADOSearchTips.htm
    >
    > You would need to convert the current date to the equivalent Integer8
    > (64-bit) value. The page above includes a link to a program,
    > DateToInteger8.vbs, to make the conversion. For example, 12:00 am August 19,
    > 2008 (in my time zone), corresponds to the Integer8 value:
    >
    > 128635956000000000
    >
    > Using the syntax from the page I linked above, your filter would be (watch
    > line wrapping):
    >
    > strFilter =
    > "(&(objectCategory=person)(objectClass=user)(accountExpires<=128635956000000000)(!accountExpires=0))"
    >
    > You could retrieve the attribute values you want for the objects meeting the
    > filter requirements with:
    >
    > strAttributes = "displayName,accountExpires"
    >
    > You could use the program Integer8ToDate.vbs linked on this page to convert
    > the resulting values retrieved for accountExpires to dates in your time
    > zone:
    >
    > http://www.rlmueller.net/Integer8Attributes.htm
    >
    > The resulting program (not tested) could be similar to below:
    > =============
    > ' 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
    >
    > ' Setup ADO objects.
    > Set adoCommand = CreateObject("ADODB.Command")
    > Set adoConnection = CreateObject("ADODB.Connection")
    > adoConnection.Provider = "ADsDSOObject"
    > adoConnection.Open "Active Directory Provider"
    > adoCommand.ActiveConnection = adoConnection
    >
    > ' Search entire Active Directory domain.
    > Set objRootDSE = GetObject("LDAP://RootDSE")
    > strDNSDomain = objRootDSE.Get("defaultNamingContext")
    > strBase = "<LDAP://" & strDNSDomain & ">"
    >
    > ' Filter on user objects expired before August 19, 2008.
    > strFilter = "(&(objectCategory=person)(objectClass=user)" _
    > & "(accountExpires<=128635956000000000)(!accountExpires=0))"
    >
    > ' Comma delimited list of attribute values to retrieve.
    > strAttributes = "displayName,accountExpires"
    >
    > ' Construct the LDAP syntax query.
    > strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    > adoCommand.CommandText = strQuery
    > adoCommand.Properties("Page Size") = 100
    > adoCommand.Properties("Timeout") = 30
    > adoCommand.Properties("Cache Results") = False
    >
    > ' Run the query.
    > Set adoRecordset = adoCommand.Execute
    >
    > ' Enumerate the resulting recordset.
    > Do Until adoRecordset.EOF
    > ' Retrieve values and display.
    > strName = adoRecordset.Fields("displayName").Value
    > Set objDate = adoRecordset.Fields("accountExpires").Value
    > dtmDate = Integer8Date(objDate, lngTZBias)
    > Wscript.Echo "Display Name: " & strName & ", Expired: " & dtmDate
    > ' Move to the next record in the recordset.
    > adoRecordset.MoveNext
    > Loop
    >
    > ' Clean up.
    > adoRecordset.Close
    > adoConnection.Close
    >
    > Function Integer8Date(ByVal objDate, ByVal 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
    > ==========
    > You would run the above at a command prompt with cscript. You can redirect
    > the output to a text file.
    >
    > Note that the displayName attribute is not required and can be blank. You
    > may want the value of the "cn" attribute (Common Name), or better yet, the
    > "sAMAccountName" attribute instead. Both cn and sAMAccountName are
    > mandatory, but only sAMAccountName uniquely identifies the object in the
    > domain. The value of cn only needs to be unique in the OU or container.
    >
    > --
    > Richard Mueller
    > MVP Directory Services
    > Hilltop Lab - http://www.rlmueller.net
    > --
    >
    >
    >

      My System SpecsSystem Spec

return a list of all expired user accounts and its dates problems?

Similar Threads
Thread Thread Starter Forum Replies Last Post
A PowerShell script to list all 'dead' user accounts in AD? MattMJF PowerShell 3 08 Jun 2009
Read messages return to the new message list Bob Lucas Live Mail 7 15 Jan 2009
Read messages return to the new message list Bob Lucas Live Messenger 7 15 Jan 2009
How to delete the list of backup dates from Vista Ultimate BigCat Vista file management 1 29 Aug 2008
User Accounts at Logon vs User Accounts in Parental Control spacejuicer Vista General 2 20 Jun 2008