Obsolete Projects

Attention!

This page is online for historical purposes only. Everything is out of date and you should probably not use any of it.

Active Directory Password Minders for Mac OS X

scripts and widgets for mac admins in AD-authenticated environments

Password Expiration Checker — an AppleScript for OS X Tiger & Leopard, updated 8/28/08

This script is meant to be used as a login item (but you can deploy it any way you wish) in environments where Macs are bound to AD with Apple’s Directory Services plug-in. (Sorry, no ADmitMac support yet.) I’ve taken some time to make it as universal as I can, so it should work without any modification.

When it runs, it will display a dialog box if the password expires within the number of days you specify, otherwise it exits quietly. Prior to deploying, be sure to set the warningDays variable to your desired value and — if deploying as a Login Item — save the script as an application.

8/28/08 Update

  • Following a tip from reader Roel, I modified the script to properly recognize first and last names containing spaces.

Password Expiration Checker (alternate) — an AppleScript for OS X Tiger & Leopard, updated 9/28/09

Download this alternate version if the above version does not work for you. Whereas the above script attempts to discover information about your AD environment on its own, this script requires you to manually input your site’s AD information.

7/29/08 Updates

  • Added ability to manually specify password expiration interval
  • Added ability to enable/disable personalization of dialog box (i.e. show user’s first and last name)
  • Cleaned up comments within the script

1/16/09 Update

  • Added ability to manually specify password expiration age

2/10/09 Update

  • Added logic to detect OS version so the script will use separate commands to determine password age on Tiger and Leopard (or greater).

9/28/09 Update

  • Fixed the command that runs on Tiger machines. Many thanks to reader Raul Santos for allowing me to remotely control his machine to troubleshoot and fix this issue.

AD Password Expiration Widget, v2 — a Dashboard widget for OS X Leopard, version 2.1, updated 7/11/08

This dashboard widget displays the number of days until the user’s Active Directory password expires. The number is superimposed on a status light that is green if there are more than 30 days to go, is yellow if between 30 and 15 days are left, and is red if 14 or fewer days remain. It also provides a ‘change password now’ button, for convenience. The widget re-uses parts of the first script above, so it has the same environmental requirements.

This update brings you offline functionality — the widget will report the correct number of days even when you’re away from the domain. Also, the rear of the widget display the time and date that it last polled AD. If you’re looking for an easy way to give your mobile users an easy way to manage their own password expiration, then this is for you.

46 thoughts on “Obsolete Projects

  1. Hi Man,
    Listen, I like your applescript for the password expiration.
    However, when I run it, I get a negative number. For instance, it says -14 days until expiration. I’ll poke around in the script. Any suggestions, would be great. Thanks, Pete

  2. Hi Peter,
    This occurs when the script is unable to retrieve the maximum password age from your domain. (It ends up subtracting the age of your password from zero.) I just modified the script to give a more descriptive error if that’s the case. I’ll be posting a revised version of the alternate script soon that will allow you to manually supply the max password age.

  3. YMG:
    I’m also having trouble with the alternate script’s arithmetic. We have a 90 day password change policy (I have configured this into the “manualExpireAge” property of your script). I have a test account whose password was changed 2 days ago. “Additional Account Information” in ADUC shows that the password expires in 88 days. However, when I run the script, it tells the user that the password expires in -148796 days.
    Instead of doing the more complex arithmetic wherein you read the date the password was last set, is it possible to simply read the Password Expires value from AD and subtract today’s date from that for the number of days until expiration? Thanks.

  4. Scott,
    Are you sure the Password Expires value is something you can directly look up? In Windows Server 2003 and earlier, the only way to get that value is to do the math I’m doing. (I’m not sure about Server 2008.) ADUC is doing a similar calculation when it displays the expiration info. I’d like to help you get this working. Email me directly and I’ll help you troubleshoot it.

  5. I’m sorry, I stand corrected. I believe you are right in that ADUC does a similar calculation. Would love to get this working as we are in the midst of a deployment wherein we are joining all of our Macs to AD. The script currently either cannot find the expiration date at all, or returns a very large negative value.
    BTW, we are on W2k3SP2 domain controllers.

    I’m unable to find your email address – did you receive mine in my submission?

  6. I’m sorry to post here, didn’t find how to contact you privately.

    The date calculation itself works for me. However, I have a question about the LastName calculation.

    Seems to be that LastName with more than one word comes out on a new line, so the grep function gets it wrong. It displays as “LastName”.

    Here’s my output using your command. I’ve included 1 line of context for clarity.


    GeneratedUID: 47BD2A36-14C7-4246-96B5-9A109E9DE90F
    LastName: Thys
    MCXFlags:

    and for the user with 2 words in LastName

    LastName:
    De Decker
    MCXFlags:

    I thought I could resort to the RealName. At least there’s some consistency there. It’s *always* on a new line, but how do I tell grep to go fetch it there?


    RealName:
    Anne Thys
    RecordName:

    and

    RealName:
    Chiara De Decker
    RecordName:

    Maybe if grep can handle it, the Applescript can. How would I adapt this line, specifically the “second word of” function, which only works for last names with only 1 word?
    set lastName to (second word of (do shell script “/usr/bin/dscl localhost read /Search/Users/$USER LastName | /usr/bin/grep Name:”) as string)

  7. Hi Folks,
    I am from Germany and I have the Same Problems. -14…
    I try too merge the two scripts and it works.
    Our ExpireAge is 30 days and that is what the script not get from the AD.

    I Translate the Mesage and the Part for open the System Preferences in to German for the German UI
    When you need it in english cpoy it from the org script
    here the Script:

    ————–
    — WARNING PERIOD —

    ————————————————–
    — begin ENVIRONMENTAL VARIABLES
    ————————————————–

    property discoverExpireAge : false
    — controls discovery of the password expiration interval on yor domain. Set to true to have the
    — script autodiscover it. Set to false if you want to specify the password expiration age manually
    — (useful if the script has trouble autodiscovering it). If you set this to false, then you MUST
    — supply the value below.

    property manualExpireAge : 30
    — set to match your domain’s password expiration interval (in days).
    — (Only necessary if you set findExpireAge to false above.)

    ————————————————–
    — end ENVIRONMENTAL VARIABLES
    ————————————————–

    set warningDays to 3 as integer

    set theError to 0

    — Check for active kerberos ticket, exit quietly if none — really only needed when running script manually
    try
    set kerb to do shell script “/usr/bin/klist”
    on error theError
    display dialog theError
    return
    end try

    — Get password expiration age from AD
    try
    — Get IP of AD’s DNS
    set myDNS to (do shell script “/usr/sbin/scutil –dns | /usr/bin/awk ‘/nameserver\\[1\\]/ {print $3}'”) as string
    — Get the distinguished name (aka search base)
    set mySearchBase to (do shell script “/usr/bin/ldapsearch -LLL -Q -s base -H ldap://” & myDNS & space & “rootDomainNamingContext | /usr/bin/awk ‘/rootDomainNamingContext/ {print $2}'”) as string

    if discoverExpireAge is true then
    try — to get password expiration age from AD
    set expireAge to ((do shell script “/usr/bin/ldapsearch -LLL -Q -s base -H ldap://” & myDNS & space & “-b” & space & mySearchBase & space & “maxPwdAge | /usr/bin/awk -F- ‘/maxPwdAge/ {print $2}'”) as integer) / 10000000
    if expireAge is equal to 0 then
    if debugDialogs is true then display dialog “Unable to find maximum password age.” buttons “OK” with icon 2
    return
    end if
    on error theError
    if debugDialogs is true then display dialog theError
    return
    end try
    else — if discovery is off, use the provided value (and do some math so it fits the expected format)
    set expireAge to manualExpireAge * 3600 * 24
    end if

    on error theError
    display dialog theError
    return
    end try

    — Get the date the password was last set, with NT–>UNIX date conversion
    try
    set pwdSetDate to (second word of (do shell script “/usr/bin/dscl localhost read /Search/Users/$USER pwdLastSet | /usr/bin/grep pwdLastSet:”) as integer) / 10000000 – 1.16444736E+10
    — get today’s date in the required format
    set today to (do shell script “date +%s”) as integer
    — do the math to get the days until expiration
    set daysUntilExp to round (expireAge – (today – pwdSetDate)) / 3600 / 24
    on error theError
    display dialog theError
    return
    end try

    — This section generates the warning dialog box
    if daysUntilExp ≤ warningDays then
    set firstName to (second word of (do shell script “/usr/bin/dscl localhost read /Search/Users/$USER FirstName | /usr/bin/grep Name:”) as string)
    set lastName to (second word of (do shell script “/usr/bin/dscl localhost read /Search/Users/$USER LastName | /usr/bin/grep Name:”) as string)

    copy (display dialog firstName & space & lastName & “,” & space & “Ihr Passwort läuft in” & space & daysUntilExp & space & “Tagen ab. möchten Sie es jetzt ändern?” buttons [“Ja”, “Nein”] default button 1 giving up after 300 with icon 0) to response
    — If user clicks Yes, try to bring up the change password dialog box
    if the button returned of response is “Ja” then
    tell application “System Preferences”
    try — to use UI scripting
    set current pane to pane “Benutzer”
    tell application “System Events”
    tell application process “Systemeinstellungen”
    end tell
    end tell
    end try
    activate
    end tell
    end if
    end if

  8. When I run your script I get…
    john
    john doe doe your password will expire in
    x days. Do you wnat to change it now?

    What do I need to change to get the name to display right?

  9. Is there any possibility your script(s) could be modified to work when the system is stand-alone?
    (Not networked to AD nor to an OS X Server)
    Thanks for the work you have already done.

  10. Mike, I’m not quite sure I understand what you’re asking. My scripts and widget take the current username and query the active directory server to determine when the password expires. If your computer is a stand-alone system, then there is no password expiration to worry about. If I’m misunderstanding what you’re asking, please clarify.

  11. I’m trying to implement the Password Expiration Checker and I was wondering, does the Mac workstation have to be bound to the AD network for this script to work? I have everyone bound to OD and not AD at the moment. Their user names on the OD system don’t necessarily line up with the AD user names, so it might be a bit of an issue to get them lined up.

    Thanks – Brian

  12. Excellent – thanks. That’s what I was thinking, but I wanted to make sure I wasn’t missing something. Of course this begs the question – is there a good way for the Mac users to then change their password once they receive the message?

    Thanks,

    Brian

  13. Even if the machine is bound to AD, if the user’s are logging on to OD accounts, they won’t have a kerberos ticket. Connecting to any AD-authenticated fileshare will create a ticket, however. My solution is probably not going to work for you as it was designed for environments where Mac users are logging on with AD accounts.

  14. Hi Peter,
    I am also having the same issue as Scott in that I get a -148975 days returned. We also hook into 2003 domain servers.
    Here is some debug output from Applescript:

    do shell script “/usr/bin/dscl /Active\\ Directory/pcroot.com -read /Users/$USER pwdLastSet | /usr/bin/grep pwdLastSet:”
    “pwdLastSet: 128719241276925789”
    do shell script “date +%s”
    “1232107519”
    do shell script “/usr/bin/ldapsearch -LLL -Q -s base -H ldap://10.150.2.155 -b DC=pcroot,DC=com maxPwdAge | /usr/bin/awk -F- ‘/maxPwdAge/ {print $2}'”
    “51840000000000”
    round -1.48974506177643E+5
    -148975
    display dialog “expireAge5184000″
    {button returned:”OK”}
    display dialog “today1.232107519E+9″
    {button returned:”OK”}
    display dialog “pwdSetDate-1.164447381475E+10″
    {button returned:”OK”}
    display dialog “daysUntilExp-148975″
    {button returned:”OK”}
    display dialog “manualExpireAge60″
    {button returned:”OK”}
    do shell script “/usr/bin/dscl localhost read /Search/Users/$USER FirstName | /usr/bin/grep Name:”
    “FirstName: Chris”
    do shell script “/usr/bin/dscl localhost read /Search/Users/$USER LastName | /usr/bin/grep Name:”
    “LastName: Hopkins”
    display dialog “Chris Hopkins, your password will expire in -148975 days. Do you want to change it now?” buttons {“Yes”, “Not now”} default button 2 giving up after 300 with icon 0
    {button returned:”Not now”, gave up:false}

    ———————————————————————————————————————————-

    With this account, there are 6 days left until a required password change.
    I added some display dialog lines to report on the property values.

    Much appreciated Peter.

    Chris

    • Chris, I just updated the alternate script to add the ability to supply the expiration age manually. Please download the updated script and give it a shot. It your case, you’ll need to replace the 0 in the expireAge property with 60.

  15. Hi,

    we get password will expire in -149059 days but there are 10 days left.

    System is 10.4.11 with AD on Win2003.

    Setting expireAge to 100 didn’t work.

  16. Hi Guys,
    My findings may be useful:
    I have had varying degrees of success with the two scripts across both Leopard and Tiger in our Win2003 AD environment.
    We have a complicated setup with multiple domains as we are a large enterprise.
    In testing, some AD user accounts return the correct days until expiry whereas other accounts may return errors or negative values. It seems that the user records in AD are not consistent in the information available for the dscl command line query. I have yet to take this up with our Windows admins. This is just a suspicion on my part as directly interrogating a users account with the dscl read command can return different criteria depending on the user.

    There could also be an issue with a Mac having the ‘All Domains’ setting in Directory Services.

    Chris

  17. Is there any settings that need to be set for the AD passwd widget? Installed it on a 10.5.5 laptop bound to AD and the status just shows as NAN and grey.

    • There are no settings to adjust. It uses the same method to get the password expiration as my applescripts do. Can you download both the regular one and the alternate one and let me know if they work for you? If not, I can help you get it working.

  18. I tried both scripts and nothing happened. I saved the script as an application in Script editor and added it to the login items in Workgrp mgr. I was wondering if I am doing something wrong. The 10.4 clients receive the password expire warning automatically. Thanks for your time.

  19. With the alternative script, you have to supply the information it asks for in the environmental variables section. Have you done that? The regular script should return some kind of error.

  20. Hi, great script will be very useful, however I too am getting -3 as the number of days remaining whereas in fact I changed the password 3 days ago.
    If I manually enter 90 instead of 0 then I get the ‘unable to find Maximum Password Age’ message
    any Ideas?
    Thanks

  21. Hi Thanks for this,
    I wonder if it is possible to grab a users AD Group so we can use it to determine wether or not to mount a network share or not,
    Thanks…

    • Rob,

      As part of a login script, for example, you can grab the user’s AD group with the following command:

      dscl /Active\ Directory/All\ Domains read /Users/$1 | awk ‘/PrimaryGroupID/ {print $2}’

  22. We use Workgroup Manager along with Active Directory, I have tried to use this as a login item in Workgroup manager but it not running when users login to it. Any ideas?

    • Can you be more specific? Which file did you try as a login item? Also, does this same file work from an AD account when you double-click on it?

    • True, it has been abandoned, but I am currently working on a complete rewrite in XCode in my spare time. I’m not sure when I’ll be done since I’m pretty much learning as I go. (I didn’t do any of the app coding for Password Expiration Monitor, only the applescript code that gets the password expiration information from AD.) This new version will work in 10.6 and 10.7. But it’s vaporware until it gets released, right? ;)

Leave a comment