List accounts within a certain date

I need some guidance from the Powershell gods as I’ve been scratching my head over this for ages now and have far too many browser tabs open.

I’m trying to retrieve a list of new start accounts of people starting within the next 30 days. In my org we set the users Start Date in a custom attribute, lets call this attribute: custAtt1. The data stored in this attribute is in the format of dd/mm/yyyy

The issue that I’m facing is that my results are returning dates outwith my date range (I’m pulling in results beyond my 30 day limit). I came across Adam Bertrams blog about having to potentially ‘casting’ strings into the DateTime format but I’m not sure how I can do this across multiple records. Ref: Demystifying PowerShell Dates, DateTime and Formatting

Here is my code:

$NewStarts = Get-ADUser -SearchBase "OU=<“Removed>” -Filter {(custAtt1 -lt $30Days)} -Properties Name,custAtt1
Write-Host "There are"$NewStarts.count" people due to start in the next 30 days"
$NewStarts | ft Name,custAtt1```

I assume you defined the varialbe $30Days before … anyway …

-Filter {(custAtt1 -lt $30Days)}

Your custAtt1 seems to be of the type [String] and comparing a String to a DateTime will not provide reasonable results.
So I’m afraid that you will have to collect all users and filter them with a Where-Object where you - first - turn your custAtt1 into a proper DateTime value and - second - compare it against your $30Days variable.

Yes sorry, I have defined that variable:

$30Days = ((Get-Date).AddDays(30)).ToString("dd/MM/yyyy")

I’ll take on your suggestion and report back, thanks!

Another tip in advance: When you define your variable to compare against do not turn it into a string type - remove the .ToString("dd/MM/yyyy").

In PowerShell we work with objects and properties - not with strings. :wink:

Fixed it!

I collected all of my users and then ran a for-each object to convert the string to DateTime:

$30Days = (Get-Date).AddDays(30)
Get-ADUser -SearchBase "OU=<Removed>" -Filter * -Properties Name,custAtt1 | Export-Csv -NoTypeInformation -Path $env:TEMP\NewStarts.csv
$NewStarts = Import-Csv $env:TEMP\NewStarts.csv
$NewStarts | ForEach-Object {
    $_.custAtt1 = [datetime]::parseexact($_.custAtt1,'dd/MM/yyyy',$null) 
    }

$NewStartWithin30Days = ($NewStarts | Where-Object {$_.custAtt1 -lt $30Days}) 

I’m sure there is a cleaner way to do this but I’m happy that the data being returned is correct so hopefully this may help someone else out there :slight_smile:

Thanks for your help Olaf.

Well, I don’t know if that counts as cleaner but you could skip the part with the export to a file and reading it again. That should speed up the snippet noticeably. :wink:

$30Days = (Get-Date).AddDays(30)
$NewStartWithin30Days = 
Get-ADUser -SearchBase "OU=<Removed>" -Filter * -Properties Name, custAtt1 | 
    Select-Object -Property *,@{Name = 'CustAttr1Parsed'; Expression = {[datetime]::parseexact($_.custAtt1, 'dd/MM/yyyy', $null)}} |
        Where-Object { $_.CustAttr1Parsed -lt $30Days }
1 Like