Last year around this time I wanted to be able to report on my Jamf Pro mobile device app catalog to be able to make informed choices about which iOS apps could stay and which to remove. Over time our catalog had ballooned to over 650 apps, many of which weren’t being used on a regular basis. However, Apple’s MDM doesn’t provide a mechanism to report app usage over time (though Screen Time could provide data via MDM, Apple has told me it probably won’t happen due to privacy concerns), and Jamf Pro has no built in field for install count. Both data points which would be useful when it comes to analyzing app quality and relevancy. If I wanted to get quantitative data beyond used and total license count, which isn’t usually an accurate representation of app usage, I had to get it myself.
That’s where jamf_cat_report.py came in. Written mostly to get installed app count, the number of iOS devices on which an app is installed, it grew to include more fields pulling from the Jamf Pro and iTunes API. The biggest challenge was getting installed app count.
Since the Jamf Pro API doesn’t allow advanced searches to return data with an actual permanent search object being created first, the only solution to write a function to do just that. To get installed count the script creates an advanced search where the criteria is “App Identifier is $bundle_id”, gets the device count from that search, and then deletes the search. I’ve done this multiple times with 500+ large app catalogs without bloating the database or seeing other performance issues. The only number that should increment in the advanced search ID.
Due to this method there is one known issue with some Jamf Cloud or on prem Tomcat servers where API returns results slowly. Basically, if your server is too slow the advanced search won’t be created quickly enough to return data from it. I have never had this happen on my own on prem server. As an attempted fix jamf_cat_report.py does try to wait a second and then get the advanced search data again, but I don’t think this is working as it should. The
--retry flag can also increase the number of attempts. If you run into this issue and are willing to give me temporary access or go through a few test let me know! Or, if installed count isn’t needed, run
jamf_cat_report.py --disable-count to skip that function altogether.
As of writing this jamf_cat_report.py reports on the following fields:
- id - Jamf Pro mobile device app ID.
- name - App name.
- main_category - Main app category.
- self_service_cat1-5 - Five Self Service categories. Ends up being first five API returns.
- featured - If the app is included under the featured category in Self Service.
- installed_count - Number of iOS devices on which an app is installed.
- used_licenses - Used license count.
- remaining_licenses - Remaining license count.
- total_licenses - Total available licenses.
- price - Current price from App Store. Default is to return USD from US App Store.
- latest_release - Date of latest version release.
- average_rating - Total average rating. Not rating of current version.
- bundle_id - App bundle ID.
- jamf_url - Jamf Pro mobile device app link based on provided URL in config.json.
- itunes_url - App Store URL pulled from Jamf Pro.
To run the script python 3 and the requests is required. To learn more and try it out yourself check out the GitHub repo.