Auto populate location data in inventory from LDAP

miles
New Contributor

I have LDAP set-up to pull in Room from AD. To make it apply, I have to go to inventory>Details>Location>Click the ellipsis>Click the blue magnifying glass, and then the attribute are populated, Save, for each record.

Can this be achieved automatically?

I use this room info for smart groups, and if it were automatic, it would save a hemp of manually clicking.

Thanks,

Matt

1 ACCEPTED SOLUTION

tlarkin
Honored Contributor

The recon command from the JAMF binary can accomplish this, then as long as you have live LDAP look ups enabled once that short name is passed it should auto-map the LDAP credentials.

sudo jamf recon -endUsername tlarkin

That would take the short name "tlarkin" and pass it to the machine record and look it up via your LDAP mappings.

Hope this helps.

Thanks,
Tom

View solution in original post

21 REPLIES 21

vadanx
Contributor

Hey - this is what I use in my environment, you'll obviously have to make modifications. It was taken from one of the posts on jamfnation (I have changed it since then) but I can't remember for the life of me who wrote it, but credit goes to them!

#!/bin/sh

LOGIN=`/usr/bin/last -1 -t console | awk '{print $1}'`
OS_VERS=`sw_vers -productVersion | awk -F. '{print $1$2}'`


if [ "$OS_VERS" == "107" ]; then
    if [ "`/usr/bin/dscl /Active Directory/PROD/All Domains -read /Users/$LOGIN | grep 'Data source' | awk '{ print $7 }'`" == "not" ]; then
# IF BIND ERROR - KILL BIND AND CALL BIND POLICY
    sudo rm -rf /Library/Preferences/OpenDirectory/Configurations; sudo killall opendirectoryd; /usr/bin/sudo /usr/sbin/jamf policy -trigger bindAD; sudo killall opendirectoryd; exit
    else
    ###Read AD fields into variables.
    PHONE=`/usr/bin/dscl /Active Directory/PROD/All Domains -read /Users/$LOGIN PhoneNumber | awk '{ $1 = ""; print }'`
    REALNAME=`/usr/bin/dscl /Active Directory/PROD/All Domains -read /Users/$LOGIN RealName | tail -n 1`
    EMAIL=`/usr/bin/dscl /Active Directory/PROD/All Domains -read /Users/$LOGIN EMailAddress | awk '{ $1 = ""; print }'`
    JOBTITLE=`/usr/bin/dscl /Active Directory/PROD/All Domains -read /Users/$LOGIN JobTitle | tail -n 1`
    BUILDING=`/usr/bin/dscl /Active Directory/PROD/All Domains -read /Users/$LOGIN streetAddress | tail -n 1`
    fi
else
    if [ "`/usr/bin/dscl /Active Directory/All Domains -read /Users/$LOGIN | grep 'Data source' | awk '{ print $7 }'`" == "not" ]; then
# IF BIND ERROR - KILL BIND AND CALL BIND POLICY
    sudo rm -rf /Library/Preferences/DirectoryService/ActiveDirectory*; sudo killall DirectoryService; /usr/bin/sudo /usr/sbin/jamf policy -trigger bindAD; sudo killall DirectoryService; exit
    else
    ###Read AD fields into variables.
    PHONE=`/usr/bin/dscl /Active Directory/All Domains -read /Users/$LOGIN PhoneNumber | awk '{ $1 = ""; print }'`
    REALNAME=`/usr/bin/dscl /Active Directory/All Domains -read /Users/$LOGIN RealName | tail -n 1`
    EMAIL=`/usr/bin/dscl /Active Directory/All Domains -read /Users/$LOGIN EMailAddress | awk '{ $1 = ""; print }'`
    JOBTITLE=`/usr/bin/dscl /Active Directory/All Domains -read /Users/$LOGIN JobTitle | tail -n 1`
    BUILDING=`/usr/bin/dscl /Active Directory/All Domains -read /Users/$LOGIN streetAddress | tail -n 1`
    fi
fi

###Reset variables to remove white space.
LOGIN=`echo $LOGIN`
echo $LOGIN
PHONE=`echo $PHONE`
echo $PHONE
REALNAME=`echo $REALNAME`
echo $REALNAME
EMAIL=`echo $EMAIL`
echo $EMAIL
JOBTITLE=`echo $JOBTITLE`
echo JOBTITLE
BUILDING=`echo $BUILDING`
echo BUILDING

if [ "$LOGIN" == "wtmp" ] || [ "$LOGIN" == "adminaccount" ] || [ "$LOGIN" == "jssadmin" ] || [ "$LOGIN" == "root" ] || [ "$LOGIN" == "adobeinstall" ]; then
PHONE=""
REALNAME="N/A"
EMAIL=""
JOBTITLE=""
BUILDING=""
/usr/sbin/jamf recon -endUsername "$LOGIN" -realname "$REALNAME"; exit 0
fi

###Run Recon and insert AD values in Location fields.
/usr/sbin/jamf recon -endUsername "$LOGIN" -realname "$REALNAME" -email "$EMAIL" -phone "$PHONE" -position "$JOBTITLE" -room "$BUILDING"

I don't have it pull Department information from LDAP/AD at the moment due to the structure of some of our policies.

tlarkin
Honored Contributor

The recon command from the JAMF binary can accomplish this, then as long as you have live LDAP look ups enabled once that short name is passed it should auto-map the LDAP credentials.

sudo jamf recon -endUsername tlarkin

That would take the short name "tlarkin" and pass it to the machine record and look it up via your LDAP mappings.

Hope this helps.

Thanks,
Tom

miles
New Contributor

Settings>Inventory Collection Preferences>Location>'Populate the computer location information of a username from an LDAP lookup on inventory update'. CHECK

I didn't know about this setting. Now its working correctly!

Thanks,

Matt

vadanx
Contributor

What version of JSS are you running?

myronjoffe
Contributor III

Nice, I didnt know this feature existed out the box from 8.6

@Miles Once you enabled it from Inventory Collection Preferences. When machines recon does the location info auto populate? Or do you need to create a policy/script to run - sudo jamf recon -endUsername <user>

bentoms
Release Candidate Programs Tester

@Myron, I run the following @ every login..

sudo jamf recon -endUsername $3

myronjoffe
Contributor III

Thanks Ben :)

miles
New Contributor

You have to have the username in so that Casper can pull the LDAP attributes.

Matt

tkimpton
Valued Contributor II

untick collect user information from LDAP

#!/bin/bash

### Specify the AD ###
AD=SERVICE-NOW

## Specify None ##
NONE=.

######### DO NOT MODIFY BELOW THIS LINE #########

### Get the currently logged in user information ###
ConsoleUser=`ls -l /dev/console | cut -d " " -f4`

### If the currently logged in user is an AD Mobile account then update the end username information to the jss ###
if

dscl /Active Directory/$AD/All Domains/ -read /Users/"${ConsoleUser}" > /dev/null 2>&1 ;then

ConsoleUserRealName=`dscl /Active Directory/$AD/All Domains/ -read /Users/"${ConsoleUser}" RealName | tail -n 1 | cut -c2-`
ConsoleUserEmail=`dscl /Active Directory/$AD/All Domains/ -read /Users/"${ConsoleUser}" | grep EMailAddress | cut -d ' ' -f2`
ConsoleUserJobTitle=`dscl /Active Directory/$AD/All Domains/ -read /Users/"${ConsoleUser}" JobTitle | tail -n 1 | cut -c2-`
ConsoleUserPhone=`dscl /Active Directory/$AD/All Domains/ -read /Users/"${ConsoleUser}" PhoneNumber | tail -n 1 | cut -c2-`

# Submit the user information to the JSS
sudo jamf recon -endUsername "${ConsoleUser}" -realname "${ConsoleUserRealName}" -email "${ConsoleUserEmail}" -position "${ConsoleUserJobTitle}" -phone "${ConsoleUserPhone}"
else

# If its not an AD account blank out the data
sudo jamf recon -endUsername $NONE -realname $NONE -email $NONE -position $NONE -phone $NONE
fi
exit 0

For the Building info you will need an extension attribute

#!/bin/bash

# Get the currently logged in user
ConsoleUser=ls -l /dev/console | cut -d " " -f4
AD=(YOUR AD)
NONE=.

if
dscl /Active Directory/$AD/All Domains/ -read /Users/"${ConsoleUser}" > /dev/null 2>&1 ;then
ConsoleUserOffice=dscl /Active Directory/$AD/All Domains/ -read /Users/"${ConsoleUser}" dsAttrTypeNative:physicalDeliveryOfficeName | cut -d ":" -f3 | cut -c2-
echo "<result>$ConsoleUserOffice</result>"
else
jamf recon -department $NONE
fi

For location information we need to vote this up

https://jamfnation.jamfsoftware.com/featureRequest.html?id=2207

tkimpton
Valued Contributor II

fabian_ulmrich
Contributor

@tkimpton Instead of leaving it empty, you could use `sudo jamf recon -endUsername "-"`. This works for me! Or is there a reason why you would like to have those fields blank?

tkimpton
Valued Contributor II

On version 9 there is no way to blank it out. Basically I have incorrect information populated in username and location fields mixed with local account usernames.

jrippy
Contributor II

I know this is an older thread but I'm having trouble with the Building Lookup. We have it mapped to an AD attribute called "physicalDeliveryOfficeAddress" which is more than just the building. Since it is a lookup table though, the AD attribute and the stored row in Casper have to match. Each of these attributes are unique to our users and their office though. Is it possible to disable the Casper rows, and just display the AD attribute like is done for the other fields. I don't really understand Department and Building are different like this but surely it can be changed.

So here's the "test" in my LDAP config. You can see the "Building" attribute is blank. Department is filled in but I've populated most of those in Casper.
external image link

And of course, those are populated here in the network organization section:
external image link

I would just like to pass through those values from AD to Casper without having to "match" them.

bentoms
Release Candidate Programs Tester

@jrippy, I don't think buildings had to match identically.. Just departments.

Another thing, are you overwriting buildings with your network segments?

tkimpton
Valued Contributor II

Buildings DO have to match identically.

Jriply you have hit it exactly.

I've banged on about this at quite some length that this is a very serious and poor design flaw in the Casper Suite.

This has caused me a great deal of stress and unless the Buidlings is exact match to department including case sensitivity, then it fails....utter pants

tlarkin
Honored Contributor

Hi Everyone,

To hopefully clarify this, and expand on what @tkimpton has already explained, yes the building must exist in the JAMF Software database. This is because every building in the JSS is also an object, with a unique ID in the database. We can map objects to buildings from LDAP attributes, or we can just use them as standalone. In a recent update of version 9 (when this was released currently escapes me) we did actually add LDAP extension attributes. This is where you can map any LDAP attribute to an extension attribute.

You can enable this by going into your Inventory Collection Preferences, check to box labeled, "Collect user and location information from LDAP," and save the settings. Next you can go into extension attributes and under the Input Type, you should now be able to select what LDAP attribute you want to map to an OS X device. With the LDAP attribute mapped, from this point you should be able to use that string as criteria for a Smart Group.

Another way to streamline building creation is you could create a script that would read the buildings from text or a csv and POST them via the API.

bentoms
Release Candidate Programs Tester

Thanks for the correction @tkimpton.

Just noticed that we do not pull buildings from AD but set via network segments.

Maybe that could work @jrippy?

tkimpton
Valued Contributor II

still a very bad design. i just want the info pulled from ldap lookups to display the user information in an AD account like building, manager etc etc and not messing with extension attributes all the time.

tkimpton
Valued Contributor II

@tlarkin kb for ldap extension attributes?

Tried in past with account manager and couldn't get it working

jrippy
Contributor II

@tkimpton That's very interesting. I will have to look into that.
If every "building" has to exist before it can be matched to an LDAP attribute, then perhaps JamF could just do a lookup and if the returned LDAP value does not exist in the Building database, then go ahead and create that object.
I know that would be extremely useful in my environment.

However, If I can take that attribute and pull out the correct building with a script in an extension attribute (basically make a lookup table), that will help a lot.

Thanks again @tkimpton

bradtchapman
Valued Contributor II

I'm going to bring a post back from the dead... is there a way to get the JSS to pull data from LDAP without waiting for a machine to recon? 

I want to perform an asynchronous LDAP lookup to populate some brand new Extension Attributes that are mapped to LDAP attributes.

Most Macs are not bound to AD and live their lives off-network, so they would be unable to query LDAP directly.  Clearly, therefore, the JSS must be brokering this request.  And since it's triggered by a recon, it should be possible to retrieve this information at any other time.

I tried PUT'ing an empty request to a computer ID with the API, but it didn't trigger the desired behavior.  Is there a specific endpoint that would accept an empty call and trigger the LDAP lookup?  Or is the behavior triggered by a special undocumented action after recon?