Thanks to various sources I have a script which pops up a dialogue reminding the user they need to change their password (because the Windows 7 pop-up reminder is inadequate).
The idea is that it gets the next password reset date, then starts to prompt the user when there are five days to go and even after their password has expired if they've still not bothered.
The problem is that the script continues to prompt the user after they've changed their password. This is a really hard one to test because you need an account whose password is close to expiry...!
My password was close to expiry so I had the ideal candidate. I reset my password yesterday but this morning I still got the prompt, but I'm sure my code should prevent this from happening.
However, clearly I've been staring at the code for too long. Can anyone see what's wrong with it?
JJ
[small][purple]Variables won't. Constants aren't[/purple]
There is no apostrophe in the plural of PC (or PST, or CPU, or HDD, or FDD, or photo, or breakfast...and so on)[/small]
The idea is that it gets the next password reset date, then starts to prompt the user when there are five days to go and even after their password has expired if they've still not bothered.
The problem is that the script continues to prompt the user after they've changed their password. This is a really hard one to test because you need an account whose password is close to expiry...!
My password was close to expiry so I had the ideal candidate. I reset my password yesterday but this morning I still got the prompt, but I'm sure my code should prevent this from happening.
However, clearly I've been staring at the code for too long. Can anyone see what's wrong with it?
Code:
option explicit
REM Credit where credit is due. This is where we got it from: [URL unfurl="true"]http://community.spiceworks.com/scripts/show/1594-password-expiration-pop-up-for-windows-7[/URL]
REM but I have also seen it here: [URL unfurl="true"]http://social.technet.microsoft.com/Forums/en-US/w7itprogeneral/thread/1a172f70-4733-4c83-847e-3d017a2e78bf/[/URL]
' Changes:
' v1.01 - First test version
' v1.02 - Bugfix: The window still pops up even after the password has been changed! This only seems to occur on Citrix, so we'll test for that...
' v1.03 - Bugfix: The window STILL pops up even after the password has been changed and DOESN'T only occur on Citrix. Attempting to fix this by having the script call itself then quit the current instance.
Dim objWSHShell : Set objWSHShell = CreateObject("WScript.Shell")
Dim strHostRole : strHostRole = objWSHShell.ExpandEnvironmentStrings("%ServerRole%")
if strHostRole="Citrix" then
'wscript.echo "User has logged on to a Citrix server. Quitting!"
Set objWSHShell = Nothing
wscript.quit
Else
'wscript.echo "User has logged on to a non-Citrix machine. Continuing..."
End If
'========================================
' First, get the domain policy.
'========================================
Dim objDomain
Dim objUserDN
Dim objMaxPwdAge
Dim numDays
Dim warningDays : warningDays = 7 ' This should be effectively 7 days as day one = zero
Dim strVersion : strVersion = "1.03beta"
Dim strTitle : strTitle = "Password Expiry Warning (v" & strVersion & ")"
Dim objLoginInfo
Dim objUser
Dim strDomainDN
Dim strUserDN
Dim intUserAccountControl
Dim Msg
Dim strDayOrDays : strDayOrDays = "days"
Dim FiveDays : FiveDays = 432000000 '= A five day week in milliseconds (432000000)
Dim SevenDays : SevenDays = 604800000 '= Seven days
Dim OneDay : OneDay = 86400000 '= One day
Dim OneHour : OneHour = 3600000 '= One hour
Dim ThirtyMinutes : ThirtyMinutes = 1800000 '= 30 minutes
Dim FifteenMinutes : FifteenMinutes = 900000 '= 15 minutes
Dim FiveMinutes : FiveMinutes = 300000 '= Five minutes
Dim OneMinute : OneMinute = 60000 '= One minute
Dim ThirtySeconds : ThirtySeconds = 30000
Dim TenSeconds : TenSeconds = 10000
Dim FiveSeconds : FiveSeconds = 5000
Dim OneSecond : OneSecond = 1000
Dim PrimaryWaitTime : PrimaryWaitTime = OneDay
'WSCRIPT.ECHO "Wait time = " & PrimaryWaitTime/1000 & " seconds"
Dim n ' which will always be null as we want the script to loop forever.
Set objLoginInfo = CreateObject("ADSystemInfo")
Set objUser = GetObject("LDAP://" & objLoginInfo.UserName & "")
strDomainDN = UCase(objLoginInfo.DomainDNSName)
strUserDN = objLoginInfo.UserName
'========================================
' Check if password is non-expiring.
'========================================
Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
intUserAccountControl = objUser.Get("userAccountControl")
Set objDomain = GetObject("LDAP://" & strDomainDN)
Set objMaxPwdAge = objDomain.Get("MaxPwdAge")
'========================================
' Calculate the number of days that are
' held in this value.
'========================================
numDays = CCur((objMaxPwdAge.HighPart * 2 ^ 32) + objMaxPwdAge.LowPart) / CCur(-864000000000)
'WScript.Echo "Maximum Password Age: " & numDays
'========================================
' Determine the last time that the user
' changed his or her password.
'========================================
Set objUserDN = GetObject("LDAP://" & strUserDN)
'========================================
' Add the number of days to the last time
' the password was set.
'========================================
Call Main
Sub Main
do while n<1
Dim whenPasswordExpires : whenPasswordExpires = DateAdd("d", numDays, objUserDN.PasswordLastChanged)
Dim fromDate : fromDate = Date
Dim daysLeft : daysLeft = DateDiff("d",fromDate,whenPasswordExpires)
If intUserAccountControl And ADS_UF_DONT_EXPIRE_PASSWD Then
'WScript.Echo "The password does not expire."
wscript.quit
Else
'WScript.Echo "Password Last Changed: " & objUserDN.PasswordLastChanged
'daysLeft = 3
'wscript.echo "daysLeft = '" & daysLeft & "'"
if daysLeft > -1 then
if daysLeft < warningDays then
If daysLeft = 0 then
bSevenDaysReminded = FALSE
Msg = "YOUR PASSWORD EXPIRES WITHIN THE NEXT 24 HOURS!" & vbCrLf & "(on " & whenPasswordExpires & ")" & vbCrLf & vbCrLf & "When you're in the office, please log out of the Cloud (or ask IT to terminate your session for you) then, on your PC, press" & vbCrLf & "CTRL + ALT + DEL and select the 'Change password' option." & vbCrLf & vbCrLf &_
"If you also get your email delivered to your iPhone/Smartphone/Tablet, you'll have to update the password for the email account there as well." & vbCrLf & vbCrLf &_
"IT Support" & vbCrLf &_
"x1234" & vbCrLf &_
"support@domain.com"
'wscript.echo msg
Msgbox Msg,vbCritical,strTitle
ElseIf (daysLeft > 0) and (daysLeft < 3) then
bSevenDaysReminded = FALSE
If daysLeft = 1 then strDayOrDays="day" end if
Msg = "Your password will expire in " & daysLeft & " " & strDayOrDays & " at " & whenPasswordExpires & "." & vbCrLf & vbCrLf & "When you're in the office, please log out of the Cloud (or ask IT to terminate your session for you) then, on your PC, press" & vbCrLf & "CTRL + ALT + DEL and select the 'Change password' option." & vbCrLf & vbCrLf &_
"If you also get your email delivered to your iPhone/Smartphone/Tablet, you'll have to update the password for the email account there as well." & vbCrLf & vbCrLf &_
"IT Support" & vbCrLf &_
"x1234" & vbCrLf &_
"support@domain.com"
'wscript.echo msg
Msgbox Msg,vbExclamation,strTitle
Else
Dim bSevenDaysReminded
' We don't want to warn users every single day when there's a week to go,
' so we warn them once at seven days then not again until there's three days left
' with the help of this flag, which is reset to FALSE when this IF loop "if daysLeft < warningDays"
' detects 2, 1 or 0 days left:
If bSevenDaysReminded = FALSE then
bSevenDaysReminded = TRUE
Msg = "Your password will expire in " & daysLeft & " days" & " at " & whenPasswordExpires & "." & vbCrLf & vbCrLf & "When you're in the office, please log out of the Cloud (or ask IT to terminate your session for you) then, on your PC, press" & vbCrLf & "CTRL + ALT + DEL and select the 'Change password' option." & vbCrLf & vbCrLf &_
"If you also get your email delivered to your iPhone/Smartphone/Tablet, you'll have to update the password for the email account there as well." & vbCrLf & vbCrLf &_
"IT Support" & vbCrLf &_
"x1234" & vbCrLf &_
"support@domain.com"
'wscript.echo msg
Msgbox Msg,vbExclamation,strTitle
Else
'wscript.echo "User already reminded..."
End If
End If
End If
Else
'Do I need to reset the password expiry date here?
Msg = "IT APPEARS YOUR PASSWORD HAS ALREADY EXPIRED!" & vbCrLf &_
"(Password Expiry Date: " & whenPasswordExpires & ")" & vbCrLf & vbCrLf & "When you're in the office, please log out of the Cloud (or ask IT to terminate your session for you) then, on your PC, press" & vbCrLf & "CTRL + ALT + DEL and select the 'Change password' option." & vbCrLf & vbCrLf &_
"If you also get your email delivered to your iPhone/Smartphone/Tablet, you'll have to update the password for the email account there as well." & vbCrLf & vbCrLf &_
"IT Support" & vbCrLf &_
"x1234" & vbCrLf &_
"support@domain.com"
'wscript.echo msg
Msgbox Msg,vbCritical,strTitle
'Now run a new instance of this script...
objWSHShell.Run WScript.ScriptFullName
' ...tidy up a bit...
Set objWSHShell = Nothing
Set objUserDN = Nothing
Set objUser = Nothing
Set objMaxPwdAge = Nothing
Set objDomain = Nothing
Set objLoginInfo = Nothing
' ...and quit.
wscript.quit
End if
End if
wscript.sleep(PrimaryWaitTime)
REM Dim i : i = PrimaryWaitTime/1000
REM Do While i>=0
REM wscript.sleep(1000)
REM wscript.echo i
REM i = i-1
REM Loop
Loop
End Sub
'========================================
' Clean up.
'========================================
Set objWSHShell = Nothing
Set objUserDN = Nothing
Set objUser = Nothing
Set objMaxPwdAge = Nothing
Set objDomain = Nothing
Set objLoginInfo = Nothing
JJ
[small][purple]Variables won't. Constants aren't[/purple]
There is no apostrophe in the plural of PC (or PST, or CPU, or HDD, or FDD, or photo, or breakfast...and so on)[/small]