Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1405
  • Last Modified:

Date Arithmetic inside an LDAP filter for GAL


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.

3 Solutions
David Johnson, CD, MVPOwnerCommented:
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 $DeletedUser.name

        $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 $DisabledUser.name

    $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

Source: http://blogs.technet.com/b/heyscriptingguy/archive/2011/11/30/use-powershell-to-find-and-remove-inactive-active-directory-users.aspx
williamwlkAuthor Commented:
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.

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.
Rich RumbleSecurity SamuraiCommented:

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.
williamwlkAuthor Commented:

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

Appreciate it.

Thanks and regards,

Featured Post

Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now