Compare then use


I have Users in my Active Directory.

I got a made a script that count them and display them on the console with informations about their profile like adresse mail, last time they set their password and when it will expire.

I creat variable for each of thoes informations and now i want to classify my User by the value of when their password will expire.

In order to do it the way i want it, i need that all Users ( for exemple) that have their password that expire in 56 days get grouped, all the Users that have their password expired in 23 days get grouped. Then i want to interract with them by group, like group that have 56 until password expire have a notification for exemple.

What i did is compare the value “password expire in 56 days” and if = 0 then creat a new variable to store them. But doing it this way just give me 2 users and i can’t harvest all of my users that get concerned by the 56 days…

I hope you will understand the message and maybe help me, i keep trying things and will keep until i find a solution !

Cannot understand the question, may be posting the code or a sample you have so far will help in understanding it better.

bit hard to know whats going on, can you show the code please?

I think essentially what you are going to need is to build a hashtable/PSObject from a where-object.

Show the code and people will be able to help.

If you haven’t already please read the bellow post to get an idea as to how to post


Hello, sorry i coudn’t post the script i wasn’t at work when i right this topic.



Write-Output "
Script de notification par mail de l’expiration des mots de passe de vos utilisateurs.


Load AD Module

Import-Module ActiveDirectory -ErrorAction Stop
Write-Warning “Impossible de charger le module d’Active Directory”

$expireInDays = “56”

Write-Output "Vous avez choisis d’être notifé si le mot de passe d’un utilisateur expire dans $expireInDays jours.


$users = get-aduser -filter {(Enabled -eq $true) -and (PasswordNeverExpires -eq $false)} -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress

$usersCount = ($users | Measure-Object).Count
Write-Output "Il y a $usersCount utilisateurs concernés par la date d’expiration des mots de passe.


$defaultMaxPasswordAge = (Get-ADDefaultDomainPasswordPolicy -ErrorAction Stop).MaxPasswordAge.Days
Write-Output "La durée de vie maximale d’un mot de passe sur votre domaine est de $defaultMaxPasswordAge jours.


$colUsers = @()

$emailaddress = “
$email = “
$SMTP = “
$Creds =[pscredential]::new(“”,(ConvertTo-SecureString -String “password” -AsPlainText -Force))
Write-Output “Process User Objects”
foreach ($user in $users)

$Name = $user.Name
$samAccountName = $user.SamAccountName
$pwdLastSet = $user.PasswordLastSet

$maxPasswordAge = $defaultMaxPasswordAge
$PasswordPol = (Get-AduserResultantPasswordPolicy $user)
if (($PasswordPol) -ne $null)
$maxPasswordAge = ($PasswordPol).MaxPasswordAge.Days

$userObj = New-Object System.Object
$expireson = $pwdLastSet.AddDays($maxPasswordAge)
$daysToExpire = New-TimeSpan -Start $today -End $Expireson

if(($daysToExpire.Days -eq “0”) -and ($daysToExpire.TotalHours -le $timeToMidnight.TotalHours))
$userObj | Add-Member -Type NoteProperty -Name UserMessage -Value “today.”
if(($daysToExpire.Days -eq “0”) -and ($daysToExpire.TotalHours -gt $timeToMidnight.TotalHours) -or ($daysToExpire.Days -eq “1”) -and ($daysToExpire.TotalHours -le $timeToMidnight2.TotalHours))
$userObj | Add-Member -Type NoteProperty -Name UserMessage -Value “tomorrow.”
if(($daysToExpire.Days -ge “1”) -and ($daysToExpire.TotalHours -gt $timeToMidnight2.TotalHours))
$days = $daysToExpire.TotalDays
$days = [math]::Round($days)
$userObj | Add-Member -Type NoteProperty -Name UserMessage -Value “in $days days.”
$daysToExpire = [math]::Round($daysToExpire.TotalDays)
$userObj | Add-Member -Type NoteProperty -Name UserName -Value $samAccountName
$userObj | Add-Member -Type NoteProperty -Name Name -Value $Name
$userObj | Add-Member -Type NoteProperty -Name PasswordSet -Value $pwdLastSet
$userObj | Add-Member -Type NoteProperty -Name DaysToExpire -Value $daysToExpire
$userObj | Add-Member -Type NoteProperty -Name ExpiresOn -Value $expiresOn

$colUsers += $userObj

$colUsersCount = ($colUsers | Measure-Object).Count

$notifyUsers = $colUsers | where { $_.DaysToExpire -le $expireInDays}
$notifiedUsers = @()
$notifyCount = ($notifyUsers | Measure-Object).Count
Write-Output "Il y a $notifyCount utilisateurs ayant un mot de passe expirant dans moins $expireInDays jours.


foreach ($user in $notifyUsers)

$samAccountName = $user.UserName
$emailAddress = $user.EmailAddress
$name = $user.Name
$messageDays = $user.UserMessage
$body ="

Le mot de passe de l’utilisateur $name expire dans $messageDays .

Veuillez lui rappeler de changer son mot de passe dans le temps restant.

Votre controleur de domaine.


If Testing Is Enabled - Email Administrator

$emailaddress = $testRecipient
} # End Testing

If a user has no email address listed

if(($emailaddress) -eq $null)
$emailaddress = $testRecipient
}# End No Valid Email
$samLabel = $samAccountName.PadRight($padVal," ")

if not using interval paramter - follow this section

if using status - output information to console

Write-Output “Sending Email : $samLabel : $emailAddress”
Send-MailMessage -To $email -From $email -Credential $Creds -Subject $Subject -Body $Body -SmtpServer $SMTP -UseSsl -Port 587 -DeliveryNotificationOption never
$user | Add-Member -MemberType NoteProperty -Name SendMail -Value “OK”

error section

$errorMessage = $_.exception.Message

if using status - output information to console

$user | Add-Member -MemberType NoteProperty -Name SendMail -Value $errorMessage

$notifiedUsers += $user

$notifiedUsers | select Name,PasswordSet,DaysToExpire,ExpiresOn | sort DaystoExpire | FT -autoSize

$runTime = New-TimeSpan $start $stop
Write-Output “Script Runtime: $runtime”



You have unnecessarily complicated this.

Why are you not just building collection first and one time only, using the cmdlet that is designed for this…

$Pw23DaysUsers = Search-ADAccount -AccountExpiring -TimeSpan "23"
$Pw56DaysUsers = Search-ADAccount -AccountExpiring -TimeSpan "56"

# Or

$Pw23DaysUsers = Search-ADAccount -AccountExpiring -TimeSpan (New-TimeSpan -Days 23)
$Pw23DaysUsers = Search-ADAccount -AccountExpiring -TimeSpan ([TimeSpan]::FromDays(23))

$Pw56DaysUsers = Search-ADAccount -AccountExpiring -TimeSpan (New-TimeSpan -Days 56)
$Pw56DaysUsers = Search-ADAccount -AccountExpiring -TimeSpan ([TimeSpan]::FromDays(56))

# Or 

$NeverExpires = 9223372036854775807

$ExpringIn = (Get-Date).AddDays(23) 
$Pw23DaysUsers = Get-ADUser -Filter * -Properties accountExpires | 
Where-Object {$_.accountExpires -ne $NeverExpires  -and [datetime]::FromFileTime([int64]::Parse($_.accountExpires)) -lt $ExpringIn }

$ExpringIn = (Get-Date).AddDays(56) 
$Pw56DaysUsers = Get-ADUser -Filter * -Properties accountExpires | 
Where-Object {$_.accountExpires -ne $NeverExpires  -and [datetime]::FromFileTime([int64]::Parse($_.accountExpires)) -lt $ExpringIn }

… then processing that collection?

Each of the above provide a count property. No real reason for the Measure. The above also provides a count and a Length property, that returns the same number, but I can’t see where you need it for your use case.


Or why are you not using:

# get function / cmdlet details
(Get-Command -Name Group-Object).Parameters
Get-help -Name Group-Object -Full
Get-help -Name Group-Object -Online
Get-help -Name Group-Object -Example

… get your groups first, then process the group. Again, this also provides a count property but I can’t se where you need it.

Oh, okay, i see!

I need it to group the mail. Now the script send 1 mail per user so, in my case only 30-40 users’s password reminder. But if someone with 500 user got to received +200 mails per day ( it’s just an exemple) it would be exausted and annoying.

That’s why i wanted to creat groups that have the same amout of time (in days) before the mail.

What you can do is move the Send-MailMessage line to the end of the script, and add $Body to a different variable at that point.

In fact, I’d probably modify the $Body template slightly, start with a header section saying “these are the users who need to change their passwords” or whatever you like, then just add the $name and $messageDays items to it each time, something like $EmailContent += “User: $Name Time: $messageDays”

Then once everything’s been added to it, tack on a brief footer message if you like, and pass that to Send-MailMessage’s -Body parameter in the final call.

Okay, i think that what i was trying to do this morning, without succes.

I will try what you said it seems close to the thing i wanted to do!