Home > Jamf Pro, Jamf Pro API, Scripting > Identifying Self Service policies with blank descriptions

Identifying Self Service policies with blank descriptions

As part of setting up Self Service policies in Jamf Pro, it’s nice to include a description for your customers of what they’re getting when they select a particular Self Service policy.

Screen Shot 2019 09 16 at 2 37 05 PM

However, sometimes folks forget to add these descriptions and it can be hard to figure this out later which ones were missed without manually checking each policy.

Screen Shot 2019 09 16 at 2 16 38 PM

To help with situations like this, I have a script which does the following:

  1. Checks all policies on a Jamf Pro server.
  2. Identifies which ones are Self Service policies which do not have descriptions
  3. Displays a list of the relevant policies

For more details, please see below the jump.

The script is named Jamf_Pro_Detect_Self_Service_Policies_Without_Descriptions.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

When the script is run, you should see output similar to that shown below.


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



# This script uses the Jamf Pro Classic API to detect which
# Self Service policies do not have descriptions and displays
# a list of the relevant policies.
# Set default exit code
# 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.
# Set the username here if you want it hardcoded.
# Set the password here if you want it hardcoded.
# Read the appropriate values from ~/Library/Preferences/com.github.jamfpro-info.plist
# if the file is available. To create the file, run the following commands:
# defaults write $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_url https://jamf.pro.server.here
# defaults write $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_user API_account_username_goes_here
# defaults write $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_password API_account_password_goes_here
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)
if [[ -z "$jamfpro_user" ]]; then
jamfpro_user=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_user)
if [[ -z "$jamfpro_password" ]]; then
jamfpro_password=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_password)
# 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
if [[ -z "$jamfpro_user" ]]; then
read -p "Please enter your Jamf Pro user account : " jamfpro_user
if [[ -z "$jamfpro_password" ]]; then
read -p "Please enter the password for the $jamfpro_user account: " -s jamfpro_password
# Remove the trailing slash from the Jamf Pro URL if needed.
# The following function downloads individual Jamf Pro policy as XML data
# then mines the policy data for the relevant information.
local PolicyId="$1"
if [[ -n "$PolicyId" ]]; then
local DownloadedXMLData=$(curl -su "${jamfpro_user}:${jamfpro_password}" -H "Accept: application/xml" "${jamfpro_url}/JSSResource/policies/id/$PolicyId")
local PolicyName=$( echo "$DownloadedXMLData" | xmllint –xpath '/policy/general/name/text()'2>/dev/null)
local SelfServicePolicyCheck=$(echo "$DownloadedXMLData" | xmllint –xpath '/policy/self_service/use_for_self_service/text()'2>/dev/null)
local SelfServiceDescription=$(echo "$DownloadedXMLData" | xmllint –xpath '/policy/self_service/self_service_description/text()'2>/dev/null)
# If a policy is detected as being a Self Service policy with an
# empty description, the policy name is saved to a temp file.
if [[ "$SelfServicePolicyCheck" = "true" ]] && [[ -z "$SelfServiceDescription" ]]; then
echo "The following Self Service policy has a blank description: $PolicyName" >> "$PolicyCountFile"
# Download all Jamf Pro policy ID numbers
PolicyIDList=$(curl -su "${jamfpro_user}:${jamfpro_password}" -H "Accept: application/xml" "${jamfpro_url}/JSSResource/policies" | xpath "//id" 2>/dev/null)
PolicyIDs=$(echo "$PolicyIDList" | grep -Eo "[0-9]+")
PoliciesCount=$(echo "$PolicyIDs" | grep -c ^)
echo "Checking $PoliciesCount policies for Self Service policies with blank descriptions …"
# Download latest version of all computer policies using their ID numbers.
# For performance reasons, we parallelize the execution.
# Create temp file for background processes' output
touch "$PolicyCountFile"
for anID in ${PolicyIDs}; do
# Run API calls in parallel
((ActiveJobs=ActiveJobs%MaximumConcurrentJobs)); ((ActiveJobs++==0)) && wait
CheckSelfServicePolicyCheckDescriptions $anID &
ProcessedJobs=$(( $ProcessedJobs + 1 ))
PercentComplete=$(echo "(100/${PoliciesCount})*${ProcessedJobs}" | bc -l | awk '{print int($1+0.5)}')
ProgressDone=$(echo "$PercentComplete/2" | bc -l | awk '{print int($1+0.5)}')
ProgressLeft=$(( 50 $ProgressDone ))
DonePattern=$(printf "%${ProgressDone}s")
LeftPattern=$(printf "%${ProgressLeft}s")
printf "\rProcessing: [${DonePattern// /#}${LeftPattern// /-}] ${PercentComplete}%%"
PolicyCountNumber=$(grep -c ^ "$PolicyCountFile")
echo "$PolicyCountNumber Self Service policies detected with blank descriptions"
cat "$PolicyCountFile"
echo "Policy check completed."
# Remove temp file
rm "$PolicyCountFile"
exit $exitCode

  1. No comments yet.
  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: