Home > Jamf Pro, Jamf Pro API, Scripting > Backing up macOS management policies from Jamf Pro

Backing up macOS management policies from Jamf Pro

When working with computer management policies on Jamf Pro, especially more complex policies, I prefer to download then and back them up to GitHub or a similar internal source control tool. The reasons I do this are the following:

  1. I have an off-server backup for the policies
  2. I can track changes to the groups
  3. If needed, I can make a change to a policy and upload via the API instead of having to edit in the web console.

Up until recently, I didn’t have a good process for handling this but after some work, I was able to build a script which does the following:

  1. If any policies were previously downloaded, back up existing downloaded policies into a .zip file
  2. Download the policy information as XML
  3. Properly format the downloaded XML
  4. Identify the display name of the policy.
  5. Identify the category of the policy.
  6. Save the downloaded XML as Policy Name Here.xml to a specified download directory, based on the category that the policy is in.

The reason the script archives previously downloaded policies are the following:

  1. In case something goes wrong with the download, I still have the previously archived copy.
  2. The script can clear out the existing download directory and have only the latest version of the policy stored inside.

For more details, please see below the jump.

The script I’ve written is named Jamf_Pro_Computer_Policy_Download.sh. For authentication, the script can accept hard-coded values in the script, manual input or values stored in a ~/Library/Preferences/com.github.jamfpro-info.plist file.

The plist file can be created by running the following commands and substituting your own values where appropriate:

To store the Jamf Pro URL in the plist file:

defaults write com.github.jamfpro-info jamfpro_url https://jamf.pro.server.goes.here:port_number_goes_here

To store the account username in the plist file:

defaults write com.github.jamfpro-info jamfpro_user account_username_goes_here

To store the account password in the plist file:

defaults write com.github.jamfpro-info jamfpro_password account_password_goes_here

The policies themselves will be stored in either a user-specified directory or, if no directory is specified, a directory created by the script. When the script is run, you should see output similar to that shown below.

If no download directory is specified:

computername:~ username$ /path/to/Jamf_Pro_Computer_Policy_Download.sh
Please enter your Jamf Pro server URL : https://jamfpro.server.here:8443
Please enter your Jamf Pro user account : jpadmin
Please enter the password for the jpadmin account:
A location to store downloaded policies has not been specified.
Downloaded policies will be stored in /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj.
/var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj not found. Creating…
Successfully created /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Casper Online
Saving Casper Online.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Utility Scripts.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Disable Apple iCloud and Diagnostic pop-ups
Saving Disable Apple iCloud and Diagnostic pop-ups.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Utility Scripts.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Encrypt Macs
Saving Encrypt Macs.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Security.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Fix JAMF MDM certificate
Saving Fix JAMF MDM certificate.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Utility Scripts.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Microsoft Office 365
Saving Microsoft Office 365.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Microsoft.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Microsoft OneNote
Saving Microsoft OneNote.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Microsoft.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Microsoft Remote Desktop
Saving Microsoft Remote Desktop.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Remote Access.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Push Install VMware Tools
Saving Push Install VMware Tools.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/VMware.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Rotate FileVault 2 recovery key
Saving Rotate FileVault 2 recovery key.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Security.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Slack
Saving Slack.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Communication.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Update Inventory
Saving Update Inventory.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Utility.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: VMware Tools
Saving VMware Tools.xml file to /var/folders/q6/z5m752w547sbrcjqwd0783340000kt/T/tmp.v8QzARJj/Virtualization.
computername:~ username$

view raw
gistfile1.txt
hosted with ❤ by GitHub

Screen Shot 2018 12 21 at 3 02 31 PM

Screen Shot 2018 12 21 at 3 04 24 PM

If a download directory is specified and has existing contents:

computername:~ username$ /path/to/Jamf_Pro_Computer_Policy_Download.sh
Please enter your Jamf Pro server URL : https://jamfpro.server.here:8443
Please enter your Jamf Pro user account : jpadmin
Please enter the password for the jpadmin account:
Archiving previous policy download directory to /path/to/PolicyDownloadDirectoryArchive-20181221152703.zip
Successfully created /path/to/PolicyDownloadDirectoryArchive-20181221152703.zip
Successfully created new /path/to/downloaded_policies
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Casper Online
Saving Casper Online.xml file to /path/to/downloaded_policies/Utility Scripts.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Disable Apple iCloud and Diagnostic pop-ups
Saving Disable Apple iCloud and Diagnostic pop-ups.xml file to /path/to/downloaded_policies/Utility Scripts.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Encrypt Macs
Saving Encrypt Macs.xml file to /path/to/downloaded_policies/Security.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Fix JAMF MDM certificate
Saving Fix JAMF MDM certificate.xml file to /path/to/downloaded_policies/Utility Scripts.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Microsoft Office 365
Saving Microsoft Office 365.xml file to /path/to/downloaded_policies/Microsoft.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Microsoft OneNote
Saving Microsoft OneNote.xml file to /path/to/downloaded_policies/Microsoft.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Microsoft Remote Desktop
Saving Microsoft Remote Desktop.xml file to /path/to/downloaded_policies/Remote Access.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Push Install VMware Tools
Saving Push Install VMware Tools.xml file to /path/to/downloaded_policies/VMware.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Rotate FileVault 2 recovery key
Saving Rotate FileVault 2 recovery key.xml file to /path/to/downloaded_policies/Security.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Slack
Saving Slack.xml file to /path/to/downloaded_policies/Communication.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: Update Inventory
Saving Update Inventory.xml file to /path/to/downloaded_policies/Utility.
Downloading macOS computer policies from https://jamfpro.server.here:8443…
Downloaded policy is named: VMware Tools
Saving VMware Tools.xml file to /path/to/downloaded_policies/Virtualization.
computername:~ username$

view raw
gistfile1.txt
hosted with ❤ by GitHub

Screen Shot 2018 12 21 at 3 32 52 PM

Screen Shot 2018 12 21 at 3 29 47 PM

Screen Shot 2018 12 21 at 3 28 49 PM

The script is available below, and at the following address on GitHub:

https://github.com/rtrouton/rtrouton_scripts/tree/master/rtrouton_scripts/Casper_Scripts/Jamf_Pro_Computer_Policy_Download

Jamf_Pro_Computer_Policy_Download.sh:

#!/bin/bash
# This script is designed to use the Jamf Pro API to identify the individual IDs of
# the policies stored on a Jamf Pro server then do the following:
#
# 1. Back up existing downloaded policies
# 2. Download the policy as XML
# 3. Identify the policy name
# 4. Categorize the downloaded policy
# 5. Save the policy to a specified directory
# If setting up a specific user account with limited rights, here are the required API privileges
# for the account on the Jamf Pro server:
#
# Jamf Pro Server Objects:
#
# Policies: Read
# Set exit error status
ERROR=0
# If you choose to specify a directory to save the downloaded policies into,
# please enter the complete directory path into the PolicyDownloadDirectory
# variable below.
PolicyDownloadDirectory=""
# If the PolicyDownloadDirectory isn't specified above, a directory will be
# created and the complete directory path displayed by the script.
# If you choose to hardcode API information into the script, set one or more of the following values:
#
# The username for an account on the Jamf Pro server with sufficient API privileges
# The password for the account
# The Jamf Pro URL
# Set the Jamf Pro URL here if you want it hardcoded.
jamfpro_url=""
# Set the username here if you want it hardcoded.
jamfpro_user=""
# Set the password here if you want it hardcoded.
jamfpro_password=""
# If you do not want to hardcode API information into the script, you can also store
# these values in a ~/Library/Preferences/com.github.jamfpro-info.plist file.
#
# To create the file and set the values, run the following commands and substitute
# your own values where appropriate:
#
# To store the Jamf Pro URL in the plist file:
# defaults write com.github.jamfpro-info jamfpro_url https://jamf.pro.server.goes.here:port_number_goes_here
#
# To store the account username in the plist file:
# defaults write com.github.jamfpro-info jamfpro_user account_username_goes_here
#
# To store the account password in the plist file:
# defaults write com.github.jamfpro-info jamfpro_password account_password_goes_here
#
# If the com.github.jamfpro-info.plist file is available, the script will read in the
# relevant information from the plist file.
if [[ -f "$HOME/Library/Preferences/com.github.jamfpro-info.plist" ]]; then
if [[ -z "$jamfpro_url" ]]; then
jamfpro_url=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_url)
fi
if [[ -z "$jamfpro_user" ]]; then
jamfpro_user=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_user)
fi
if [[ -z "$jamfpro_password" ]]; then
jamfpro_password=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_password)
fi
fi
# If the Jamf Pro URL, the account username or the account password aren't available
# otherwise, you will be prompted to enter the requested URL or account credentials.
if [[ -z "$jamfpro_url" ]]; then
read -p "Please enter your Jamf Pro server URL : " jamfpro_url
fi
if [[ -z "$jamfpro_user" ]]; then
read -p "Please enter your Jamf Pro user account : " jamfpro_user
fi
if [[ -z "$jamfpro_password" ]]; then
read -p "Please enter the password for the $jamfpro_user account: " -s jamfpro_password
fi
echo ""
# Remove the trailing slash from the Jamf Pro URL if needed.
jamfpro_url=${jamfpro_url%%/}
initializePolicyDownloadDirectory ()
{
if [[ -z "$PolicyDownloadDirectory" ]]; then
PolicyDownloadDirectory=$(mktemp -d)
echo "A location to store downloaded policies has not been specified."
echo "Downloaded policies will be stored in $PolicyDownloadDirectory."
echo "$PolicyDownloadDirectory not found. Creating…"
mkdir -p $PolicyDownloadDirectory
if (( $? == 0 ))
then
echo "Successfully created $PolicyDownloadDirectory"
else
echo "Could not create $PolicyDownloadDirectory"
echo "Please make sure the parent directory is writable. Exiting…."
ERROR=1
exit $ERROR
fi
else
# Remove the trailing slash from the PolicyDownloadDirectory variable if needed.
PolicyDownloadDirectory=${PolicyDownloadDirectory%%/}
if [[ -d "$PolicyDownloadDirectory" ]] && [[ -n "$(ls -A "$PolicyDownloadDirectory")" ]]; then
archive_file="PolicyDownloadDirectoryArchive-`date +%Y%m%d%H%M%S`.zip"
echo "Archiving previous policy download directory to ${PolicyDownloadDirectory%/*}/$archive_file"
ditto -ck "$PolicyDownloadDirectory" "${PolicyDownloadDirectory%/*}/$archive_file"
if (( $? == 0 )); then
echo "Successfully created ${PolicyDownloadDirectory%/*}/$archive_file"
else
echo "Could not create $archive_file. Exiting…."
ERROR=1
exit $ERROR
fi
# Removing existing directory after archiving is complete.
rm -rf $PolicyDownloadDirectory
# Creating a new directory with the same name.
mkdir -p $PolicyDownloadDirectory
if (( $? == 0 ))
then
echo "Successfully created new $PolicyDownloadDirectory"
else
echo "Could not create new $PolicyDownloadDirectory"
echo "Please make sure the parent directory is writable. Exiting…."
ERROR=1
exit $ERROR
fi
elif [[ -d "$PolicyDownloadDirectory" ]] && [[ -z "$(ls -A "$PolicyDownloadDirectory")" ]]; then
echo "$PolicyDownloadDirectory exists but is empty. Using existing directory for downloading policies."
elif [[ -n "$PolicyDownloadDirectory" ]] && [[ ! -d "$PolicyDownloadDirectory" ]]; then
echo "$PolicyDownloadDirectory does not exist. Creating $PolicyDownloadDirectory for downloading policies."
mkdir -p $PolicyDownloadDirectory
if (( $? == 0 )); then
echo "Successfully created new $PolicyDownloadDirectory"
else
echo "Could not create new $PolicyDownloadDirectory"
echo "Please make sure the parent directory is writable. Exiting…."
ERROR=1
exit $ERROR
fi
fi
fi
}
DownloadComputerPolicy(){
# Download the policy information as raw XML,
# then format it to be readable.
echo "Downloading macOS computer policies from $jamfpro_url"
FormattedComputerPolicy=$(curl -su "${jamfpro_user}:${jamfpro_password}" -H "Accept: application/xml" "${jamfpro_url}/JSSResource/policies/id/${ID}" -X GET | xmllint –format – )
# Identify and display the policy's name.
DisplayName=$(echo "$FormattedComputerPolicy" | xpath "/policy/general/name/text()" 2>/dev/null | sed -e 's|:|(colon)|g' -e 's/\//\\/g')
echo "Downloaded policy is named: $DisplayName"
# Identify the policy category
PolicyCategory=$(echo "$FormattedComputerPolicy" | xpath "/policy/general/category/name/text()" 2>/dev/null | sed -e 's|:|(colon)|g' -e 's/\//\\/g')
# Save the downloaded policy.
echo "Saving ${DisplayName}.xml file to $PolicyDownloadDirectory/$PolicyCategory."
if [[ -d "$PolicyDownloadDirectory/$PolicyCategory" ]]; then
echo "$FormattedComputerPolicy" > "$PolicyDownloadDirectory/$PolicyCategory/${DisplayName}.xml"
else
mkdir -p "$PolicyDownloadDirectory/$PolicyCategory"
echo "$FormattedComputerPolicy" > "$PolicyDownloadDirectory/$PolicyCategory/${DisplayName}.xml"
fi
}
# Back up existing policy downloads and create policy download directory.
initializePolicyDownloadDirectory
# Download latest version of all computer policies
ComputerPolicy_id_list=$(curl -su "${jamfpro_user}:${jamfpro_password}" -H "Accept: application/xml" "${jamfpro_url}/JSSResource/policies" | xpath "//id" 2>/dev/null)
ComputerPolicy_id=$(echo "$ComputerPolicy_id_list" | grep -Eo "[0-9]+")
for ID in ${ComputerPolicy_id}; do
DownloadComputerPolicy
done
exit $ERROR

  1. Lewis
    January 11, 2019 at 3:16 pm

    Awesome work!!! I’ve been waiting for this capability for ages. Are you looking into a script to upload the XML back into Jamf?

  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 )

Google photo

You are commenting using your Google 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: