Page 1 of 1 1
Topic Options
#193695 - 2009-05-06 08:09 AM How to find out maxPwdAge from Domain
Sam_B Offline
Getting the hang of it

Registered: 2005-10-25
Posts: 68
Loc: Bern, Switzerland
Hello guys, once again I'm completely stuck and need help from you, the experts. I'm currently deploying a script that reads all users from a specific Ou to check out the password age of each user object. In case a password will expire soon in x days, the script sends a E-mail message to the user informing him/her about this.

Fist of all, I want to retrieve the domain password age policy by querying the AD via LDAP: (code borrowed from a VB scriptlet)

$strDomainDN = "YOURDOMAIN"
$strUserDN = strDomainDN + "/CN=John Doe,CN=Users,DC=YOURDOMAIN,DC=COM"

$oDomain = GetObject("LDAP://" + $strDomainDN)
$maxPwdAge = $oDomain.Get("maxPwdAge")

As I have learn(I might be wrong...), $maxPwdAge seems to be a integer8 object that I need to convert first to be able to use it in my script. I saw that fnInteger8Date() converts such kind of data type to YYYY/MM/DD HH:MM:SS format, but in this case I fail, because I assume that $maxPwdAge ist not a date, but a value...

in the VB example, the numDays is calculated via this:
'========================================
' Calculate the number of days that are
' held in this value.
'========================================
numDays = ((maxPwdAge.HighPart * 2 ^ 32) + _
maxPwdAge.LowPart) / -864000000000@

But I'm completely stuck how to manage such kind of operations in KIX....

Top
#193697 - 2009-05-06 08:50 AM Re: How to find out maxPwdAge from Domain [Re: Sam_B]
Arend_ Moderator Offline
MM club member
*****

Registered: 2005-01-17
Posts: 1894
Loc: Hilversum, The Netherlands
Could you paste the entire VBScript in code tags?
Top
#193698 - 2009-05-06 11:42 AM Re: How to find out maxPwdAge from Domain [Re: Arend_]
Arend_ Moderator Offline
MM club member
*****

Registered: 2005-01-17
Posts: 1894
Loc: Hilversum, The Netherlands
Nevermind, figured it out, here is your script:
 Code:
$=SetOption('Explicit','On')
Dim $objUser, $strUserDN, $objShell, $lngBiasKey, $lngBias, $k
Dim $objMaxPwdAge, $intMaxPwdAge, $intCurPwdAge
Dim $objDate, $dtmPwdLastSet, $lngFlag, $blnPwdExpire, $blnExpired
Dim $lngHighAge, $lngLowAge

Dim $ADS_UF_PASSWD_CANT_CHANGE, $ADS_UF_DONT_EXPIRE_PASSWD 
$ADS_UF_PASSWD_CANT_CHANGE = &40
$ADS_UF_DONT_EXPIRE_PASSWD = &10000

; Hard code user Distinguished Name.
$strUserDN = "CN=John Smith,OU=Users,DC=mydomain,DC=local"
$objUser = GetObject("LDAP://" + $strUserDN)

; Obtain local time zone bias from machine registry.
$lngBiasKey = ReadValue("HKLM\System\CurrentControlSet\Control\TimeZoneInformation","ActiveTimeBias")
$lngBias = CInt($lngBiasKey)

; Determine domain maximum password age policy in days.
Dim $objRootDSE, $strDNSDomain, $objDomain
$objRootDSE = GetObject("LDAP://RootDSE")
$strDNSDomain = $objRootDSE.Get("DefaultNamingContext")
$objDomain = GetObject("LDAP://" + $strDNSDomain)
$objMaxPwdAge = $objDomain.MaxPwdAge

; Account for bug in IADslargeInteger property methods.
$lngHighAge = $objMaxPwdAge.HighPart
$lngLowAge = $objMaxPwdAge.LowPart

If ($lngLowAge < 0)
  $lngHighAge = $lngHighAge + 1
EndIf

Dim $pow, $l
$Pow=2.0
For $l = 1 to 31 $Pow=2.0*$Pow Next
$intMaxPwdAge = -((CDBL($lngHighAge)*$Pow+$lngLowAge)/600000000-$lngBias)/1440
$intMaxPwdAge = Round($intMaxPwdAge)

; Retrieve user password information.
$objDate = $objUser.PwdLastSet
$dtmPwdLastSet = Integer8Date($objDate, $lngBias)
$intCurPwdAge = TimeDiff($dtmPwdLastSet, "Now", "d")
$lngFlag = $objUser.Get("userAccountControl")
$blnPwdExpire = 1
If (($lngFlag & $ADS_UF_PASSWD_CANT_CHANGE) <> 0)
  $blnPwdExpire = 0
EndIf
If (($lngFlag & $ADS_UF_DONT_EXPIRE_PASSWD) <> 0)
  $blnPwdExpire = 0
EndIf

; Determine if password expired.
$blnExpired = 0
If ($blnPwdExpire = 1)
  If $intCurPwdAge > $intMaxPwdAge
    $blnExpired = 1
  EndIf
EndIf

; Display password information.
? "User: "+$strUserDN
? "Password last set: "+$dtmPwdLastSet
? "Maximum password age (days): "+$intMaxPwdAge
? "Current password age (days): "+$intCurPwdAge
? "Can password expire? "+$blnPwdExpire
? "Password expired? "+$blnExpired

Function Integer8Date($objDate,$lngBias)
   Dim $lngHigh,$lngLow,$lngDate,$Pow,$l,$jdate,$lngYear,$lngMonth,$lngDay,$s,$m,$h
   If Not (VarType($objDate) & 9) Exit 87 EndIf
   If VarType($lngBias)=0
      $lngBias = Val(ReadValue("HKLM\System\CurrentControlSet\Control\TimeZoneInformation\","ActiveTimeBias"))
      If @ERROR Exit @ERROR EndIf
   EndIf
   
   $lngHigh = $objDate.HighPart 
   $lngLow = $objDate.LowPart 
   If $lngLow < 0 $lngHigh=$lngHigh+1 EndIf
   If $lngHigh = 0 And $lngLow = 0 $lngBias=0 EndIf
   $Pow=2.0
   For $l = 1 to 31 $Pow=2.0*$Pow Next
   $lngDate = ((CDBL($lngHigh)*$Pow+$lngLow)/600000000-$lngBias)/1440 
   If $lngDate > 0
      $jdate = 584389 + Fix($lngDate)
      $lngYear = (100*(((100*($jdate+306)-25)/3652425)-(((100*($jdate+306)-25)/3652425)/4))+
         (100*($jdate+306)-25))/36525 
      $lngMonth = (5*(((100*($jdate+306)-25)/3652425)-(((100*($jdate+306)-25)/3652425)/4)+
         ($jdate+306)-365*$lngYear-$lngYear/4)+456)/153 
      $lngDay = (((100*($jdate+306)-25)/3652425)-(((100*($jdate+306)-25)/3652425)/4)+
         ($jdate+306)-365*$lngYear-$lngYear/4)-(153*$lngMonth-457)/5 
      If $lngMonth>12 $lngYear=$lngYear+1 $lngMonth=$lngMonth-12 EndIf 
      $lngMonth = Right("0"+$lngMonth,2) 
      $lngDay = Right("0"+$lngDay,2) 
      
      $s = Fix(86400.0 * ($lngDate-Fix($lngDate)))
      $m = $s / 60
      $s = $s mod 60
      $h = $m / 60
      $m = $m mod 60
      $Integer8Date=''+$lngYear+'/'+$lngMonth+'/'+$lngDay+' '+$h+':'+Right("0"+$m,2)+':'+Right("0"+$s,2)
   EndIf
EndFunction

Function TimeDiff($_Start, OPTIONAL $_End, OPTIONAL $_Fmt, OPTIONAL $_MSec)
  Dim $_, $_SDate, $a_Start, $_EDate, $a_End, $_Duration

  ; Check for special START parameters
  Select
   Case $_Start = 'now'
    $_Start = @DATE + ' ' + @TIME + '.' + @MSECS
   Case $_START = 'today'
    $_Start = @DATE + ' 00:00:00.000'
  EndSelect

  ; Check for special END parameters
  Select
   Case $_End = 'now' Or $_End = ''
    $_End = @DATE + ' ' + @TIME + '.' + @MSECS
   Case $_End = 'today'
    $_End = @DATE + ' 00:00:00.000'
  EndSelect

  ; Validate parameters
  ; Parameters passed are "yyyy/mm/dd hh:mm:ss[.sss]" - make sure the default time is added
  $a_Start = Split(Join(Split(Join(Split($_Start + ' 00:00:00.000', '/'), ' '), ':'), ' '), ' ', 6)
  If UBound($a_Start) <> 5 Exit 87 EndIf		; bad start time parameter
  For $_ = 0 to 5
    $a_Start[$_] = CDbl($a_Start[$_])		; convert to numeric values
  Next

  $a_End = Split(Join(Split(Join(Split($_End + ' 00:00:00.000', '/'), ' '), ':'), ' '), ' ', 6)
  If UBound($a_End) <> 5 Exit 87 EndIf		; bad start time parameter
  For $_ = 0 to 5
    $a_End[$_] = CDbl($a_End[$_])		; convert to numeric values
  Next

  ; Convert dates to Days, then convert to seconds and add the time value
  If $a_Start[1] < 3
    $a_Start[1] = $a_Start[1] + 12
    $a_Start[0] = $a_Start[0] - 1
  EndIf
  $_SDate = $a_Start[2] + ( 153 * $a_Start[1] - 457 ) / 5 + 365 * $a_Start[0] + $a_Start[0] / 4 - $a_Start[0] / 100 + $a_Start[0] / 400 - 306
  $_SDate = CDbl($_SDate) * 86400.0
  $_SDate = $_SDate + $a_Start[3] * 3600 + $a_Start[4] * 60 + $a_Start[5]

  If $a_End[1] < 3
    $a_End[1] = $a_End[1] + 12
    $a_End[0] = $a_End[0] - 1
  EndIf
  $_EDate = $a_End[2] + ( 153 * $a_End[1] - 457 ) / 5 + 365 * $a_End[0] + $a_End[0] / 4 - $a_End[0] / 100 + $a_End[0] / 400 - 306
  $_EDate = CDbl($_EDate) * 86400.0
  $_EDate = $_EDate + $a_End[3] * 3600 + $a_End[4] * 60 + $a_End[5]

  ; Get the duration between the timestamps
  $_Duration = CDbl($_EDate - $_SDate)
 
  ; Trim fractional seconds if the MSec flag wasn't set
  ; Value returned is whole seconds
  If Not $_MSec
    $_Duration = CInt($_Duration)
  EndIf

  ; Return data as a Double - seconds (default), hours, minutes, days, or years
  Select
    Case $_Fmt = 'm'	; minutes
      $TimeDiff = $_Duration / 60.0
    Case $_Fmt = 'h'	; hours
      $TimeDiff = $_Duration / 3600.0
    Case $_Fmt = 'd'	; days
      $TimeDiff = $_Duration / 86400.0
    Case $_Fmt = 'y'	; years
      $TimeDiff = $_Duration / 31536000.0
    Case 1
      $TimeDiff = $_Duration
  EndSelect
  Exit 0
EndFunction


Edited by apronk (2009-05-06 12:04 PM)
Edit Reason: Added Glenn's TimeDiff Function

Top
#193708 - 2009-05-06 04:58 PM Re: How to find out maxPwdAge from Domain [Re: Arend_]
Sam_B Offline
Getting the hang of it

Registered: 2005-10-25
Posts: 68
Loc: Bern, Switzerland
Always amazing how fast you help me guys when I'm stuck, the codes is working perfect, exactly what I was searching for (and never had found out by myself due to my stupidity)Thank you very much!!!!
Top
#193723 - 2009-05-07 08:09 AM Re: How to find out maxPwdAge from Domain [Re: Sam_B]
Arend_ Moderator Offline
MM club member
*****

Registered: 2005-01-17
Posts: 1894
Loc: Hilversum, The Netherlands
You are very welcome \:\)
Top
Page 1 of 1 1


Moderator:  Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 242 anonymous users online.
Newest Members
SERoyalty, mytar, Gabriel, Alex_Evos, Dansen
17869 Registered Users

Generated in 0.053 seconds in which 0.022 seconds were spent on a total of 14 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org