Enterprise Connect with AD field pulled with either dscl or ldapsearch

jrepasky
New Contributor III

I'm sure this has been done before and probably could be done simpler but here is my way of getting AD info onto a machine and ultimately into the JSS (All domain info in these exampsles are listed generically and need to be customized to your specifications)

I found the only way this works since it runs as the user is to create a LaunchAgent and have the fields written to a plist locally in the users account.
This can then be read by defaults read command for input into API or extension attributes (perhaps for fields beyond the defults in jss we use extensionattribute7)

Writing the LaunchAgent requires it to have a hard coded path that includes the username so I used defaults write with variables.
For the difference in scripts between Enterprise Connect/ldapsearch and Active Directory/dscl the plist name changes com.domain.enterprise.connect.pull.plist
com.domain.Active-Directory-info.plist

#!/bin/sh

UserList=`/bin/ls -1 /Users | grep -v Shared | grep -v 'Deleted Users' | grep -v .localized | grep -v administrator | grep -v .DS_Store`

for user in $UserList;
do
defaults write "/Users/$user/Library/LaunchAgents/com.domain.enterprise.connect.pull" Label "com.domain.enterprise.connect.pull.plist"
defaults write "/Users/$user/Library/LaunchAgents/com.domain.enterprise.connect.pull"  "ProgramArguments" -array-add "/bin/bash" "/Users/$user/Library/Application Support/Desktop Engineering/EnterpriseConnect-pull-AD-info.sh" 
defaults write "/Users/$user/Library/LaunchAgents/com.domain.enterprise.connect.pull"  "RunAtLoad" -bool "TRUE"
chmod 600 "/Users/$user/Library/LaunchAgents/com.domain.enterprise.connect.pull.plist"
chown $user  "/Users/$user/Library/LaunchAgents/com.domain.enterprise.connect.pull.plist"

done
exit 0

Enterprise Connect pull AD info using ldapsearch:

#!/bin/sh

loggedInUser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
touch /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info.plist
chmod 777 /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info.plist

adUser=$(klist | grep 'Principal:' | awk -F: '{print $NF}' | sed 's/ //g' | sed 's/@.AD.DOMAIN.COM//g')

sAMAccountName=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser sAMAccountName 2>/dev/null|grep sAMAccountName: | sed 's/sAMAccountName: //' | awk -F: '{print $NF}') 
displayName=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser displayName 2>/dev/null|grep displayName: | sed 's/displayName: //'| awk -F: '{print $NF}') 
userPrincipalName=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser userPrincipalName 2>/dev/null|grep userPrincipalName: | sed 's/departmentNumber: //'| awk -F: '{print $NF}') 
telephoneNumber=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser telephoneNumber 2>/dev/null|grep telephoneNumber: | sed 's/telephoneNumber: //'| awk -F: '{print $NF}') 
title=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser title 2>/dev/null|grep title: | sed 's/title: //'| awk -F: '{print $NF}') 
building=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser departmentNumber 2>/dev/null|grep departmentNumber: | sed 's/departmentNumber: //'| awk -F: '{print $NF}') 
department=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser department 2>/dev/null|grep department: | sed 's/department: //'| awk -F: '{print $NF}') 
physicalDeliveryOfficeName=$(ldapsearch -o ldif-wrap=no -h AD.DOMAIN.com -s sub -b `defaults read com.apple.Enterprise-Connect defaultNamingContext` sAMAccountName=$adUser physicalDeliveryOfficeName 2>/dev/null|grep physicalDeliveryOfficeName: | sed 's/physicalDeliveryOfficeName: //'| awk -F: '{print $NF}') 


defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info Username "${sAMAccountName}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info RealName "${displayName}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info Email "${userPrincipalName}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info Phone "${telephoneNumber}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info Title "${title}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info Department "${department}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info Building "${building}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info Room "${physicalDeliveryOfficeName}"

plutil -convert xml1 /Users/$loggedInUser/Library/Preferences/com.domain.Enterprise-Connect-info.plist

AD Bound pull AD info using dscl:

#!/bin/sh

loggedInUser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
touch /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info.plist
chmod 777 /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info.plist

sAMAccountName=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:sAMAccountName | tail -n +2|sed 's/[^ ]* //')
displayName=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:displayName | tail -n +2|sed 's/[^ ]* //')
userPrincipalName=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:userPrincipalName | tail -n +2|sed 's/[^ ]* //')
telephoneNumber=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:telephoneNumber | tail -n +2|sed 's/[^ ]* //')
title=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:title | tail -n +2|sed 's/[^ ]* //')
building=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:departmentNumber | tail -n +2|sed 's/[^ ]* //')
department=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:department | tail -n +2|sed 's/[^ ]* //')
physicalDeliveryOfficeName=$(dscl /Active Directory/DOMAIN/All Domains -read /Users/$loggedInUser dsAttrTypeNative:physicalDeliveryOfficeName | tail -n +2|sed 's/[^ ]* //')

defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Username "${sAMAccountName}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info RealName "${displayName}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Email "${userPrincipalName}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Phone "${telephoneNumber}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Title "${title}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Department "${department}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Building "${building}"
defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Room "${physicalDeliveryOfficeName}"

plutil -convert xml1 /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info.plist

If you are worried that the Building doesn't exist in Jamf (Department and Building need to match the AD input) then you use a script like this to post it to the API

#!/bin/sh

jssUser="api-user"
jssPass="api-user-password"
jssUrl="https://domain.jamfcloud.com"

loggedInUser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')

getDept=$(defaults write /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Department)

touch /tmp/ea.xml
XML="<?xml version="1.0" encoding="UTF-8" standalone="no"?>"
XML+="<department><name>"
XML+="${formattedGetDept}"
XML+="</name></department>"
echo "${XML}" | xmllint --format - > /tmp/ea.xml

curl -k -u "${jssUser}":"${jssPass}" "${jssUrl}"/JSSResource/departments/id/0 -H "Content-type: application/xml" -T "/tmp/ea.xml" -X POST
rm /tmp/ea.xml

Then you can run a script that post all that info back into the

#!/bin/sh

jssUser="api-user"
jssPass="api-user-password"
jssUrl="https://domain.jamfcloud.com"

loggedInUser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')

### Get Serial Number for local computer
serial_number=$(ioreg -l | awk '/IOPlatformSerialNumber/ { print $4;}' | sed '$s/"//'g)

# Get JSS ID using the serial number and API
jssid=$(/usr/bin/curl -sku $jssUser:$jssPass -H "Accept: application/xml" $jssUrl/JSSResource/computers/serialnumber/${serial_number}/subset/general -X GET | xpath //computer/general/id[1]  2>/dev/null | sed -e 's/<id>//' | sed -e 's/</id>//')


# Get the department from the plist and post to computer record with the API
getDept=$(defaults read /Users/$loggedInUser/Library/Preferences/com.domain.Active-Directory-info Department)

#Post the building from defaults read
curl -X PUT -H "Accept: application/xml" -H "Content-type: application/xml" -k -u "${jssUser}":"${jssPass}" -d ""<computer><location><department>$getDept</department></location></computer>"" "${jssUrl}"/JSSResource/computers/id/"${jssid}" --verbose;
1 REPLY 1

Daikonran
New Contributor III

Love this post. Had a lot of little goodies to help me out. Thanks!