Discussion:
script to detect password expiration for local account
(too old to reply)
cybercoaster
2009-04-02 17:30:02 UTC
Permalink
Hello,

I am looking for a script that can dump the expiration date of all local user
accounts. The only scripts I can seem to locate deal with one user and for
Active Directory. Can anyone point me in the right direction?

Thanks.
Richard Mueller [MVP]
2009-04-02 18:27:11 UTC
Permalink
Post by cybercoaster
Hello,
I am looking for a script that can dump the expiration date of all local user
accounts. The only scripts I can seem to locate deal with one user and for
Active Directory. Can anyone point me in the right direction?
Thanks.
You must use the WinNT provider with local user accounts. You can use the
maxPasswordAge and passwordAge properties (both in seconds) to determine
when the password will expire (or if it is already expired). In addition,
you should use the userFlags property to check if the password can expire
for the user. For example (not tested):
====
Option Explicit

Dim objNetwork, strComputer, objComputer, objUser, lngFlag
Dim lngMaxPwdAge, lngPwdAge, dtmExpire

Const ADS_UF_PASSWD_CANT_CHANGE = &H10
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000

' Retrieve NetBIOS name of local computer.
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName

' Bind to local computer object.
Set objComputer = GetObject("WinNT://" & strComputer)

' Filter on user objects.
objComputer.Filter = Array("user")

' Enumerate all local users.
For Each objUser In objComputer
' Retrieve values.
lngFlag = objUser.userFlags
lngMaxPwdAge = CLng(objUser.maxPasswordAge / 86400)
lngPwdAge = Clng(objUser.passwordAge / 86400)
' Check if password can expire or be changed.
If (lngFlag And ADS_UF_PASSWD_CANT_CHANGE) <> 0 Then
Wscript.Echo objUser.Name & ",<Password cannot change>"
ElseIf(lngFlag And ADS_UF_DONT_EXPIRE_PASSWD) <> 0 Then
Wscript.Echo objUser.Name & ",<Password does not expire>"
ElseIf (lngMaxPwdAge > lngPwdAge) Then
' Calculate when password will expire.
dtmExpire = DateAdd("d", Now(), lngMaxPwdAge - lngPwdAge)
Wscript.Echo objUser.Name & "," & dtmExpire
Else
Wscript.Echo objUser.Name & ",<Password expired>"
End If
Next
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--
cybercoaster
2009-04-02 19:23:09 UTC
Permalink
Thanks, that looks promising. I am pretty green on scripts and cant get this
to run. Trying to figure it out now (getting Expected end of statement). I
found some other examples on
http://www.microsoft.com/technet/scriptcenter/resources/qanda/apr07/hey0419.mspx
but those come back saying all the account dont expire. I even created a test
user and it didnt say it expired - although I know they do. Yours looks like
it does the actual date calculations is what I need.
Post by cybercoaster
Hello,
[quoted text clipped - 4 lines]
Post by cybercoaster
Thanks.
You must use the WinNT provider with local user accounts. You can use the
maxPasswordAge and passwordAge properties (both in seconds) to determine
when the password will expire (or if it is already expired). In addition,
you should use the userFlags property to check if the password can expire
====
Option Explicit
Dim objNetwork, strComputer, objComputer, objUser, lngFlag
Dim lngMaxPwdAge, lngPwdAge, dtmExpire
Const ADS_UF_PASSWD_CANT_CHANGE = &H10
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
' Retrieve NetBIOS name of local computer.
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
' Bind to local computer object.
Set objComputer = GetObject("WinNT://" & strComputer)
' Filter on user objects.
objComputer.Filter = Array("user")
' Enumerate all local users.
For Each objUser In objComputer
' Retrieve values.
lngFlag = objUser.userFlags
lngMaxPwdAge = CLng(objUser.maxPasswordAge / 86400)
lngPwdAge = Clng(objUser.passwordAge / 86400)
' Check if password can expire or be changed.
If (lngFlag And ADS_UF_PASSWD_CANT_CHANGE) <> 0 Then
Wscript.Echo objUser.Name & ",<Password cannot change>"
ElseIf(lngFlag And ADS_UF_DONT_EXPIRE_PASSWD) <> 0 Then
Wscript.Echo objUser.Name & ",<Password does not expire>"
ElseIf (lngMaxPwdAge > lngPwdAge) Then
' Calculate when password will expire.
dtmExpire = DateAdd("d", Now(), lngMaxPwdAge - lngPwdAge)
Wscript.Echo objUser.Name & "," & dtmExpire
Else
Wscript.Echo objUser.Name & ",<Password expired>"
End If
Next
Richard Mueller [MVP]
2009-04-02 20:36:49 UTC
Permalink
I suspect word wrapping broke up one or more lines in the program I posted.
I ran the program before I posted it and got no such error. I've tested
again and it works for me.

The error you got indicates that one or more statements was wrapped onto two
lines. The error message should have indicated a line number, which helps to
troubleshoot.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--
Post by cybercoaster
Thanks, that looks promising. I am pretty green on scripts and cant get this
to run. Trying to figure it out now (getting Expected end of statement). I
found some other examples on
http://www.microsoft.com/technet/scriptcenter/resources/qanda/apr07/hey0419.mspx
but those come back saying all the account dont expire. I even created a test
user and it didnt say it expired - although I know they do. Yours looks like
it does the actual date calculations is what I need.
Post by cybercoaster
Hello,
[quoted text clipped - 4 lines]
Post by cybercoaster
Thanks.
You must use the WinNT provider with local user accounts. You can use the
maxPasswordAge and passwordAge properties (both in seconds) to determine
when the password will expire (or if it is already expired). In addition,
you should use the userFlags property to check if the password can expire
====
Option Explicit
Dim objNetwork, strComputer, objComputer, objUser, lngFlag
Dim lngMaxPwdAge, lngPwdAge, dtmExpire
Const ADS_UF_PASSWD_CANT_CHANGE = &H10
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
' Retrieve NetBIOS name of local computer.
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
' Bind to local computer object.
Set objComputer = GetObject("WinNT://" & strComputer)
' Filter on user objects.
objComputer.Filter = Array("user")
' Enumerate all local users.
For Each objUser In objComputer
' Retrieve values.
lngFlag = objUser.userFlags
lngMaxPwdAge = CLng(objUser.maxPasswordAge / 86400)
lngPwdAge = Clng(objUser.passwordAge / 86400)
' Check if password can expire or be changed.
If (lngFlag And ADS_UF_PASSWD_CANT_CHANGE) <> 0 Then
Wscript.Echo objUser.Name & ",<Password cannot change>"
ElseIf(lngFlag And ADS_UF_DONT_EXPIRE_PASSWD) <> 0 Then
Wscript.Echo objUser.Name & ",<Password does not expire>"
ElseIf (lngMaxPwdAge > lngPwdAge) Then
' Calculate when password will expire.
dtmExpire = DateAdd("d", Now(), lngMaxPwdAge - lngPwdAge)
Wscript.Echo objUser.Name & "," & dtmExpire
Else
Wscript.Echo objUser.Name & ",<Password expired>"
End If
Next
cybercoaster via WinServerKB.com
2009-04-03 13:32:59 UTC
Permalink
Yip, I did find the errors. Thanks so much for your help!
Post by Richard Mueller [MVP]
I suspect word wrapping broke up one or more lines in the program I posted.
I ran the program before I posted it and got no such error. I've tested
again and it works for me.
The error you got indicates that one or more statements was wrapped onto two
lines. The error message should have indicated a line number, which helps to
troubleshoot.
Post by cybercoaster
Thanks, that looks promising. I am pretty green on scripts and cant get this
[quoted text clipped - 56 lines]
Post by cybercoaster
Post by Richard Mueller [MVP]
End If
Next
--
Message posted via http://www.winserverkb.com
cybercoaster via WinServerKB.com
2009-04-03 13:32:48 UTC
Permalink
Yip, I did find the errors. Thanks so much for your help!
Post by Richard Mueller [MVP]
I suspect word wrapping broke up one or more lines in the program I posted.
I ran the program before I posted it and got no such error. I've tested
again and it works for me.
The error you got indicates that one or more statements was wrapped onto two
lines. The error message should have indicated a line number, which helps to
troubleshoot.
Post by cybercoaster
Thanks, that looks promising. I am pretty green on scripts and cant get this
[quoted text clipped - 56 lines]
Post by cybercoaster
Post by Richard Mueller [MVP]
End If
Next
--
Message posted via http://www.winserverkb.com
cybercoaster via WinServerKB.com
2009-04-03 14:09:29 UTC
Permalink
To expand a little further on this script, can it pull last user logon date?
I looked at the ADS_USER_FLAG_ENUM at
http://msdn.microsoft.com/en-us/library/aa772300.aspx but dont see that value
there.
Post by Richard Mueller [MVP]
I suspect word wrapping broke up one or more lines in the program I posted.
I ran the program before I posted it and got no such error. I've tested
again and it works for me.
The error you got indicates that one or more statements was wrapped onto two
lines. The error message should have indicated a line number, which helps to
troubleshoot.
Post by cybercoaster
Thanks, that looks promising. I am pretty green on scripts and cant get this
[quoted text clipped - 56 lines]
Post by cybercoaster
Post by Richard Mueller [MVP]
End If
Next
--
Message posted via WinServerKB.com
http://www.winserverkb.com/Uwe/Forums.aspx/windows-server-scripting/200904/1
Richard Mueller [MVP]
2009-04-03 14:43:36 UTC
Permalink
You can retrieve the lastLogin attribute of the user object. However, an
error is raised if the user has never logged in. You can trap the error, for
example:
===========
Dim dtmLastLogin

' Enumerate all local users.
For Each objUser In objComputer
' Retrieve values.
lngFlag = objUser.userFlags
lngMaxPwdAge = CLng(objUser.maxPasswordAge / 86400)
lngPwdAge = Clng(objUser.passwordAge / 86400)
On Error Resume Next
dtmLastLogin = objUser.lastLogin
If (Err.Number <> 0) Then
dtmLastLogin = "<Never>"
End If
On Error GoTo 0
' Check if password can expire or be changed.
If (lngFlag And ADS_UF_PASSWD_CANT_CHANGE) <> 0 Then
Wscript.Echo objUser.Name & ",<Password cannot change>," &
dtmLastLogin
ElseIf(lngFlag And ADS_UF_DONT_EXPIRE_PASSWD) <> 0 Then
Wscript.Echo objUser.Name & ",<Password does not expire>," &
dtmLastLogin
ElseIf (lngMaxPwdAge > lngPwdAge) Then
' Calculate when password will expire.
dtmExpire = DateAdd("d", Now(), lngMaxPwdAge - lngPwdAge)
Wscript.Echo objUser.Name & "," & dtmExpire & "," & dtmLastLogin
Else
Wscript.Echo objUser.Name & ",<Password expired>," & dtmLastLogin
End If
Next
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--
Post by cybercoaster via WinServerKB.com
To expand a little further on this script, can it pull last user logon date?
I looked at the ADS_USER_FLAG_ENUM at
http://msdn.microsoft.com/en-us/library/aa772300.aspx but dont see that value
there.
Post by Richard Mueller [MVP]
I suspect word wrapping broke up one or more lines in the program I posted.
I ran the program before I posted it and got no such error. I've tested
again and it works for me.
The error you got indicates that one or more statements was wrapped onto two
lines. The error message should have indicated a line number, which helps to
troubleshoot.
Post by cybercoaster
Thanks, that looks promising. I am pretty green on scripts and cant get this
[quoted text clipped - 56 lines]
Post by cybercoaster
Post by Richard Mueller [MVP]
End If
Next
--
Message posted via WinServerKB.com
http://www.winserverkb.com/Uwe/Forums.aspx/windows-server-scripting/200904/1
cybercoaster via WinServerKB.com
2009-04-16 15:02:16 UTC
Permalink
Been hectic around here, just wanted to drop a big thank you for your help!
The script works perfect!
Post by Richard Mueller [MVP]
You can retrieve the lastLogin attribute of the user object. However, an
error is raised if the user has never logged in. You can trap the error, for
===========
Dim dtmLastLogin
' Enumerate all local users.
For Each objUser In objComputer
' Retrieve values.
lngFlag = objUser.userFlags
lngMaxPwdAge = CLng(objUser.maxPasswordAge / 86400)
lngPwdAge = Clng(objUser.passwordAge / 86400)
On Error Resume Next
dtmLastLogin = objUser.lastLogin
If (Err.Number <> 0) Then
dtmLastLogin = "<Never>"
End If
On Error GoTo 0
' Check if password can expire or be changed.
If (lngFlag And ADS_UF_PASSWD_CANT_CHANGE) <> 0 Then
Wscript.Echo objUser.Name & ",<Password cannot change>," &
dtmLastLogin
ElseIf(lngFlag And ADS_UF_DONT_EXPIRE_PASSWD) <> 0 Then
Wscript.Echo objUser.Name & ",<Password does not expire>," &
dtmLastLogin
ElseIf (lngMaxPwdAge > lngPwdAge) Then
' Calculate when password will expire.
dtmExpire = DateAdd("d", Now(), lngMaxPwdAge - lngPwdAge)
Wscript.Echo objUser.Name & "," & dtmExpire & "," & dtmLastLogin
Else
Wscript.Echo objUser.Name & ",<Password expired>," & dtmLastLogin
End If
Next
Post by cybercoaster via WinServerKB.com
To expand a little further on this script, can it pull last user logon date?
[quoted text clipped - 19 lines]
Post by cybercoaster via WinServerKB.com
Post by Richard Mueller [MVP]
End If
Next
--
Message posted via WinServerKB.com
http://www.winserverkb.com/Uwe/Forums.aspx/windows-server-scripting/200904/1
Loading...