Date Arithmetic inside an LDAP filter for GAL

Posted on 2012-08-21
Last Modified: 2012-09-02

In addition to the above, I'd like to implement the following :

I’m not sure it’s possible to do date arithmetic inside an LDAP filter…

But I would like your help on this:


Where user account is disabled AND User account Whenchanged greater than or equal to today–90 days

Can you transform the above LDAP Filter Logic to something like this:

Thanks a bunch.

Question by:williamwlk
    LVL 77

    Assisted Solution

    by:David Johnson, CD, MVP
    could do it in powershell using AD commandlets if I understood what you want other than search an OU and see if an account is disabled and was changed 90 days or more ago.

    #import the ActiveDirectory Module
    Import-Module ActiveDirectory
    #Create a variable for the date stamp in the log file
    $LogDate = get-date -f yyyyMMddhhmm
    #Sets the OU to do the base search for all user accounts, change for your env.
    $SearchBase = "OU=User_Accounts,DC=DEVLAB,DC=LOCAL"
    #Create an empty array for the log file
    $LogArray = @()
    #Sets the number of days to delete user accounts based on value in description field
    $Disabledage = (get-date).adddays(-14)
    #Sets the number of days to disable user accounts based on lastlogontimestamp and pwdlastset.
    $PasswordAge = (Get-Date).adddays(-90)
    #RegEx pattern to verify date format in user description field.
    $RegEx = '^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](20)\d\d$'
    #Use ForEach to loop through all users with description date older than date set. Deletes the accounts and adds to log array.
    ForEach ($DeletedUser in (Get-Aduser -searchbase $SearchBase -Filter {enabled -eq $False} -properties description ) ){
      #Verifies description field is in the correct date format by matching the regular expression from above to prevent errors with other disbaled users.
      If ($DeletedUser.Description -match $Regex){
        #Compares date in the description field to the DisabledAge set.
        If((get-date $DeletedUser.Description) -le $Disabledage){
          #Deletes the user object. This will prompt for each user. To suppress the prompt add "-confirm:$False". To log only add "-whatif".
          Remove-ADObject $DeletedUser
            #Create new object for logging
            $obj = New-Object PSObject
            $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $
            $obj | Add-Member -MemberType NoteProperty -Name "samAccountName" -Value $DeletedUser.samaccountname
            $obj | Add-Member -MemberType NoteProperty -Name "DistinguishedName" -Value $DeletedUser.DistinguishedName
            $obj | Add-Member -MemberType NoteProperty -Name "Status" -Value 'Deleted'
            #Adds object to the log array
            $LogArray += $obj
    #Use ForEach to loop through all users with pwdlastset and lastlogontimestamp greater than date set. Also added users with no lastlogon date set. Disables the accounts and adds to log array.
    ForEach ($DisabledUser in (Get-ADUser -searchbase $SearchBase -filter {((lastlogondate -notlike "*") -OR (lastlogondate -le $Passwordage)) -AND (passwordlastset -le $Passwordage) -AND (enabled -eq $True)} )) {
      #Sets the user objects description attribute to a date stamp. Example "11/13/2011"
      set-aduser $DisabledUser -Description ((get-date).toshortdatestring())
      #Disabled user object. To log only add "-whatif"
      Disable-ADAccount $DisabledUser
        #Create new object for logging
        $obj = New-Object PSObject
        $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $
        $obj | Add-Member -MemberType NoteProperty -Name "samAccountName" -Value $DisabledUser.samaccountname
        $obj | Add-Member -MemberType NoteProperty -Name "DistinguishedName" -Value $DisabledUser.DistinguishedName
        $obj | Add-Member -MemberType NoteProperty -Name "Status" -Value 'Disabled'
        #Adds object to the log array
        $LogArray += $obj
    #Exports log array to CSV file in the temp directory with a date and time stamp in the file name.
    $logArray | Export-Csv "C:\Temp\User_Report_$logDate.csv" -NoTypeInformation

    Open in new window


    Author Comment

    Thanks. I am doing all those things from my Windows XP Client.

    Import-Module ActiveDirectory

    I have PowerShell 1.0 but I don't have "ActiveDirectory" PowerShell 1.0 CMDLet.

    Where can I download and install it?

    Thank you.

    LVL 26

    Assisted Solution

    LDAP time is... different from POSIX/UNIX epoch time. Where epoch time starts at 01 Jan 1970, Microsoft in (its infinite insanity along with the ANSI folks) decided LDAP time should being at 01 Jan 1601 and is measured in how many 100ns ticks there have been since that time.

    No, that's not a typo. AD LDAP time start before the first live showing of Hamlet.
    LVL 38

    Accepted Solution


    That should do it, I used dsquery.exe from the ADAM pack to test

    dsquery * dc=my,dc=company,dc=com -limit 0 -filter "(&(objectCategory=User)(userAccountControl:1.2.840.113556.1.4.803:=2)(whenchanged>=20120526000000.0Z))" -attr name samaccountname

    The date is broken down as "2012 may the 26th, 00 hrs, 00 min, 00 sec, 0 Zulu" The 0Zulu is required, and the Z has to be capital.
    There is no way to use JUST greaterthan so you have to use >= or <= for lessthan. You can use * in place of name/samaccountname, and get ALL user fields back. I'm not sure about how to query outlook in this way, but that is how to quickly query AD itself. You don't really need a big script or powershell, there are simpler tools out there like dsquery and dsget that I love to use.

    Author Closing Comment


    Your solution is a bull's eyes hit. I am grateful for your expert's advise.

    Appreciate it.

    Thanks and regards,

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Join & Write a Comment

    Synchronize a new Active Directory domain with an existing Office 365 tenant
    Exchange server is not supported in any cloud-hosted platform (other than Azure with Azure Premium Storage).
    This tutorial will walk an individual through setting the global and backup job media overwrite and protection periods in Backup Exec 2012. Log onto the Backup Exec Central Administration Server. Examine the services. If all or most of them are stop…
    This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor ( If you're looking for how to monitor bandwidth using netflow or packet s…

    754 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now