AD Password expiration as JSS Extension Attribute - no AD bind necessary

signetmac
Contributor

Hi JAMFers.

Wrote this in November and promptly forgot to throw it up for people to get some usefulness. Please, as always, give suggestions for improving, or extending. This script assumes that your usernames associated with the asset record in JSS are populated by LDAP. It does not require the computer to be bound to the domain. Instead, I leveraged the same LDAP account that we use to give our printers access to the GAL. It returns days remaining (thanks to some math worked out for us by @colonelpanic ) as an Extension Attrib.

#!/bin/bash

################################################
# Created By: Mac Scott, macscott[at]livenation.com
# Creation Date: November 4, 2015
# Last modified: November 4, 2015 by macscott[at]livenation.com
# Brief Description: Scrapes JSS for username assigned to asset, then does AD LDAP lookup to determine AD 
################################################
# Set up your organization's variables
# For JSS:

jss_server=     # Full URL for logging into your JSS instance, quoted b/c of the characters; i.e. 'https://jss.yourorg.com:8443'
rest_account=   # An account on your jss server with limited privs set up to scrape user info from the site
rest_password=  # Password for the rest_account user above

# For AD/LDAP:
ldap_server=    # IP address of a dc within your org that allows directory lookups
ldap_account=   # AD account with limited privs, used to query the active directory server using ldapsearch
ldap_password=  # Password for the ldap_account user above
forest_domain=  # i.e. forest.yourorg.com
dist_name=  # The distinguished name of your domain and forest in AD, quoted b/c of the characters; i.e. 'dc=forest,dc=yourorg,dc=com'
pwdPolicy=  # Days to password expiration since last set i.e.: 90

################################################
# Program logic:
# Determine if on corporate network

if ping -c 1 $ldap_server &>/dev/null ; then

    # Determine Primary MAC address of computer and pull API data
    en0=`ifconfig en0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'`
    jssxml="`curl --silent --insecure -u $rest_account:$rest_password $jss_server/JSSResource/computers/macaddress/$en0/subset/Location -X GET`"

    # Get name of user the computer was assigned to
    trimName=`echo ${jssxml#*"<username>"}`
    usernameINjss=`echo ${trimName%"</username>"*}`

    # LDAP lookup for pwdLastSet and then a little math to arrive at days until expiry. 
    # Credit for this portion of the script goes to Jason Borchardt, aka colonelpanic on jamfNation

    lastpwdMS=`ldapsearch -x -H ldap://$ldap_server -D $ldap_account@$forest_domain -w "$ldap_password" -b "$dist_name" -L "anr=$usernameINjss" pwdLastSet | /usr/bin/awk '/pwdLastSet:/{print $2}'`
    lastpwdUNIX1=`expr $lastpwdMS / 10000000 - 1644473600`
    lastpwdUNIX=`expr $lastpwdUNIX1 - 10000000000`
    todayUNIX=`date +%s`
    diffDays1=`expr $todayUNIX - $lastpwdUNIX`
    diffDays=`expr $diffDays1 / 86400`
    daysRemaining=`expr $pwdPolicy - $diffDays`
    echo "<result>$daysRemaining</result>"
fi
3 REPLIES 3

pereljon
New Contributor III

Hi @signetmac,
Great script! Found that the script had an issue if the primary MAC address of the computer changes (for users who sometime use Thunderbolt ethernet dongles and other times use the Ethernet on a thunderbolt monitor). Here it is using the UUID of the hardware which should never change. (Also changed to use xpath to pull out the username from XML).

Cheers,
JP

#!/bin/bash

################################################
# Created By: Mac Scott, macscott[at]livenation.com
# Creation Date: November 4, 2015
# Last modified: November 4, 2015 by macscott[at]livenation.com
# Brief Description: Scrapes JSS for username assigned to asset, then does AD LDAP lookup to determine AD 
################################################
# Set up your organization's variables
# For JSS:

jss_server=     # Full URL for logging into your JSS instance, quoted b/c of the characters; i.e. 'https://jss.yourorg.com:8443'
rest_account=   # An account on your jss server with limited privs set up to scrape user info from the site
rest_password=  # Password for the rest_account user above

# For AD/LDAP:
ldap_server=    # IP address of a dc within your org that allows directory lookups
ldap_account=   # AD account with limited privs, used to query the active directory server using ldapsearch
ldap_password=  # Password for the ldap_account user above
forest_domain=  # i.e. forest.yourorg.com
dist_name=  # The distinguished name of your domain and forest in AD, quoted b/c of the characters; i.e. 'dc=forest,dc=yourorg,dc=com'
pwdPolicy=  # Days to password expiration since last set i.e.: 90

################################################
# Program logic:
# Determine if on corporate network

if ping -c 1 $ldap_server &>/dev/null ; then

    # Determine Hardware UUID of computer and pull API data
    uuid="`system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}'`"
    jssxml="`curl --silent --insecure -u $rest_account:$rest_password $jss_server/JSSResource/computers/udid/$uuid/subset/Location -X GET`"

    # Get name of user the computer was assigned to
    usernameINjss="`echo "${jssxml}" | xpath "string(/computer/location/username)" 2> /dev/null`"


    # LDAP lookup for pwdLastSet and then a little math to arrive at days until expiry. 
    # Credit for this portion of the script goes to Jason Borchardt, aka colonelpanic on jamfNation

    lastpwdMS=`ldapsearch -x -H ldap://$ldap_server -D $ldap_account@$forest_domain -w "$ldap_password" -b "$dist_name" -L "anr=$usernameINjss" pwdLastSet | /usr/bin/awk '/pwdLastSet:/{print $2}'`
    lastpwdUNIX1=`expr $lastpwdMS / 10000000 - 1644473600`
    lastpwdUNIX=`expr $lastpwdUNIX1 - 10000000000`
    todayUNIX=`date +%s`
    diffDays1=`expr $todayUNIX - $lastpwdUNIX`
    diffDays=`expr $diffDays1 / 86400`
    daysRemaining=`expr $pwdPolicy - $diffDays`
    echo "<result>$daysRemaining</result>"
fi

signetmac
Contributor

Thank you @pereljon ! I always appreciate a chance to make my scripts better AND learn new things in the process. I've not used xpath before and am happy to get the example of its usage. This will come in handy in other scripts I'm working on.

All my best,

Mac

pereljon
New Contributor III

@signetmac Do you have your scripts on github? It's a great place to share these from and keep them updated. One more suggestion would be to get the JSS URL directly from the JAMF preferences file.

JSS_BASEURL=$(/usr/bin/defaults read /Library/Preferences/com.jamfsoftware.jamf jss_url)

Here's a script on my github that does this:
https://github.com/pereljon/Casper-Scripts/blob/master/mailsend.sh

Cheers,
JP