Home > Casper, Jamf Pro, Scripting > Running all Jamf Pro policies in a specified category via the API

Running all Jamf Pro policies in a specified category via the API

As part of a project I’m working on, I need to run several policies from a Jamf Pro server using a script which is using the Jamf Pro agent to run policies. However, I also want to maintain maximum flexibility and retain the ability to add, remove or change policies as required without needing to change the script.

My colleague Marc provided a solution for this by letting me know that it was possible to use the Jamf Pro API to pull down a list of policies associated with a specific category and then running those policies in the order provided by the API. For more details, see below the jump.

I was able to use Marc’s technique in the following way:

1. Run the following command to get the policy IDs:

/usr/bin/curl -ksf -u api_username_goes_here:api_password_goes_here -H "Accept: application/xml" https://server.name.here/JSSResource/policies/category/Policy_Category_Goes_Here | xpath "policies/policy/id" | sed 's/\<id>//g' | tr '</id>' '\n' | sed '/^s*$/d'

view raw


hosted with ❤ by GitHub

2. Add all policy IDs into a bash array.

3. Run each policy in the order they were added to the bash array, which will be the same order provided by the API.

To set the order for the policies, I need to use numbering as part of the policy name. So when naming the policies. the first policy name starts with 010, the second policy’s name begins with 020 and so on.

Once the policies are in place, a script like the one shown below can be used to access the list of policy IDs via the API and run the policies in their specified order.

# Set username of the API user.
# Script uses Parameter 4 to get the appropriate username from Jamf Pro
# Set password of the API user.
# Script uses Parameter 5 to get the appropriate password from Jamf Pro.
# Set the policy category which contains the Jamf Pro
# policies that need to be run. Script uses Parameter 6
# to get the appropriate category from Jamf Pro.
CheckBinary (){
# Identify location of jamf binary.
jamf_binary=`/usr/bin/which jamf`
if [[ "$jamf_binary" == "" ]] && [[ -e "/usr/sbin/jamf" ]] && [[ ! -e "/usr/local/bin/jamf" ]]; then
elif [[ "$jamf_binary" == "" ]] && [[ ! -e "/usr/sbin/jamf" ]] && [[ -e "/usr/local/bin/jamf" ]]; then
elif [[ "$jamf_binary" == "" ]] && [[ -e "/usr/sbin/jamf" ]] && [[ -e "/usr/local/bin/jamf" ]]; then
# Run the CheckBinary function to identify the location
# of the jamf binary
# If the jamf binary isn't found, stop the script
# and exit with an error status.
if [[ "$jamf_binary" == "" ]]; then
/bin/echo "`date +%Y-%m-%d\ %H:%M:%S` Jamf Pro agent not found. Exiting."
exit 1
# Identify the URL of the Jamf Pro server using the
# 'jamf checkJSSConnection' command
JamfProURLCheck=$("$jamf_binary" checkJSSConnection | awk '/Checking/ {print $4}')
JamfProURL=$(echo ${JamfProURLCheck///…})
# Save current IFS state
# Change IFS to
# create newline
casper_policy_ids=`/usr/bin/curl -ksf -u "${apiUsername}:${apiPassword}" -H "Accept: application/xml" "${JamfProPolicyURL}" | xpath "policies/policy/id" | sed 's/\<id>//g' | tr '</id>' '\n' | sed '/^s*$/d'`
# read all policy IDs into an array
policies=($(/bin/echo "$casper_policy_ids"))
# restore IFS to previous state
# Get length of the array
# Run all matching Jamf Pro policies in the order received from the Jamf Pro server
for (( i=0; i<${tLen}; i++ ));
/bin/echo "`date +%Y-%m-%d\ %H:%M:%S` Installing policy "${policies[$i]}" on this Mac."
"$jamf_binary" policy -id "${policies[$i]}"

The script is also available on Github at the following address:


If you want to run this script from your Jamf Pro server, it should be set up as follows.

Screen Shot 2017 04 05 at 3 01 14 PM

Screen Shot 2017 04 05 at 3 01 18 PM

Screen Shot 2017 04 05 at 3 01 22 PM

To use this capability, you will need to set up a category if needed and assign your policies to it. For this example, I’ve created a category named InitialSetup.

Screen Shot 2017 04 05 at 5 14 40 PM

Once created, assign your policies to this category. If needed, rename the policies to include numerical values. The number values will designate the order for the policies to run.

Screen Shot 2017 04 05 at 3 38 20 PM

Once the category and policies have been set up as desired, you can have a separate policy or other means run the script. The script will need to have the following information specified:

  • API username
  • API password
  • Category name
Screen Shot 2017 04 05 at 3 04 06 PM
With this information available, the script will query the API for the appropriate policy information and then run the policies in the specified order.

One notable thing about running policies using this technique is the affected policies do not need to be associated with any of the usual triggers.

Screen Shot 2017 04 05 at 9 50 25 PM

Instead, the policy is being called directly by its ID number, which in this case will act as a trigger to run the policy:

jamf policy -id policy_id_number_goes_here
Categories: Casper, Jamf Pro, Scripting
  1. richardpurves
    April 6, 2017 at 6:53 am

    Does that work with spaces in the category names? I think it should judging by your use of IFS.

  2. mackitzy
    April 6, 2017 at 3:39 pm

    Why not just use a custom trigger? Am I missing something?

  1. No trackbacks yet.

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 )

Connecting to %s

%d bloggers like this: