Script Center > Scripting Forums > The Official Scripting Guys Forum! > Create script to list the user whose accounts in excel sheet whose "account expires" in upcoming 2 months
Ask a questionAsk a question
 

QuestionCreate script to list the user whose accounts in excel sheet whose "account expires" in upcoming 2 months

  • Tuesday, November 03, 2009 2:00 PMNaresh Maddala Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello All,

    I am new to the VBscripting. I tried creating the script but got stuck in using the condition (Account expires in upcoming 2 months).I am pasting the script for the review. Please assist me in modifying the scripts to get the list of user accounts.

    VBScript
    ====================================================

    On Error Resume Next

    Const ADS_SCOPE_SUBTREE = 2

    Dim objConnection,objCommand,objUser

    Dim strADSPath

    Dim dtmAccountExpires 

     

    Set objConnection = CreateObject("ADODB.Connection")

    Set objCommand =   CreateObject("ADODB.Command")

    objConnection.Provider = "ADsDSOObject"

    objConnection.Open "Active Directory Provider"

    Set objCommand.ActiveConnection = objConnection

     

    objCommand.Properties("Page Size") = 1000

    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE

     

    objCommand.CommandText = _

    "SELECT distinguishedName FROM'LDAP://dc=contoso,dc=com' WHERE objectCategory='user'"

     

    Set objRecordSet = objCommand.Execute

     

    objRecordSet.MoveFirst

    Set objFSO = CreateObject("scripting.filesystemobject")

    Set logStream = objFSO.opentextfile("C:\accountexpires.csv", 3, True)

    logStream.writeline("Name,AccountExpires,AccountExpirationDate")

    Do Until objRecordSet.EOF

                Set strADSPath = objRecordset.Fields("distinguishedName").value

                Set objUser = GetObject(strADSPath)

                dtmAccountExpires=CDate(objUser.AccountExpirationDate)

     

                If Month(dtmAccountExpires)> 1 Then

                            If dtmAccountExpires < Date() Then

                            Text = "Yes"

                            Else

                            Text = "No"

                            End If

                End If

                 

                logStream.writeline(objRecordset.Fields("Name").Value & ","_

                            & text & ","_

                            & objRecordset.Fields("accountExpires").Value & ","_                 

                            )

         objRecordSet.MoveNext

        logStream.Close

    Loop

    'logStream.Close

    objConnection.Close

    Set objRecordSet = Nothing

    Set objCommand = Nothing

    Set objConnection = Nothing
    ==================================================================
    Help is appreciated

All Replies

  • Tuesday, November 03, 2009 3:16 PMRichard MuellerMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Your solution requires binding to all user objects in AD. Instead you can query for just the user objects where the account expires in the next 60 days. My solution follows:
    ===========
    ' AcctExp.vbs

    Option Explicit

    Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
    Dim objRootDSE, strDNSDomain, strQuery, adoRecordset
    Dim dtmDate1, dtmDate2, intDays, strName, strDN
    Dim lngSeconds1, str64Bit1, lngSeconds2, str64Bit2
    Dim objShell, lngBiasKey, lngBias, k
    Dim objDate, dtmExpires

    ' Number of days in future.
    intDays = 60

    ' Find date this may days in the future.
    dtmDate1 = Now()
    dtmDate2 = DateAdd("d", intDays, dtmDate1)

    ' Retrieve DNS name of domain.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("DefaultNamingContext")

    ' 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

    ' Convert the datetime values to UTC.
    dtmDate1 = DateAdd("n", lngBias, dtmDate1)
    dtmDate2 = DateAdd("n", lngBias, dtmDate2)

    ' Find number of seconds since 1/1/1601 for these dates.
    lngSeconds1 = DateDiff("s", #1/1/1601#, dtmDate1)
    lngSeconds2 = DateDiff("s", #1/1/1601#, dtmDate2)

    ' Convert the number of seconds to a string
    ' and convert to 100-nanosecond intervals.
    str64Bit1 = CStr(lngSeconds1) & "0000000"
    str64Bit2 = CStr(lngSeconds2) & "0000000"

    ' 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.
    strBase = "<LDAP://" & strDNSDomain & ">"

    ' Filter on user objects where the account expires between the
    ' dates specified.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
        & "(accountExpires>=" & str64Bit1 & ")" _
        & "(accountExpires<=" & str64Bit2 & "))"

    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "sAMAccountName,distinguishedName,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.
        strName = adoRecordset.Fields("sAMAccountName").Value
        strDN = adoRecordset.Fields("distinguishedName").Value
        ' Determine when account expires.
        Set objDate = adoRecordset.Fields("accountExpires").Value
        dtmExpires = Integer8Date(objDate, lngBias)
        Wscript.Echo strName & "," & strDN & "," & CStr(dtmExpires)
        ' 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
    =========
    My version requires that you run the script at a command prompt and redirect the output to a text file. The values are comma delimited. You can revise to use the FileSystemObject, and to output any attributes of the users desired. Note that in your version you attempt to output the value of the accountExpires attribute. This attribute is data type Integer8, which is a large 64-bit number that must be converted into a date. I hope this helps. For more discussion on accountExpires and the AccountExpirationDate property method, see this link:

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

    Richard Mueller


    MVP ADSI
  • Monday, November 09, 2009 10:05 AMNaresh Maddala Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello Richard, Thank you very much for assisting me. I tested the script,but the script list out those users as well whose accounts are going to epire in less than 2 months. Please help me in modifyoing the script to get the o/p of the users whose account gets expired in next 2 months regards Naresh
  • Monday, November 09, 2009 5:04 PMRichard MuellerMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I'm not sure I understand. If this month is November, perhaps you want all users whose accounts expire in December and January, but not in November. If so, one option would be to hardcode the critical dates in the script. For example:

    dtmDate1 = #12/01/2009#
    dtmDate2 = #01/31/2010#

    The program will find all users whose accounts expire between the two dates. Note that date literals are conclosed in "#" characters in VBScript. Also, this assumes your computer regional settings define dates as mm/dd/yyyy. If you want the program to calculate the critical dates based on the current date, then perhaps you can use:
    =======
    dtmDate1 = DateSerial(Year(Now()), Month(Now()), 1)
    dtmDate1 = DateAdd("m", 1, dtmDate1)
    dtmDate2 = DateAdd("m", 2, dtmDate1)
    dtmDate2 = DateAdd("d", -1, dtmDate2)
    =====
    If you run this code today, then dtmDate1 will be the first day of December and dtmDate2 will the the last day of January. I hope this helps.

    Richard Mueller
    MVP ADSI