Improved pwdLastSet--has better error handling.
Option Explicit Const LocalTimeZone = "PT" Const AppTitle = "Password Last Changed" Dim ADsPath ADsPath = WScript.Arguments.Named.Item("ADsPath") If ADsPath = "" Then MsgBox "Enter a username.", , AppTitle Else ShowPasswordLastChanged ADsPath End If Sub ShowPasswordLastChanged(ADsPath) Dim User, PasswordLastChanged, Message Set User = GetObject(ADsPath) PasswordLastChanged = GetLocal(User) 'PasswordLastChanged = GetUTC(User) If PasswordLastChanged = "" Then Message = " must change password at next logon." Else Message = vbCrLf & " Password Last Changed: " & PasswordLastChanged End If MsgBox User.samAccountName & " (" & User.cn & ")" & Message, , AppTitle 'MsgBox User.PasswordExpirationDate, , AppTitle ' This can take a long time to come up. End Sub Function GetLocal(User) Const E_ADS_PROPERTY_NOT_FOUND = &H8000500D On Error Resume Next GetLocal = User.PasswordLastChanged If Err.Number = E_ADS_PROPERTY_NOT_FOUND Then GetLocal = "" Else GetLocal = GetLocal & " " & LocalTimeZone End If End Function Function GetUTC(User) GetUTC = DecodeLargeInt(User.pwdLastSet) If GetUTC = 0 Then GetUTC = "" Else GetUTC = GetUTC & " UTC" End If End Function Function DecodeLargeInt(LgInt) Dim dVal Const Ticks_per_sec = 10000000 ' 1E7. 1 tick = 100 nanoseconds Const Tick_start_date = #1/1/1601# Const MinuteInterval = "n" ' "n" is Minute ("m" is Month) Const SecondInterval = "s" ' See Correction in Community Content section under http://msdn.microsoft.com/en-us/library/aa706038 dVal = LgInt.HighPart * 2 ^ 32 + (LgInt.LowPart Xor &H80000000) + 2 ^ 31 If (LgInt.HighPart = -2147483648 And LgInt.LowPart = 0) Or (LgInt.HighPart = 2147483647 And LgInt.LowPart = -1) Then DecodeLargeInt = "(never)" ElseIf dVal > 1E+17 And dVal < 2E+17 Then ' Assume dVal represents a Date between Nov 1917 and Oct 2234. Dim ticks, seconds, minutes ticks = dVal ' dVal contains 100-nanosecond intervals (ticks) since Jan 1, 1601. seconds = ticks / Ticks_per_sec ' DateAdd() converts the 2nd argument to a Long. Passing in seconds will overflow, so use minutes even though there's some rounding. minutes = CLng(seconds / 60) DecodeLargeInt = DateAdd(SecondInterval, seconds - minutes * 60, DateAdd(MinuteInterval, minutes, Tick_start_date)) Else DecodeLargeInt = dVal ' Assume it's a Large Int, not a Date. End If End Function