Posted on 08-26-2024 07:33 AM
I have always used JSSConduit to purge old classes to learn JAMF no longer accepts basic authentication. Support sends me the below script to run without explanation. I am a network guy who also manages Jamf, and par for the course Jamf Support falls short. As I stated, I am not a JAMF scripting expert so I am only looking for a detailed procedure on how to delete the classes which typically took me 5 minutes has now lingered for 3 weeks. Any expert advice / instructions would be appreciated. Script below:
#!/bin/bash #################################################################################################### # # THIS SCRIPT IS NOT AN OFFICIAL PRODUCT OF JAMF # AS SUCH IT IS PROVIDED WITHOUT WARRANTY OR SUPPORT # # BY USING THIS SCRIPT, YOU AGREE THAT JAMF # IS UNDER NO OBLIGATION TO SUPPORT, DEBUG, OR OTHERWISE # MAINTAIN THIS SCRIPT # #################################################################################################### # # DESCRIPTION # This is a self destruct script that will delete all classes in Jamf Pro. # Requires a user that has READ and DELETE privys for Classes. # The noRefesh version goes through 100 at a time before forcing a class refresh with Jamf. # This allows the script to run much faster than past scripts. # Jul 22, 2024 - version 3.0 # updated to accomidate a change that was made to curl # added an extra step at the end to create a class and delete it. This forces the class refresh. # #################################################################################################### # Variable declarations bearerToken="" tokenExpirationEpoch="0" count=0 re='^[0-9]+$' # 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="" # Function to gather and format bearer token getBearerToken() { response=$(/usr/bin/curl -k -k -s -u "$jamfpro_user":"$jamfpro_password" "$jamfpro_url"/api/v1/auth/token -X POST) bearerToken=$(echo "$response" | plutil -extract token raw -) tokenExpiration=$(echo "$response" | plutil -extract expires raw - | awk -F . '{print $1}') tokenExpirationEpoch=$(date -j -f "%Y-%m-%dT%T" "$tokenExpiration" +"%s") echo "New bearer token generated." echo "Token valid until the following date/time UTC: " "$tokenExpiration" } # Function to check token expiration checkTokenExpiration() { nowEpochUTC=$(date -j -f "%Y-%m-%dT%T" "$(date -u +"%Y-%m-%dT%T")" +"%s") if [[ tokenExpirationEpoch -lt nowEpochUTC ]] then echo "No valid token available, getting new token" getBearerToken fi } # Funtion to invalidate token invalidateToken() { responseCode=$(/usr/bin/curl -k -w "%{http_code}" -H "Authorization: Bearer ${bearerToken}" $jamfpro_url/api/v1/auth/invalidate-token -X POST -s -o /dev/null) if [[ ${responseCode} == 204 ]] then echo "Bearer token successfully invalidated" bearerToken="" tokenExpirationEpoch="0" elif [[ ${responseCode} == 401 ]] then echo "Bearer token already invalid" else echo "An unknown error occurred invalidating the bearer token" fi } # Dispaly warning and confrim user would like to continue echo "#####################" echo "###!!! WARNING !!!###" echo "#####################" echo "This is a self destruct script that will delete all classes." echo "There is no undo button." while true; do read -p "Are you sure you want to continue? [ y | n ] " answer case $answer in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer y | n";; esac done # If the Jamf Pro URL, the account username and/or the account password have not been provided, # the below will prompt the user to enter the necessary information. 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 # Remove the trailing slash from the Jamf Pro URL if needed. jamfpro_url=${jamfpro_url%%/} echo echo "Credentials received" echo # Genrating bearer token echo "Generating bearer token for server authentication..." getBearerToken echo echo "Deleting all classes now!" # create array with all class IDs classID=$(/usr/bin/curl -k --silent --header "Authorization: Bearer ${bearerToken}" --header "accept: text/xml" ${jamfpro_url}/JSSResource/classes | xmllint --format - | awk -F '[<>]' '//{print $3}') # starting loop to delete all classes for class in $classID;do # sleep to prevent server overload (commented out for testing) # sleep 1 # log delete attmpt and report to user echo echo "$(date) - Deleting class ID $class" >> /tmp/classes_deleted.txt echo "Deleting class ID $class" # checking bearer token expiration # delete class via API if [[ "$count" -lt "100" ]]; then checkTokenExpiration /usr/bin/curl -k --silent --header "Authorization: Bearer ${bearerToken}" ${jamfpro_url}/JSSResource/classes/id/$class/action/deleteNoRefresh --request DELETE ((count++)) echo else checkTokenExpiration /usr/bin/curl -k --silent --header "Authorization: Bearer ${bearerToken}" ${jamfpro_url}/JSSResource/classes/id/$class --request DELETE count=0 echo fi done #create class for refresh XML='Temp1234Temp' echo echo "Creating Temp1234 class to force the class refresh in Jamf Pro" echo checkTokenExpiration newClass=$(curl --silent --header "Authorization: Bearer ${bearerToken}" --header "Content-type: text/xml" $jamfpro_url/JSSResource/classes/id/1 -X POST -d "$XML" ) newClassID=$(echo "$newClass" | xmllint --format - | awk -F '[<>]' '//{print $3}') echo echo "30 second pause to confirm tenant sync" echo sleep 30 # delete new class via API echo echo "Deleting Temp1234 class." echo checkTokenExpiration /usr/bin/curl --silent --header "Authorization: Bearer ${bearerToken}" ${jamfpro_url}/JSSResource/classes/id/$newClassID --request DELETE echo echo "All classes have been deleted." echo # Invalidate bearer token (keep this at the end of the script) echo "Invalidating bearer token..." invalidateToken exit
Posted on 08-26-2024 07:58 AM
Was this script sent to you by email or did you receive a link? Can you post the link?
It would take a few minutes to convert it to use tokens, but if it came directly from Jamf Support then they need to address this, and I can reach out to them.
Posted on 08-28-2024 12:40 PM
Have you considered using Prune?
Posted on 08-28-2024 12:43 PM
Posted on 08-28-2024 12:50 PM
Awhile back I was given these directions from jamf - but since then have used Prune successfully
We can try using the API to do this. First we will want to find the range of class IDs. If you would like to get rid of all of them, then you can start with 1 for the lower range.
curl -ksu INSERT_USERNAME -H "content-type: text/xml" INSERT_JAMF_URL/JSSResource/classes/id/[1-100] -X DELETE