locked
attribute for disabled date RRS feed

  • Question

  • Hi,

    i want to write Script to delete all the disabled accounts after 1 month from their disabled date and export them to CSV file. unfortunatly i didn't find attribute for disabled date. so can you help me or advice which attribute to use for this purpose.

    thanks.
    Saturday, October 30, 2010 1:07 PM

Answers

  • AD does not track the date when an account was disabled. However, the whenChanged attribute represents the date when the last change of any kind was made to an object. I recently posted the following script to retrieve all disabled users where whenChanged is more than 30 days in the past:

    Option Explicit
    
    Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
    Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strDN
    Dim dtmValue, strValue
    
    ' Setup ADO objects.
    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    Set adoCommand.ActiveConnection = adoConnection
    
    ' Search entire Active Directory domain.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<LDAP://" & strDNSDomain & ">"
    
    ' Find date 30 days in the past.
    dtmValue = DateAdd("d", Now(), -30)
    
    strValue = CStr(Year(dtmValue)) _
      & Right("0" & CStr(Month(dtmValue)), 2) _
      & Right("0" & CStr(Day(dtmValue)), 2) & "000000.0Z"
    
    ' Filter on disabled user objects that have not be modified in 30 days.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
      & "(userAccountControl:1.2.840.113556.1.4.803:=2)" _
      & "(whenChanged<=" & strValue & "))"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"
    
    ' 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.
      strDN = adoRecordset.Fields("distinguishedName").Value
      Wscript.Echo strDN
      ' Move to the next record in the recordset.
      adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close
    

    As with most administrative scripts, this should be run at a command prompt so you can redirect the output to a text file. For more on using ADO in VBScript programs, see this link:

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

    Richard Mueller


    MVP ADSI
    Saturday, October 30, 2010 2:11 PM

All replies

  • AD does not track the date when an account was disabled. However, the whenChanged attribute represents the date when the last change of any kind was made to an object. I recently posted the following script to retrieve all disabled users where whenChanged is more than 30 days in the past:

    Option Explicit
    
    Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
    Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strDN
    Dim dtmValue, strValue
    
    ' Setup ADO objects.
    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    Set adoCommand.ActiveConnection = adoConnection
    
    ' Search entire Active Directory domain.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<LDAP://" & strDNSDomain & ">"
    
    ' Find date 30 days in the past.
    dtmValue = DateAdd("d", Now(), -30)
    
    strValue = CStr(Year(dtmValue)) _
      & Right("0" & CStr(Month(dtmValue)), 2) _
      & Right("0" & CStr(Day(dtmValue)), 2) & "000000.0Z"
    
    ' Filter on disabled user objects that have not be modified in 30 days.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _
      & "(userAccountControl:1.2.840.113556.1.4.803:=2)" _
      & "(whenChanged<=" & strValue & "))"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"
    
    ' 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.
      strDN = adoRecordset.Fields("distinguishedName").Value
      Wscript.Echo strDN
      ' Move to the next record in the recordset.
      adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close
    

    As with most administrative scripts, this should be run at a command prompt so you can redirect the output to a text file. For more on using ADO in VBScript programs, see this link:

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

    Richard Mueller


    MVP ADSI
    Saturday, October 30, 2010 2:11 PM
  • Hi,

    thanks for your response, but what i;m planning for is to schedule this script to check the disabled date and delete the account after 1 month as per the policy. we have more than 8856 users and there are alot of disabled users. it will be hard to delete them mannually.

    Sunday, October 31, 2010 5:41 AM
  • If you've got formal procedures for disbling user accounts, you can add writing the disable date to an AD attribute.  You can append or prepend it to Description, or put it in one of the Exchange custom attribute fields if you've got Exchange schema extensions, lots of possibilities.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Sunday, October 31, 2010 6:01 AM
  • If you want the script to delete the users, instead of document them, replace the final loop with this:

    ' Enumerate the resulting recordset.
    Do Until adoRecordset.EOF
      ' Retrieve values.
      strDN = adoRecordset.Fields("distinguishedName").Value
      strDN = Replace(strDN, "/", "\/")
      ' Bind to the user object.
      ' Delete the object.
       objUser.DeleteObject (0)
      ' Move to the next record in the recordset.
      adoRecordset.MoveNext
    Loop
    

     

    This will delete any disabled users that have not been modified in the last 30 days. Unless an administrator modifies a disabled user, the whenChanged date should be the date the account was disabled. I would run the script first with the Wscript.Echo statement to make sure there are no disabled accounts that you don't want to have deleted.

    Richard Mueller


    MVP ADSI
    Sunday, October 31, 2010 12:45 PM