Hello everyone - I've combined several VBS scripts and came up with a script that will provide user account status like the screenshots below.
The information will change based on whether the account is
- Enabled or Disabled
- Locked or Not Locked
- Password Expired or Not Expired
- Date Password was Changed
- Date Password Expires/Expired — # of days from now, if not yet expired
- (Maximum password age based on group policy)
- Whether or not the user can change their password, and after however many days the GPO says is the minimum pasword age.
Here's the VBS code named acctstat.vbs:
If WScript.Arguments.Count = 1 Then
struser = WScript.Arguments(0)
Set objUser = GetObject("LDAP://" & struser)
Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
Const ADS_ACETYPE_ACCESS_DENIED_OBJECT = &H6
Const CHANGE_PASSWORD_GUID = "{ab721a53-1e2f-11d0-9819-00aa0040529b}"
Set objSD = objUser.Get("nTSecurityDescriptor")
Set objDACL = objSD.DiscretionaryAcl
Set objUserLDAP = GetObject("LDAP://" & struser)
intCurrentValue = objUserLDAP.Get("userAccountControl")
strSAMAccountName = objUser.Get("sAMAccountName")
strCN = objUser.Get("cn")
Set objNet = CreateObject("WScript.NetWork")
dtmValue = objUserLDAP.PasswordLastChanged
intTimeInterval = int(now - dtmValue)
Set objDomainNT = GetObject("WinNT://" & objNet.UserDomain)
intMaxPwdAge = objDomainNT.Get("MaxPasswordAge")/86400
intMinPwdAge = objDomainNT.Get("MinPasswordAge")/86400
For Each Ace In objDACL
If ((Ace.AceType = ADS_ACETYPE_ACCESS_DENIED_OBJECT) And _
(LCase(Ace.ObjectType) = CHANGE_PASSWORD_GUID)) Then
blnEnabled = True
End If
Next
'Clear strMsg
strMsg = ""
'Account Disabled?
If objuser.AccountDisabled = True Then
MsgBox "This account is Disabled.",0,strCN & " (" & strSAMAccountName & ")"
Else
'Account Locked?
If objuser.IsAccountLocked = True Then
strMsg = strMsg & "This account is Enabled but Locked." & VbCrLf & VbCrLf
Else
strMsg = strMsg & "This account is Enabled and Not Locked." & VbCrLf & VbCrLf
End If
'Password Expires?
If intCurrentValue and ADS_UF_DONT_EXPIRE_PASSWD Then
strMsg = strMsg & "The Password Never Expires for this account due to account settings." & VbCrLf & _
" Password Changed: " & DateValue(dtmValue) & VBTab & int(now - dtmvalue) & " days ago" & VbCrLf & VbCrLf
Else
If intMaxPwdAge < 0 Then
strMsg = strMsg & "The Maximum Password Age is set to 0 in the domain. Therefore, the password does not expire." & VbCrLf & VbCrLf
Else
'Password Expired already?
If intTimeInterval >= intMaxPwdAge Then
strMsg = strMsg & "The password has Expired." & VbCrLf & _
" Password Changed: " & DateValue(dtmValue) & VBTab & int(now - dtmvalue) & " days ago" & VbCrLf & _
" Password Expires: " & DateValue(dtmValue + intMaxPwdAge) & VBTab & int(now - (dtmValue + intMaxPwdAge)) & " days ago" & VbCrLf & _
" (Maximum password age: " & intMaxPwdAge & " days)" & VbCrLf & VbCrLf
Else
strMsg = strMsg & "The password has Not Expired." & VbCrLf & _
" Password Changed: " & DateValue(dtmValue) & VBTab & int(now - dtmvalue) & " days ago" & VbCrLf & _
" Password Expires: " & DateValue(dtmValue + intMaxPwdAge) & VBTab & int((dtmValue + intMaxPwdAge) - now + 1) & " days from today" & VbCrLf & _
" (Maximum password age: " & intMaxPwdAge & " days)" & VbCrLf & VbCrLf
End If
End If
End If
'User can Change the Password?
If blnEnabled Then
strMsg = strMsg & strCN & " cannot change the password due to account settings."
Else
If intTimeInterval >= intMinPwdAge Then
strMsg = strMsg & strCN & " can change the password."
Else
strMsg = strMsg & strCN & " can change the password after " & DateValue(dtmValue) + intMinPwdAge & "." & VbCrLf & _
" (Minimum password age: "& intMinPwdAge & " days)"
End If
End If
'Display the Info
MsgBox strMsg,0,strCN & " (" & strSAMAccountName & ")"
End If
Else
WScript.Echo "Error"
End If
Set objNet = Nothing
Set objUser = Nothing
Set objSD = Nothing
Set objDACL = Nothing
Set objUserLDAP = Nothing
Set objDomainNT = Nothing
I'm not very good at VBS, so the code is probably pretty messy, but it works.
If the account is disabled, then the MsgBox will just show that the account is disabled and it'll skip the rest of the information. Otherwise, all of the information will be there.
I've added this custom action in LS Configuration under User actions:
Description -
Account StatusAction -
{actionpath}acctstat.vbs "{cn}"I hope others find it useful.
Jono
Update: 14-Dec-11My thanks to romwarrior for pointing out a problem in the code. I think I've corrected it; I added a line and edited a line to get the domain name programatically rather than having to hard code the domain name.
I've also added lines at the bottom of the code to release memory. Also, the title bar of the MsgBox now shows the User's common name along with their user ID.
Update: 19-Dec-11I've cleaned up the code a bit, added labels, and made the resulting displays a little easier to read at a quick glance. I had the results show the date that the password was changed even if the account settings are for the password to never expire; this info was skipped previously. I also added 4 screenshots to show 4 different results based on different account settings, password expirations, etc.
As always, I welcome feedback or tips on how to improve the code.