Author Posts

April 12, 2016 at 8:59 am

I'm writing a script that will find any AD account within 14 days of expiring and will email out to the users to change their passwords.

So far I have

#gets all users that arent service accounts and are not disabled
$users = get-aduser -filter * -properties passwordlastset, passwordneverexpires |?{$_.passwordneverexpires -ne "true" -and $_.enabled -eq "true"}

foreach($user in ($users | ?{$_.passwordlastset -ne $null -and $user.passwordexpired -ne "true"}))
{
	#90 days is our GPO
	$expireon = $user.passwordlastset.adddays(90)
	#warning date for 14 days out
	$warning = ($expireon).adddays(-14)
	
	if($warning -lt (get-date))
	{
		$clock = $expireon - (get-date)
		
		if($clock -ge 1)
		{
		
			#mail on success
			$smtpServer = "10.10.10.10"
			$msg = new-object Net.Mail.MailMessage
			$smtp = new-object Net.Mail.SmtpClient($smtpServer)
			$msg.From = "test@test.com"
			$msg.To.Add(@($user.userprincipalname))
			$msg.Subject = "Your Account is About to Expire"
			$msg.Body = "Your username: $($user.samaccountname) expires on $expireon, you have $($clock.days) days $($clock.hours) hours to change it."
			$smtp.Send($msg)
			
		}
	}
}

I want to maybe put in a switch, or nested If's that meet the conditions

1 IF within 14-8 days, send only 1 email
2 IF withing 7-6 days, send another emails (so only 2 emails so far sent to user)
3 IF withing 5-0 days, send out an email each day

I'm not sure how to set this up exactly. I figured to put this script into task scheduler but not sure how to make sure it knows each user has already been sent an email.

Any help will be appreciated.

April 12, 2016 at 9:53 am

Assuming that the script is run every day, send the email when $clock = 14, 7, 5, 4, 3, 2, 1, or 0.

For the first week that script is run, the users whose passwords are 8-13 days from expiring will miss the first email, but after that you should be good.

April 12, 2016 at 10:08 am

I think that'll do, a simple way to get it done. Thanks!

April 12, 2016 at 11:06 am

Or run it once checking for $clock = 0-5 or 7-14, then as I said above after that.

April 12, 2016 at 11:11 am

#gets all users that arent service accounts and are not disabled
$users = get-aduser -filter * -properties passwordlastset, passwordneverexpires |?{$_.passwordneverexpires -ne "true" -and $_.enabled -eq "true"}


if($users)
{

	# create empty array to collect the data
	$data = New-Object -TypeName System.Collections.ArrayList
	
	foreach($user in ($users | ?{$_.passwordlastset -ne $null -and $user.passwordexpired -ne "true"}))
	{
		#90 days is our GPO
		$expireon = $user.passwordlastset.adddays(90)
		#warning date for 14 days out
		$warning = ($expireon).adddays(-14)
		
		#if within 14 days of today's date, this triggers
		if($warning -lt (get-date))
		{
			$clock = $expireon - (get-date)
			
			if($clock -ge 1)
			{
				if($clock.days -eq 14 -or $clock.days -eq 7)
				{
					#mail on success
					$smtpServer = "10.10.10.10"
					$msg = new-object Net.Mail.MailMessage
					$smtp = new-object Net.Mail.SmtpClient($smtpServer)
					$msg.From = "user@domain.com"
					#$msg.To.Add(@($user.userprincipalname))
					$msg.To.Add(@("test@test.com"))
					$msg.Subject = "Your Account: $($user.samaccountname) Exipiring in $($clock.days) Days"
					$msg.Body = "Hello $($user.givenname),`n`nYour username: $($user.samaccountname) expires on $expireon.`nYou have $($clock.days) days $($clock.hours) hours to change it.`nIf you are unsure how to complete this task please contact your system administartor at: support@domain.com"
					$smtp.Send($msg)
				}
				elseif( $clock.days -eq 0 -or
						$clock.days -eq 1 -or
						$clock.days -eq 2 -or
						$clock.days -eq 3 -or
						$clock.days -eq 4 -or
						$clock.days -eq 5)
				{
					#mail on success
					$smtpServer = "10.10.10.10"
					$msg = new-object Net.Mail.MailMessage
					$smtp = new-object Net.Mail.SmtpClient($smtpServer)
					$msg.From = "user@domain.com"
					#$msg.To.Add(@($user.userprincipalname))
					$msg.To.Add(@("test@test.com"))
					$msg.Subject = "FINAL NOTICE: Your Account: $($user.samaccountname) Exipiring in $($clock.days) Days"
					$msg.Body = "Hello $($user.givenname),`n`nYour username: $($user.samaccountname) expires on $expireon.`nYou have $($clock.days) days $($clock.hours) hours to change it.`nIf you are unsure how to complete this task please contact your system administartor at: support@domain.com"
					$smtp.Send($msg)
				
				}
				else
				{
					"$($user.samaccountname) $($clock.days)"
				}
				
				$text =  "$($user.samaccountname),"
				$text += "$($expireon),"
				$text += "$($clock.days) Day(s) $($clock.hours) Hour(s)"
				# add row to the array
				[void]$data.Add($text)
			}
		}
	}

	#header info
	$style = "BODY{font-family: Arial; font-size: 10pt;}"
	$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
	$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
	$style = $style + "TD{border: 1px solid black; padding: 5px; }"
	$style = $style + ""

	####send to IT staff
	$html = $data | ConvertFrom-Csv -Header "Expiring Users","Expire Date", "Remaining Time" | convertto-html -head $style 

	#mail on success
	$smtpServer = "10.10.10.10"
	$msg = new-object Net.Mail.MailMessage
	$smtp = new-object Net.Mail.SmtpClient($smtpServer)
	$msg.From = "user@domain.com"
	$msg.To.Add(@("test@test.com"))
	$msg.Subject = "Exipiring Users"
	$msg.Body = $html
	$msg.isbodyhtml = $true
	$smtp.Send($msg)
}

Is there a way so it doesnt convert to military time?

Your username: blahblah expires on 04/19/2016 16:20:38.

***EDITED AT REQUEST OF POSTER*** – WA

April 12, 2016 at 11:44 am

This should convert a DateTime object.

$expireon = $user.passwordlastset.adddays(90)
$expireon = get-date -Date $expireon
# Result: Tuesday, April 19, 2016 4:20:38 PM

April 12, 2016 at 12:19 pm

You could reduce some redundancy like this:

Also, "administrator" is misspelled in $msg.Body.