Run DSCL Extension Attribute once

dondo521
New Contributor III

I have an extension attribute that does a dscl query to create a Manager field in the JSS. What I would like to do is have it run once as it really does not need to perform a query every time inventory is run.
What do I need to add to have it run once?

Thanks in advance!

!/bin/bash

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

DSManager="$(dscl /Active Directory/XXXXXX/XXXXXX.com -read /Users/"$loggedInUser" | grep dsAttrTypeNative:manager | /usr/bin/awk {'print $2'} |sed 's/.{46}$//' | awk '{print substr($0,4,length($0)-1)}')"
Manager="$(dscl /Active Directory/XXXXXX/XXXXXX.com -read /Users/"$DSManager" RealName | tail -n1 | cut -c2-)"

echo begin ping

ping -c 3 XXXldap.XXXXXX.com if [ $? -eq 0 ]; then echo "<result>$Manager</result>"

else

echo "<result>Not available at this time.</result>"

fi

exit 0

10 REPLIES 10

Look
Valued Contributor III

Does it matter terribly if it runs every time?
If you wanting to reduce the load in some way you could have a script that runs occasionally and populates a local plist file that you then read from during inventory.
I have something similar that is used to pull multiple values from various places which I then use for a variety of EA's in the JSS. It's potentially possible to disrupt things by manually editing the file, but it is also a file local technicians can look at to get machine info without having to go to the JSS.

dondo521
New Contributor III

Hey Samuel,

Actually I really don't want it to run every time. I was hoping there was a way to have an extension attribute run once or maybe have it begin but then stop when it detects that the field it is supposed to populate has already been done.

I do like your idea, especially the fact that it serves two purposes: the variety of EA's and the local file aspect. A lot of the time the techs just don't go to the JSS. Your method of a local file might make it less daunting for them. Can you share your script?

In the meantime I am going to see if there is away to script what I have to check first if the intended field is populated and if so not continue. I would think there would be a way to do this. If I could figure that out it I think it might help a lot of people out here who don't want recon to run things that don't necessarily have to be run every time, especially dscl queries.

Thanks!

Look
Valued Contributor III

The script I use is pretty specific as we have an assets database and the admins have created a web interface I use curl to get info from.
But in principal you can just use defaults write or defaults read with basically an arbitrary file location ie

defaults write /Library/preferences/org.myorg.machineDetails.plist manager -string "Bob"
defaults read /Library/preferences/org.myorg.machineDetails.plist manager

The first write will simply create the file as it needs to.
Just have a script in casper set to run weekly or something to populate anything you want in there (or you can use different scripts at different times of course).
As for checking the JSS to see if it populated already, if all your doing is reading a single value out of a local plist and writing the result to the JSS, it's probably going to take as long to check as it is to just populate it again. One thing you could do is check your value isn't empty before writing it to the JSS, that would something like the local file being deleted from removing the data from the JSS.

davidacland
Honored Contributor II

I think the load on the directory would be minimal and as the inventory only updates once per week, it would be ok to leave it running. Plus you would want to know if the value changed to avoid storing stale data.

That being said, if you wanted it to not run every time, you could store the value locally on the Mac and read from that. Then use an if statement with mtime to check when the file was last modified.

dondo521
New Contributor III

David,
I would think the load on the directory would be minimal as well. However our network team has told me that the Mac are taking up gigabytes of network traffic performing these queries. We have monitored this through Wireshark. The inventory does not run every week, rather anytime a recon is performed (for example anytime you set a policy to run recon in the maintenance tab) I really don't want to take that off any of the policies as that is something that is obviously beneficial.

I do think both of you (Samuel and David ) are on to good ideas here. I am going to take that and think about the best way to move forward as it would be great to come up with a solution for others on here who might have similar concerns. Thanks for your input!

dondo521
New Contributor III

This looks pretty similar in design to what you both were speaking of:
https://github.com/mm2270/UpdateExtensionAttributes

mm2270
Legendary Contributor III

Hi @dondo521 I see you linked to scripts on my github page. Unfortunately, what you linked to is actually for a very different purpose than what you're looking for. Those scripts are designed to work around a current limitation (by design) with Extension Attributes, or more specifically, with inventory collection. There is no way to only collect Extension Attributes without also doing an entire full inventory collection. Those scripts were designed to have a way to trigger EAs to be collected on whatever schedule you may like and nothing else. The Extension Attributes themselves must still exist in the JSS though, since that defines the database field for your Macs.

What you're looking to do is best solved by the suggestions above to redesign your EA script to first look for a local file on the Mac with the information it needs, read it back and then upload that to the JSS' Mac record, and if not found, do the dscl query against AD, then write the value into the local file. This will have the effect that, the first time it runs on any Mac, it will do your AD lookup, but each subsequent time it should be able to pull the value from the file.
The only caveat to this approach is as David mentioned, you run the risk of stale, outdated information being collected for some Macs. I don't know how much of a concern that would be for you and your environment, but its something to consider. If it is a concern, you can consider his example of using something like mtime to check the last modification date and if its beyond a certain timespan, do the AD lookup again to make sure its getting the most recent information.

BTW, in case it hasn't been mentioned before, its not possible to run any EA script only once. These scripts are designed to run at each inventory, and there isn't really a way around this other than what's been outlined above

bentoms
Release Candidate Programs Tester

@dondo521 why not pull this information in via LDAP on the JSS itself?

JSS LDAP

If you're not using all the LDAP fields, map one to manager & rename.

It may lessen the bandwidth usage.

dondo521
New Contributor III

mm2270,
Thanks for the information. I think the mtime approach you and David had suggested is probably the way to go.

bentoms,
Good idea as well, but I am going to see if I can tackle it based on mm2270 and davidacland's suggestion.

Thanks everyone for your help. Hope to have something on here shortly...!

sean
Valued Contributor

If you don't wish to map, then I'd suggest a /Library/LaunchAgent to populate a plist file. The script will only run at each login and will be correct based upon the current user. Casper can then just read this value as the EA.

As far as the script is concerned, a ping check would probably be more useful before trying to communicate with AD.