Tuesday, July 04, 2006

Password Reminder

Ok, what happens when you have a Sharepoint extranet environment? Right! Users don't get prompted or reminded that they have to change their password within a couple of days. So there are several solutions to overcome this problem: 1. Create a console application that is scheduled to run every day to check if an user's password is about to expire. If expiration is due, for example, 10 days. An email is sent to the user which will remind the user to change their password. 2. Create a webpart that checks and displays the remaining time that a password needs to be changed. Well solution 1 is near finished and I must say that the part that took most of my time was interfacing with Active Directory to find out when a password was about to expire. It turned out to be the following property : pwdLastSet. The return value of this property was of the following type LargeInteger. I used the solution which I found at .Net Directory Services Programming - C# - Part 1 in the comments section :) See the following code that takes user class

public static void GetAccountExpiration(CUser user) { try { string LogUser = user.UserName; DirectoryEntry entry = new DirectoryEntry("LDAP://domain"); DirectorySearcher search = new DirectorySearcher(entry); search.Filter = "(SAMAccountName=" + LogUser + ")"; SearchResult LDAPresult = search.FindOne(); entry = LDAPresult.GetDirectoryEntry(); // 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(#number of days that is set in the AD group policy); string strAcctPwdChange = DateTime.FromFileTime(dateAcctPwdChange).ToString("d",ci); string strAcctPwdExpires = DateTime.FromFileTime(dateAcctPwdChange).AddDays(#number of days that is set in the AD group policy).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 < 10) { WebMail mail = new WebMail(); mail.To = user.EmailAddress; mail.From = "admin"; mail.Subject = "Password expiration"; mail.Body = "Dear user.UserFirstName,
you've changed your password for the last time on strAcctPwdChange.
Your password is about to expire on strAcctPwdExpires.
Please change your password as soon as possible"; mail.SendMessage(); } } catch { } }
As you can see the, this is all to it. Just write a function to get all the users and put their usernames through this function ;) I got all my users from a database from another application where I administer the users. I almost forgot to mention you have to reference "activeds.tlb" in the system32 directory and then add 'using ActiveDs' in your project. Solution no2 is being worked on and it's not very different from the first solution. I can use most of the function that is described above.

No comments: