It just so happens that I have a script that runs every Monday morning that checks for expired, locked, and about-to-expire accounts. It generates a report and emails the report to specific users. Since this does 173% of what you need, I've posted it here and you can remove the unwanted parts and customize it to your specific needs..

The core pieces are there - look for accounts that are locked, send email. \:\)

Glenn


;; KixGenerated: 2008/10/22 10:00:32 
Break On
 
Dim $Members, $Member			; array of domain user members, enumerator var 
Dim $I					; index var 
Dim $objUser				; AD user query object pointer 
Dim $Flags				; user flags 
Dim $ExpDate, $Days			; expiration date, days remaining 
Dim $LStat, $EStat			; locked and Expired status flags 
Dim $RptData[0], $R			; report array, record pointer 
Dim $Header				; report page header 
Dim $MaxDays				; max days before expiration 
Dim $MailTo, $MailSender, $MailServer	; mail parameters 
Dim $BlatCmd				; Blat command string 
 
$MaxDays = 10				; passwords expiring within 10 days 
 
; get array of user accounts 
'Collecting'
$Members = GroupMembers(@DOMAIN, 'Domain Users', 2)
Chr(13) 'Reporting ' ?
 
$R = -1
 
; header 
;00000000011111111112222222222333333333344444444445555555555666666666677777777778 
;12345678901234567890123456789012345678901234567890123456789012345678901234567890 
$Header = 'UserID         UserName                                Locked? Expired?' + @CRLF
$Header = $Header + '  Expiration date' + @CRLF
$Header = $Header + '===============================================================================' + @CRLF
 
For Each $Member In $Members
 
  ; get specific user data 
  $objUser = GetObject('WinNT://' + @DOMAIN + '/' +$Member + ',user')
 
  ; read flags 
  $Flags = $objUser.UserFlags 
 
  ; if not disabled, and not Never Expires, report on expired or about to expire accounts 
  If Not $objUser.AccountDisabled And Not ($Flags & 65536)
    $ExpDate = FixDate($objUser.PasswordExpirationDate)
    $Days = Int(TimeDiff('Now', $ExpDate, 'D'))
    $LStat = $objUser.IsAccountLocked
    $EStat = $objUser.PasswordExpired
    If $EStat Or $LStat Or $Days < 10
      $R = $R + 1
      ReDim Preserve $RptData[$R]
      $RptData[$R] = Left($Member + '                    ', 15)
      $RptData[$R] = $RptData[$R] + Left($objUser.FullName + '                                        ', 40)
 
      ; display LOCKED and EXPIRED status 
      If $LStat
        $RptData[$R] = $RptData[$R] + 'LOCKED  '
      Else
        $RptData[$R] = $RptData[$R] + '        '
      EndIf
      If $EStat
        $RptData[$R] = $RptData[$R] + 'EXPIRED   ' + @CRLF + '   ' + $ExpDate
      Else
        ; get remaining days 
        If $Days < $MaxDays
          $RptData[$R] = $RptData[$R] + $Days + ' REMAIN  ' + @CRLF + '   ' + $ExpDate
        Else
          $RptData[$R] = $RptData[$R] + '          '
        EndIf
      EndIf
      If Exist('.\debug.txt')
        $RptData[$R] ?
        $I = $I + 1
        If $I > 100 Quit 0 EndIf
      EndIf
    EndIf
  EndIf
 
Next
 
Del '%S_CONFIG%\Logs\ExpiredPW.txt'				; remove prior report 
$R = RedirectOutput('%S_CONFIG%\Logs\ExpiredPW.txt')		; create new report file 
$Header						; output the header 
For $R = 0 to UBound($RptData)
  If $R Mod 52 = 0 And $R > 0
    Chr(12) $Header				; output a formfeed and header every 52 records 
  EndIf
  $RptData[$R] ?
Next
$R = RedirectOutput('')				; close the report file 
 
$MailTo     = ReadProfileString('%S_CONFIG%\lockout.ini', 'MAIL', 'MailTo')
$MailSender = ReadProfileString('%S_CONFIG%\lockout.ini', 'MAIL', 'MailSender')
$MailServer = ReadProfileString('%S_CONFIG%\lockout.ini', 'MAIL', 'MailServer')
 
; send the report via email (BLAT) 
If $MailTo <> ''
  $BlatCmd = '%COMSPEC% /c %S_BIN%\blat.exe %S_CONFIG%\Logs\ExpiredPW.txt'
  $BlatCmd = $BlatCmd + ' -to ' + $MailTo
  $BlatCmd = $BlatCmd + ' -subject "Expiring Passwords"'
  $BlatCmd = $BlatCmd + ' -f ' + $MailSender
  $BlatCmd = $BlatCmd + ' -server ' + $MailServer
  $BlatCmd = $BlatCmd + ' >NUL:'
  Shell $BlatCmd
EndIf
 
Exit 0
 
 
; ================================================================================ 
; correct the date format - change from "11/1/2007 2:31:30 PM" to "2007/11/01 14:31:30" 
Function FixDate($_Date)
 
  Dim $_ODate
  Dim $_Tmp
  $_ODate = Split($_Date, ' ')
 
  ; Change the date format 
  $_Tmp = Split($_ODate[0], '/')
  $_ODate[0] = $_Tmp[2] + '/' + Right('0' + $_Tmp[0], 2) + '/' + Right('0' + $_Tmp[1], 2)
 
  ; Change the time format 
  $_Tmp = Split($_ODate[1], ':')
  If $_ODate[2] = 'PM' And Val($_Tmp[0]) < 12
    $_Tmp[0] = Right('0' + (Val($_Tmp[0]) + 12), 2)
  Else
    $_Tmp[0] = Right('0' + $_Tmp[0], 2)
  EndIf
  $_ODate[1] = Join($_Tmp, ':')
 
  $FixDate = $_ODate[0] + ' ' + $_ODate[1]
  Exit 0
 
EndFunction
 
 
 
; 
;FUNCTION    GroupMembers 
; 
;ACTION      Returns an array of all group members of the specified group 
; 
;SYNTAX      GroupMembers(Target, Group, [FLAG]) 
; 
;PARAMETERS  Target 
;               The Domain name or Workstation to work with.  For faster workstation  
;               execution, include the Domain Name that the workstation is a meber of. 
; 
;               "Kixtart/beanbag" would be working with the workstation Beanbag in the  
;               Kixtart domain 
; 
;            Group 
;               The Group you want to query 
; 
;            [FLAGS] 
;               To use the flags options add the numbers of the desired flags toghthers and 
;               Use that number in the flag field. 
; 
;                  Filter :(only one filter flag at a time please) 
;                     1 = all 
;                     2 = Users only 
;                     4 = Groups only 
; 
;                  ADSI Information(return ADSI information "pick only one") 
;                     8  = ADSPath field 
;                     16 = ADSI Object Handle 
; 
;RETURNS     an array containing , if the ADSPath option is used the ADSPath  
;            will also be returned |. 
; 
;REMARKS     ADSI com object must be installed. 
; 
;EXAMPLES    ;this return all members of the Domain Admins group in the kixtart domain. 
;            $members = groupmembers("kixtart","Domain admins") 
; 
;            ;this will will return all groups in the local administrators group on  
;            ;the Workstation beanbad in the kixtart domain.  Also the  
;            $groups = groupmembers("kixtart/beanbag","Administratoos","group") 
Function Groupmembers($target, $group, optional $flag)
 
  DIM $temparray[8], $member, $i, $chunk, $flag, $ADSIFlag, $filterFlag
 
  $chunk = ubound($temparray)
  $flag = val($flag)
  $i = 0
  $group = getobject("WinNT://" + $target + "/" + $group)
 
  if vartype($group) <> 9 exit(@error) endif
 
  select
    case $flag & 1
      $filterflag = 1
    case $flag & 2
      $filterflag = 2
    case $flag & 4
      $filterflag = 4
    case 1
      $filterflag = 1
  endselect
 
  select
    case $flag & 8
      $ADSIFlag = 8
    case $flag & 16
      $ADSIFlag = 16
  endselect
 
  for each $member in $group.members
    select
      case $filterflag = 2 AND $member.class = "user"
        if substr($member.name,len($member.name),1) <> Chr(36)
          $temparray[$i] = $member.name
 
          select
            case $adsiflag = 8
              $temparray[$i] = $member.adspath
 
            case $adsiflag = 16
              $temparray[$i] = $member
 
          endselect
 
          $i = $i + 1
 
        endif
 
      case $filterflag = 4 AND $member.class = "Group"
        if substr($member.name,len($member.name),1) <> Chr(36)
          $temparray[$i] = $member.name
 
          select
            case $adsiflag = 8
              $temparray[$i] = $member.adspath
 
            case $adsiflag = 16
              $temparray[$i] = $member
 
          endselect
 
          $i = $i + 1
 
        endif
 
      case $filterflag = 1
        if substr($member.name,len($member.name),1) <> Chr(36)
          $temparray[$i] = $member.name
 
          select
            case $adsiflag = 8
              $temparray[$i] = $member.adspath
 
            case $adsiflag = 16
              $temparray[$i] = $member
 
          endselect
 
          $i = $i + 1
 
        endif
 
      case $filterflag
        ;bit bucket 
 
    endselect
 
    if $i = ubound($temparray)
      redim preserve $temparray[Ubound($temparray)+$chunk]
 
    endif
 
  next
 
  if $i <> 0
    redim preserve $temparray[$i-1]
    $groupmembers=$temparray
 
  endif
 
endfunction
 
;; 
;;====================================================================== 
;; 
;;FUNCTION       TimeDiff() 
;; 
;;AUTHOR         Glenn Barnas 
;; 
;;VERSION        2.2 / 2007/10/14 
;;		 Modified to increase accuracy, permit fracional second calculations 
;;		 2.1 / 2007/03/17 
;;               added "now" and "today" options for both start and end times 
;;               2.0 / 2006/11/20 
;;               Changes for code efficiency; added defaults for midnight  
;; 
;;ACTION         Calculates the time difference between two given date/time strings 
;; 
;;SYNTAX         TimeDiff(Start [, End] [, Format] [, MSec]) 
;; 
;;PARAMETERS     Start  - REQUIRED, String value representing the start timestamp 
;;                 Format yyyy/mm/dd hh:mm:ss 
;; 
;;               End    - OPTIONAL, Defaults to "now" 
;;		   String value representing the ending time 
;;                 Format yyyy/mm/dd hh:mm:ss 
;;		   Can be the special value "now" for the current date/time, or "today" 
;;                 for midnight of the current day. 
;; 
;;                 When the time value is not specified, it defaults to 00:00:00.000 (midnight) 
;; 
;;		 Format - OPTIONAL, one of: 
;;		  "m" - return minutes 
;;		  "h" - return hours 
;;		  "d" - return days 
;;		  "y" - return years 
;;		 When a format value is specified, it returns the fractional part (ie 0.5 days for 12 hours). 
;; 
;;		 MSec	- OPTIONAL, True if the fractional seconds should be returned. Default 
;;		  is false, returning whole seconds, to maintain compatibility with earlier versions. 
;;		  MSec only affects the return of fractional seconds, not fractional parts of other time formats. 
;; 
;;REMARKS        Returns a value representing the difference in time between two date/time 
;;		 strings. Assumes that "Start" is in the past, but will properly return a 
;;		 negative value if it is in the future. 
;; 
;;RETURNS        Double - difference between Start and End timestamps in seconds 
;; 
;;DEPENDENCIES   None 
;; 
;;TESTED WITH    Kix 4.2+, NT4, W2K, WXP, W2K3 
;; 
;;EXAMPLES       If TimeDiff(GetFileTime('SomeFile.txt'),  'now', 'h') > 48 
;;		   "File is more than 2 days old!" ? 
;;		 EndIf 
; 
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
 
 
 
 
 
_________________________
Actually I am a Rocket Scientist! \:D