Posted on 07-23-2018 01:40 PM
Since Jamf Pro PI-005903, I’ve been thinking of a faster way to update policies.
Last week, Adobe released six updates which — outside of building new packages via Adobe's admin console — effectively required only incrementing a version number four places in each policy (please don't tell @talkingmoose):
- Adobe After Effects CC 15.1.1 was update to: Adobe After Effects CC 15.1.2
- Adobe Media Encoder CC 12.1.1 was update to: Adobe Media Encoder CC 12.1.2
- Adobe Bridge CC 8.0.1 was update to: Adobe Bridge CC 8.1
- Adobe Premiere Pro CC 12.1.1 was update to: Adobe Premiere Pro CC 12.1.2
- Adobe Prelude CC 7.1 was update to: Adobe Prelude CC 7.1.1
- Adobe XD CC 9.1.12 was updated to: Adobe XD CC 10.0.12
With inspiration from @mm2270's API scripts, and lots of feedback from @Leslie, Jamf Pro Policy Editor Lite was born.
To utilize this script, the API account must have the following privileges:
- Policies: CREATE, READ, UPDATE
- Because of the need to use API credentials with Create privileges, the script allows you to interactively enter the credentials so they don't need to be stored within the script. (Thanks, mm2270)
- The script performs only minor error checking; please ensure proper API credentials or you will encounter errors
If policies include the version number in parenthesis, for example: "Adobe Prelude CC 2018 (7.1.1)", the script will automatically parse the version number, for example: "7.1.1"; otherwise, you will be prompted for the version number.
The updated package must be present before running this script.
This script was designed to be run interactively in Terminal and allows you to use the API (along with valid API credentials) to update a policy's version number.
This script uses some BASH specific items; please first make the script executable:
chmod +x /path/to/Jamf Pro Policy Editor Lite.sh
To use the script:/path/to/path/to/Jamf Pro Policy Editor Lite.sh
While the script does backup a policy's XML before performing updates, please thoroughly test before using in production.
Latest version on GitHub.
#!/bin/bash
####################################################################################################
#
# ABOUT
#
# Jamf Pro Policy Editor Lite: Edit a policy's version number via the API
#
####################################################################################################
#
# HISTORY
#
# Version 1.0, 23-Jul-2018, Dan K. Snelson
# Original Version
# With inspiration from mm2270
# https://github.com/mm2270/Casper-API/blob/master/Convert-SG-Search-Search-SG.sh
#
####################################################################################################
####################################################################################################
#
# Global Variables
#
####################################################################################################
# Values for API connection; if left blank, you will be prompted to interactively enter
apiURL=""
apiUser=""
apiPassword=""
# Debug mode [ true | false ]
debug="false"
# ------------------------------ No edits required below this line --------------------------------
###################################################################################################
#
# Define the Functions
#
####################################################################################################
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Create Working Diretory and Log file
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function createWorkingDirectory() {
# Currently logged-in user
loggedInUser=$( /usr/bin/stat -f%Su /dev/console )
# Time stamp for log file
timestamp=$( /bin/date '+%Y-%m-%d-%H%M%S' )
# Working Directory
workingDirectory="/Users/${loggedInUser}/Documents/Jamf_Pro_Policy_Editor_Lite"
logDirectory="${workingDirectory}/Logs/"
logFile="${logDirectory}/Jamf_Pro_Policy_Editor_Lite-${timestamp}.log"
# Ensure Working Directory exists
if [[ ! -d ${workingDirectory} ]]; then
/bin/mkdir -p ${workingDirectory}
fi
# Ensure Log Directory exists
if [[ ! -d ${logDirectory} ]]; then
/bin/mkdir -p ${logDirectory}
fi
# Ensure Log File exists
if [[ ! -d ${logFile} ]]; then
/usr/bin/touch ${logFile}
echo "Log file created `date`" >> ${logFile}
fi
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Logging
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function ScriptLog() { # Re-direct logging to the log file ...
NOW=`date +%Y-%m-%d %H:%M:%S`
/bin/echo "${NOW}" " ${1}" >> "${logFile}"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Reveal File in Finder
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function revealMe() {
/usr/bin/open -R "${1}"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# API Connection
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function apiConnectionSettings() {
printf "
-------------------------------------------------------------------------------------------------------"
printf "
###
"
echo "# Step 1 of 6: API Connection Settings"
printf "###
"
promptAPIurl
promptAPIusername
promptAPIpassword
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Prompt user for API URL
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function promptAPIurl() {
if [[ -z "$apiURL" ]]; then
ScriptLog "API URL is blank; attempt to read from JAMF plist ..."
# Read the API URL from the JAMF preferences
if [[ -e "/Library/Preferences/com.jamfsoftware.jamf.plist" ]]; then
ScriptLog "Found JAMF plist; read its URL ..."
apiURL=$( defaults read "/Library/Preferences/com.jamfsoftware.jamf.plist" jss_url | sed 's|/$||' )
echo "
Use this URL? ${apiURL}
[y] Yes - Use the URL presented above
[n] No - Enter the API URL at the next prompt
[x] Exit"
read -n 1 -r -p "`echo $'
> '`" urlResponse
ScriptLog "Use this URL: ${apiURL}? ${urlResponse}"
case "$urlResponse" in
y|Y)
apiURL="$apiURL"
;;
n|N)
printf "
Enter the API URL:"
read -r -p "`echo $'
> '`" newURLResponse
if [[ -z "$newURLResponse" ]]; then
ScriptLog "No API URL provided; exiting."
printf "
No API URL provided; exiting.
"
exit 0
fi
apiURL="${newURLResponse}"
ScriptLog "API URL: ${apiURL}"
;;
x|X)
ScriptLog "Exiting. Goodbye!"
printf "
Exiting. Goodbye!
"
exit 0
;;
*)
ScriptLog "ERROR: Invalid response: ${urlResponse}; exiting."
printf "
ERROR: Invalid response; exiting.
"
exit 1
;;
esac
else
ScriptLog "No API URL is specified in the script; prompt user ..."
echo "
No API URL is specified in the script. Enter it now?
[y] Yes - Enter the URL at the next prompt
[n] No - Exit the script"
read -n 1 -r -p "`echo $'
> '`" urlResponse
case "$urlResponse" in
y|Y)
printf "
Enter the API URL:"
read -r -p "`echo $'
> '`" userURLResponse
if [[ -z "$userURLResponse" ]]; then
ScriptLog "No API URL provided; exiting."
printf "
No API URL provided; exiting.
"
exit 0
fi
apiURL="$userURLResponse"
ScriptLog "API URL: ${apiURL}"
;;
n|N)
ScriptLog "Exiting. Goodbye!"
printf "
Exiting. Goodbye!
"
exit 0
;;
*)
ScriptLog "ERROR: Invalid response ${urlResponse}; exiting."
printf "
ERROR: Invalid response; exiting.
"
exit 1
;;
esac
fi
fi
apiURL=$( echo "$apiURL" | sed 's|/$||' )
ScriptLog "Using the API URL of: ${apiURL}"
printf "
• Using the API URL of: ${apiURL}"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Prompt user for API Username
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function promptAPIusername() {
if [[ -z "${apiUser}" ]]; then
ScriptLog "API username is blank; attempt to read from JAMF plist ..."
printf "
No API Username has been supplied. Enter it now?
[y] Yes - Enter the Username at the next prompt
[n] No/Exit
"
read -n 1 -r -p "`echo $'
> '`" apiUsernameResponse
case "$apiUsernameResponse" in
y|Y)
printf "
API Username:"
read -r -p "`echo $'
> '`" apiUserName
if [[ -z "${apiUserName}" ]]; then
printf "
No API Username provided; exiting.
"
exit 0
fi
apiUser="${apiUserName}"
;;
n|N)
printf "
Exiting. Goodbye!
"
exit 0
;;
*)
printf "
Invalid response! Please try again."
promptAPIusername
;;
esac
fi
ScriptLog "Using the API Username of: ${apiUser}"
printf "
• Using the API Username of: ${apiUser}"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Prompt user for API Password
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function promptAPIpassword() {
if [[ -z "${apiPassword}" ]]; then
printf "
No API Password has been supplied. Enter it now?
[y] Yes - Enter the password at the next prompt
[n] No/Exit
"
read -n 1 -r -p "`echo $'
> '`" apiPasswordEntryResponse
case "$apiPasswordEntryResponse" in
y|Y)
printf "
API Password:
>"
read -s apiPasswordEntry
if [[ -z "${apiPasswordEntry}" ]]; then
printf "
No API Password provided; exiting.
"
exit 0
fi
apiPassword="${apiPasswordEntry}"
;;
n|N)
printf "
Exiting. Goodbye!
"
exit 0
;;
*)
printf "
Invalid response! Please try again."
promptAPIpassword
;;
esac
fi
if [[ ${debug} == "true" ]]; then
ScriptLog "Using the API Password of: ${apiPassword}"
printf "
• Using the API Password of: ${apiPassword}
"
else
printf "
• Using the supplied API password
"
fi
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Select Policy to Update (Thanks, mm2270!)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function selectPolicy() {
# Reset Variables
ScriptLog "Reset variables ..."
unset policyNames policyIDs policyName policyNamesArray policyID policyIDsArray policyChoice
printf "
-------------------------------------------------------------------------------------------------------"
printf "
###
"
echo "# Step 2 of 6: Select Policy to Update"
printf "###
"
# Build two lists via the API: One for Policy names; the other for their respective IDs.
ScriptLog "Build list of policy names via API ..."
policyNames=$( /usr/bin/curl -H "Accept: text/xml" -sfku "${apiUser}:${apiPassword}" "${apiURL}/JSSResource/policies" | xmllint --format - | awk -F'>|<' '/<name>/{print $3}')
ScriptLog "Build list of policy IDs via API ..."
policyIDs=$( /usr/bin/curl -H "Accept: text/xml" -sfku "${apiUser}:${apiPassword}" "${apiURL}/JSSResource/policies" | xmllint --format - | awk -F'>|<' '/<id>/{print $3}')
# Create array for Policy names
ScriptLog "Create array for Policy names ..."
while read policyName; do
policyNamesArray+=("$policyName")
done < <( printf '%s
' "$policyNames" )
# Create array for Policy IDs
ScriptLog "Create array for Policy IDs ..."
while read policyID; do
policyIDsArray+=("$policyID")
done < <( printf '%s
' "$policyIDs" )
# Display Policy names with index labels
ScriptLog "Display Policy names with index labels ..."
for i in "${!policyNamesArray[@]}"; do
printf "%s %s
" "[$i]" "${policyNamesArray[$i]}"
done
echo "
Choose the Policy to update by entering its index number:"
read -r -p "`echo $'
> '`" policyChoice
if [ "${policyChoice}" -eq "${policyChoice}" ] 2>/dev/null; then
ScriptLog "Policy index: ${policyChoice}"
else
printf "
ERROR: "${policyChoice}" is not an index number; exiting.
"
ScriptLog "ERROR: "${policyChoice}" is not an index number; exiting."
exit 1
fi
echo " "
echo "Policy Name: ${policyNamesArray[$policyChoice]}"
echo " Policy ID: ${policyIDsArray[$policyChoice]}"
echo " "
# Assign Policy ID to variable
policyID="${policyIDsArray[$policyChoice]}"
ScriptLog "User selected: Policy ID ${policyID} ${policyNamesArray[$policyChoice]}"
promptToContinue
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Download and backup the Policy XML
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function downloadBackupXML() {
printf "
-------------------------------------------------------------------------------------------------------"
printf "
###
"
echo "# Step 3 of 6: Download and Backup Policy XML"
printf "###
"
echo "• Downloading XML for Policy ID ${policyID} ..."
ScriptLog "Downloading XML for Policy ID ${policyID} ..."
# Backup Directory
backupDirectory="${workingDirectory}/Backups/${timestamp}"
# Ensure Backup Directory exists
if [[ ! -d ${backupDirectory} ]]; then
/bin/mkdir -p ${backupDirectory}
ScriptLog "Created backup directory: ${backupDirectory}"
fi
# Updates Directory
updatesDirectory="${workingDirectory}/Updates/${timestamp}"
# Ensure Update Directory exists
if [[ ! -d ${updatesDirectory} ]]; then
/bin/mkdir -p ${updatesDirectory}
ScriptLog "Created update directory: ${updatesDirectory}"
fi
# Download policy XML
if [[ ${debug} == "true" ]]; then
/usr/bin/curl -u "$apiUser":"$apiPassword" $apiURL/JSSResource/policies/id/${policyID} -H "Accept: application/xml" -X GET -o ${backupDirectory}/policy-${policyID}.xml
else
/usr/bin/curl -s -u "$apiUser":"$apiPassword" $apiURL/JSSResource/policies/id/${policyID} -H "Accept: application/xml" -X GET -o ${backupDirectory}/policy-${policyID}.xml
fi
echo "• Downloaded to: ${backupDirectory}/policy-${policyID}.xml ..."
ScriptLog "Downloaded to: ${backupDirectory}/policy-${policyID}.xml"
# Copy downloaded XML to Updates directory
echo "• Copying ../Backups/policy-${policyID}.xml to ../Updates/policy-${policyID}.xml"
ScriptLog "Copying ../Backups/policy-${policyID}.xml to ../Updates/policy-${policyID}.xml"
if [[ ${debug} == "true" ]]; then
/bin/cp -v ${backupDirectory}/policy-${policyID}.xml ${updatesDirectory}/policy-${policyID}.xml
else
/bin/cp ${backupDirectory}/policy-${policyID}.xml ${updatesDirectory}/policy-${policyID}.xml
fi
echo "• Copied to ../Updates/policy-${policyID}.xml"
ScriptLog "Copied to ../Updates/policy-${policyID}.xml"
# Exit if update file does not exist
if [[ ! -f "${updatesDirectory}/policy-${policyID}.xml" ]]; then
echo "ERROR: Policy file "../Updates/policy-${policyID}.xml" does NOT exist; exiting"
ScriptLog "ERROR: Policy file "../Updates/policy-${policyID}.xml" does NOT exist; exiting"
exit 1
fi
printf "
-------------------------------------------------------------------------------------------------------
"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Prompt the user for the new version number
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function promptNewVersion() {
printf "
###
"
echo "# Step 4 of 6: Specify new version number"
printf "###
"
# Lookup policy name
policyName=$( /usr/bin/xmllint --xpath "/policy/general/name/text()" ${updatesDirectory}/policy-${policyID}.xml )
printf "• Policy Name: ${policyName}
"
ScriptLog "Policy Name: ${policyName}"
# Determine current version
currentVersion=$( echo $policyName | /usr/bin/awk -F"[()]" '{print $2}' )
if [[ -z ${currentVersion} ]]; then
# Prompt user for current version
printf "• Current version: UNKOWN
"
read -p "Please specify the current version number: `echo $'
> '`" currentVersion
ScriptLog "Current version number: ${currentVersion}"
echo " "
fi
printf "• Current version: ${currentVersion}
"
ScriptLog "Current version: ${currentVersion}"
read -p "Please specify the new version number: `echo $'
> '`" newVersion
ScriptLog "New version number: ${newVersion}"
echo " "
read -n 1 -r -p "Are you sure you want to update version "${currentVersion}" to version "${newVersion}"? [y]es or [n]o: `echo $'
> '`" confirmUpdate
ScriptLog "Are you sure you want to update version "${currentVersion}" to version "${newVersion}"?: ${confirmUpdate}"
case "${confirmUpdate}" in
y|Y )
updatePolicyVersion
updatePackageID
;;
n|N )
printf "
No; exiting
"
exit 0
;;
*)
printf "
ERROR: Did not recognize response: ${confirmUpdate}; exiting.
"
exit 1
;;
esac
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Update Policy Version
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function updatePolicyVersion() {
printf "
-------------------------------------------------------------------------------------------------------
"
printf "
###
"
echo "# Step 5 of 6: Update Policy"
printf "###
"
echo "• Replacing "${currentVersion}" with "${newVersion}" ..."
ScriptLog "Replacing "${currentVersion}" with "${newVersion}" ..."
/usr/bin/sed -i.bak1 "s|${currentVersion}|${newVersion}|g" ${updatesDirectory}/policy-${policyID}.xml
echo "• Done."
newpolicyName=$( /usr/bin/xmllint --xpath "/policy/general/name/text()" ${updatesDirectory}/policy-${policyID}.xml )
printf "• New Policy version: ${newpolicyName}
"
ScriptLog "New Policy version: ${newpolicyName}"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Update Package ID
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function updatePackageID() {
echo "• Updating Package ID for "${newpolicyName}" ..."
ScriptLog "Updating Package ID for "${newpolicyName}" ..."
currentPackageID=$( /usr/bin/xmllint --xpath "/policy/package_configuration/packages/package/id/text()" ${updatesDirectory}/policy-${policyID}.xml )
echo "• The "${policyName}" policy has a Package ID of: ${currentPackageID}"
newPackageName=$( /usr/bin/xmllint --xpath "/policy/package_configuration/packages/package/name/text()" ${updatesDirectory}/policy-${policyID}.xml )
echo "• Determining Package ID for "${newPackageName}" ..."
newPackageNameScrubbed=$( echo ${newPackageName} | sed 's| |%20|g' )
newPackageID=$( /usr/bin/curl -H "Accept: text/xml" -sfku "${apiUser}:${apiPassword}" "${apiURL}/JSSResource/packages/name/${newPackageNameScrubbed}" | xmllint --format - | awk -F'>|<' '/<id>/{print $3}')
echo "• Package "${newPackageName}" has an ID of: ${newPackageID} ..."
echo "• Updating Package ID from "${currentPackageID}" to "${newPackageID}" ..."
/usr/bin/sed -i.bak2 "s|<package><id>${currentPackageID}|<package><id>${newPackageID}|" ${updatesDirectory}/policy-${policyID}.xml
echo "• Done."
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Prompt Upload New Policy
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function promptUploadNewPolicy() {
printf "
-------------------------------------------------------------------------------------------------------
"
printf "
###
"
echo "# Step 6 of 6: Upload New Policy"
printf "###
"
printf "• New Policy Name: ${newpolicyName}
"
# Prompt user for permission to proceed
read -n 1 -r -p "Would you like to upload this policy? [y]es or [n]o: `echo $'
> '`" uploadChoice
ScriptLog "Would you like to upload this policy?: ${uploadChoice}"
case "${uploadChoice}" in
y|Y )
uploadNewPolicy
;;
n|N )
ScriptLog "Upload canceled; exiting."
printf "
Upload canceled; exiting.
"
exit 0
;;
*)
ScriptLog "ERROR: Did not recognize response: $choice; exiting."
printf "
ERROR: Did not recognize response: $choice; exiting."
exit 1
;;
esac
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Upload New Policy
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function uploadNewPolicy() {
ScriptLog "Uploading ${newpolicyName} ..."
printf "
• Uploading "${newpolicyName}" ...
"
if [[ ${debug} == "true" ]]; then
/usr/bin/curl -u "$apiUser":"$apiPassword" $apiURL/JSSResource/policies/id/${policyID} -H "Content-Type: application/xml" -X PUT -T ${updatesDirectory}/policy-${policyID}.xml
else
/usr/bin/curl -s -u "$apiUser":"$apiPassword" $apiURL/JSSResource/policies/id/${policyID} -H "Content-Type: application/xml" -X PUT -T ${updatesDirectory}/policy-${policyID}.xml
fi
ScriptLog "Uploaded ${newpolicyName} ..."
printf "• Uploaded "${newpolicyName}" ...
"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# View New Policy
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function viewNewPolicy() {
printf "
-------------------------------------------------------------------------------------------------------
"
printf "
###
"
echo "# Complete: View New Policy"
printf "###
"
ScriptLog "Launching browser to view "${newpolicyName}" policy ..."
printf "
• Launching browser to view "${newpolicyName}" policy ...
"
/usr/bin/open $apiURL/policies.html?id=${policyID}
printf "• Policy ID "${policyID}" has been updated to "${newpolicyName}."
To revert Policy ID "${policyID}" to "${policyName}," use the following Terminal command:
"
if [[ ${debug} == "true" ]]; then
echo "/usr/bin/curl -k -u ${apiUser}:${apiPassword} ${apiURL}/JSSResource/policies/id/${policyID} -H "Content-Type: application/xml" -X PUT -T ${backupDirectory}/policy-${policyID}.xml ; /usr/bin/open $apiURL/policies.html?id=${policyID}"
else
echo "/usr/bin/curl -k -u ${apiUser}:API_PASSWORD_GOES_HERE ${apiURL}/JSSResource/policies/id/${policyID} -H "Content-Type: application/xml" -X PUT -T ${backupDirectory}/policy-${policyID}.xml"
fi
printf "
***************************************** Policy Updated *****************************************
"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Prompt to Continue
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function promptToContinue(){
unset choice
# Prompt user for permission to proceed
read -n 1 -r -p "Would you like to update this policy? [y]es or [n]o: `echo $'
> '`" choice
ScriptLog "Would you like to update this policy?: ${choice}"
case "${choice}" in
y|Y )
ScriptLog "Updating policy ..."
downloadBackupXML # Download and backup the XML
promptNewVersion # Prompt the user for the new version
promptUploadNewPolicy # Prompt to upload the new policy using the supplied API password
;;
n|N )
ScriptLog "Prompting user to select a different policy ..."
/usr/bin/clear
selectPolicy
;;
*)
ScriptLog "ERROR: Did not recognize response: $choice; exiting."
printf "
ERROR: Did not recognize response: $choice; exiting."
exit 1
;;
esac
}
####################################################################################################
#
# Main Program
#
####################################################################################################
# Clear the user's Terminal session
/usr/bin/clear
createWorkingDirectory
echo "#####################################"
echo "# Jamf Pro Policy Editor Lite, v1.0 #"
echo "#####################################"
echo " "
echo "This script updates a selected policy's version number. For example, the policy for
"Adobe Prelude CC 2018 (7.1.1)" would be updated to: "Adobe Prelude CC 2018 (7.1.2).""
if [[ ${debug} == "true" ]]; then
printf "
###
# DEBUG MODE ENABLED
###
"
ScriptLog "DEBUG MODE ENABLED"
/usr/bin/open "${logFile}"
/usr/bin/osascript -e 'tell application "Console" to activate'
fi
apiConnectionSettings
selectPolicy
viewNewPolicy
exit 0
Posted on 07-24-2018 08:58 PM
Jamf Pro Policy Viewer.sh is a slimmed-down version which launches a browser to view the selected policy, bypassing the slow-as-molasses ../policy.html page.
Posted on 10-21-2019 10:03 AM
Here's a link to the presentation given at the October 2019 U of U MacAdmins meeting.
Posted on 08-01-2020 03:32 PM
Posted on 02-05-2021 01:50 PM
Version 1.4.4 is now available on GitHub
Inspired by @grahamrpugh's erase-install, Jamf Pro Policy Editor Lite, version 1.4.4, now includes the following flags:
bash ./policy-editor-lite.bash --help
Jamf Pro Policy Editor Lite, 1.4.4
by Dan K. Snelson (@dan-snelson)
Usage:
bash ./policy-editor-lite.bash [--filter] [--auto] [--version] [--debug]
[no flags] Displays all polcies
If API variables are left blank, you will be prompted to interactively enter.
If you have multiple lanes, fill-in variables in the "laneSelection" function.
--filter ... Filters policy names
--auto Auto-answers "yes" to prompt Nos. 2, 5 and 6
--version Specifies the new version number
--debug Enables debug mode
--help Displays this message and exits
For example, the following command will filter policies names containing foundry
, auto-answer Y
to prompt numbers 2, 5 and 6, and pre-populate 7.2.0
for the version number for prompt number 4.
bash ./policy-editor-lite.bash --filter foundry --auto --version 7.2.0