JAMF Recon – A passion course that leads to pain.

We’re building fires that will burn until morning.

We all love jamf Pro (Casper to us old timers!) and know that inventory is king. Without an accurate inventory all those smart groups generate inaccurate results and can lead to random policy delivery.

To counter that too much inventory traffic wil lead to database growth and slow down jss as it stores all the information and updates those smart groups every time.

Questions questions, Give me no answers.

I wrote a patching system for MacOS, it needs good accurate inventory to work correctly but I didn’t want each and every update to trigger a recon followed by routine timed recons and any other ones that happened to be in other policies that had been forgotten abou. Just too much inventory for my liking.

I checked the time, it was almost time, A curious smell, an intangible crime.

So, what did we do. plist controlled recons of course!

We recently started using a central plist file to record some local information when running policies, it started out as a small part of the patching process but soon became an obvious place to record lots of settings.

So for the recon two keys are used;

  1. LastReconDate – written as yyyy-mm-dd
  2. ReconRequired – yes/no

Laying in the after glow, I only want to learn what you know.

The recon is triggered by either ReconRequired being yes or being more than x days after the lastReconDate.

To set this up the policies that require a recon after they complete have a line in a script to set the ReconRequired value;

defaults write "$plist" ReconReqd yes

The main script checks if the yes value has been set then runs the recon;

# todays date
todaysDate=$(date "+%Y-%m-%d")

reconCheck() {
# check if a recon is required and run it and set date 
reconRequired=$(defaults read "$plist" ReconReqd)
if [ "$reconRequired" = "yes" ]
	$jamfBinary recon &
	defaults write "$plist" ReconReqd no
	defaults write "$plist" LastReconDate "$todaysDate"
	echo "No need for a recon"


This sets the device up for the routine inventory policy.

I hope you find a little more time, Remember we were partners in crime.

Things are now set to used the timed recon policy. this is a script in a policy. The policy is set to run every day but the script only runs an inventory if it has to.


name="Recon Time Delay"
version="0.3"  #script version

#plist location

# interval is the number of days between inventory runs. Set as variable 4 in the jamf policy
# if nothing is passed then 14 is used as a fallback value
if [ "$interval" = "" ]


# Get variables from the plist
# if nothing is set then use todays date and yes to start the cycle
lastrecondate=$(defaults read $plist LastReconDate)
if [ "$lastrecondate" = "" ]; then
	lastrecondate=$(date +"%Y-%m-%d")

reconrequired=$(defaults read $plist ReconReqd)
if [ "$reconrequired" = "" ]; then

# Calculate the days between the last date and now.
dayssincelastrecon=$(( ( $(date +%s ) - $(date -j -f "%Y-%m-%d" $lastrecondate +%s)) /60/60/24 ))

# if days more then the number given in $4 or it is required run the recon and update the plist.
if [[ $dayssincelastrecon -gt $interval ]] || [[ $reconrequired == "yes" ]]; then
	echo "Running Recon"
	$jamfBinary recon
        # set the plist values to todays date and no
	defaults write  $plist LastReconDate $(date +"%Y-%m-%d")
	defaults write  $plist ReconReqd no
	echo "recon not required"


Thats it.

This mechanism can be used across any other policies that install things that require an inventory update but not instantly, and this is easily set up using policy chaining and scripts calling other policies.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s