Monday, April 23, 2007

Password Reminder updated!

I made some small (but significant) changes to the Password Reminder console application. First of all, it's useless to send disabled users a reminder to change their password eh? So I changed my code that only the 'not-disabled' users are notified. The property you need to query for this is : userAccountControl and it returns an integer. I used the following chart http://support.microsoft.com/kb/305144 to come up with the integer value of 544 to only get a non-disabled user.
The code below is the function that determines per user whether when his/her password will expire and if the user is enabled/disabled. If the password is about to expire within 20 days, an email will be sent to notify the user that their password must be changed.

public static void GetAccountExpiration(CUser user)

{

try

{

string LogUser = user.UserName;

DirectoryEntry entry = new DirectoryEntry("LDAP://DOMAINSERVER");

DirectorySearcher search = new DirectorySearcher(entry);

search.Filter = "(SAMAccountName=" + LogUser + ")";

SearchResult LDAPresult = search.FindOne();

entry = LDAPresult.GetDirectoryEntry();

//This int will tell us if the user is disabled yes or no

int disabled = Convert.ToInt32(entry.Properties["userAccountControl"].Value.ToString());

// Pulling the informtion on when the password was last changed and converting it to a LargeInteger.

LargeInteger liAcctPwdChange = entry.Properties["pwdLastSet"].Value as LargeInteger;

// Convert the highorder/loworder parts of the property pulled to a long.

long dateAcctPwdChange = (((long)(liAcctPwdChange.HighPart) << 32) + (long)liAcctPwdChange.LowPart);

// Convert FileTime to DateTime and get what today's date is.

DateTime dtNow = DateTime.Now;

// I added 90 days because I know what my password expiration is set to, if not you need to pull that information and add the number of days it is set for.

CultureInfo ci = new CultureInfo("nl-NL");

DateTime dtAcctPwdChange = DateTime.FromFileTime(dateAcctPwdChange).AddDays(180);

string strAcctPwdChange = DateTime.FromFileTime(dateAcctPwdChange).ToString("d",ci);

string strAcctPwdExpires = DateTime.FromFileTime(dateAcctPwdChange).AddDays(180).ToString("d",ci);

// Calculate the difference between the date the pasword was changed, and what day it is now and display the # of days.

TimeSpan time;

time = dtAcctPwdChange - dtNow;

if (time.Days < 20 && time.Days >= 0)

{

if (disabled == 544)

{

Console.WriteLine(user.FirstName + " " + user.LastName + " " + user.EmailAddress + " " + "Password changed: " + strAcctPwdChange + " Password expires: " + strAcctPwdExpires + " There are " + time.Days.ToString()+ " days left");

WebMail mail = new WebMail();

mail.To = user.EmailAddress;

mail.From = "";

mail.Subject = "Password expiration";

mail.Body = "" +

"<style>table {margin: 20px; border: 2 inset #efefff; background-color: #efefff; } td {font-family: verdana; font-size: 10px; color: #444444; font-weight: normal} .label {width:200px; font-weight: bold;} .title {font-weight: bold; font-size:14px; align: center;}</style>" +

"<table cellspacing=10 cellpadding=0>" +

"<tr><td colspan=2 class=title>Password expiration</td></tr>" +

"<tr><td class=label>Dear "+user.FirstName + " "+user.LastName +" , <BR><BR>your password is about to expire. You've last changed your password on " + strAcctPwdChange + ". Your password will expire or is expired on " + strAcctPwdExpires + ".<br></td></tr></table>";

mail.SendMessage();

}

}

}

catch(Exception error)

{

Console.WriteLine(error.Message.ToString());

}

}


 

And there you have it! Btw if you are wondering why on earth I created this console app.. Well, in the Sharepoint2003 time we did not have the luxury of formsbased authentication for our internet users so we created an extranet domain which could be administrated via the web. And when an user logons to Sharepoint there was no easy task of telling the user that his or her password was about to expire, even if it was possible, not every user logged on every day/week so the idea came to notify the user by email.

6 comments:

Kimulus said...

I wonder how to use this script? I would need similar thing in our environment (we do not use Sharepoint) and I would like to make this standalone.

Paramesh said...

I am also looking similar tool for a workgroup server.

Mike G. said...

Why not use Password Reminder PRO from www.sysoptools.com? It works excellent, sends multiple reminders to the correct types of user accounts only, allows customization fo the reminder messages, includes a daily summary report of reminders sent for the day, identifies misconfigured user accounts, and includes a report console for ez audit of all user accounts. No scripting required, runs on a standalone server. just my 2c... the solution exists.

Anonymous said...

I came across this code and it looks to be very helpful. Question though, what is the 'CUser' in the line 'public static void GetAccountExpiration(CUser user)'

I've been getting an error at this point and am having trouble figuring out why.

thanks

Brent Blades said...

Why use this and not Password Reminder Pro? This is free and has no user limits, and that software is $300 for 100 users max.

electronic signature said...

Excellent! Thanks for this - I've been looking at this feature for ages. Followed your instructions and it works a treat!