Skip to main content
Question

Solve Jamf agent and MDM problems automatically?

  • December 12, 2025
  • 3 replies
  • 25 views

howie_isaacks
Forum|alt.badge.img+23

Like a lot of other Jamf admins I see a small number of Macs that have stopped checking in and sending inventories. I see some that appear to be having problems with MDM. I am curious about what everyone else is doing to solve these issues. Since we also use some other management agents I can see that a lot of the Macs that are having Jamf agent issues are working with the other management agents. They appear to be in use. I wrote a script that leverages the Jamf Management Framework redeployment API command. I was able to deploy it through Tanium to some systems that had stopped checking in and sending inventories. This has worked on some but not on others. For the systems having MDM issues, this may not work since the Jamf Management framework redeployment using the API needs MDM functionality to work. Here’s the current version of the script that I created.

#!/bin/zsh --no-rcs

:<<ABOUT_THIS_SCRIPT
---------------------------------------------------------------------------------------------------
Uses the Jamf Pro API to run the Jamf management framework command to re-enroll a Mac. Before the
command is run the computer is temporarily added to a static group that is excluded from running
enrollment policies that will be visible to the user.

USAGE:
1 - Add your Jamf Pro server URL, API client ID and secret to the variables for Jamf Pro API
login.

2 - Create a static group and exclude it from enrollment policies that would be visible to users.
Add the group ID to the variable "group_id". Exclude the group from enrollment policies. Comment
out the section that excludes the Mac from enrollment policies if this is not needed.

EXPERIMENTAL: Jamf Pro parameter 7 can be used to trigger the Jamf "removeFramework" command just
before running the Jamf management framework API command. Specify "yes" in parameter 7. If this script
is used with another management system, change the "remove_framework" variable to ="$1" to be able to
run the script with an argument to activate the removal of the Jamf framework.

VERSION 1

12/11/2025 | Howie Canterbury
---------------------------------------------------------------------------------------------------
ABOUT_THIS_SCRIPT

###########################
# OPTIONS #
###########################

remove_framework="$7"

###############################################################################
# JAMF PRO API LOGIN #
# Parameter 4: API client ID #
# Parameter 5: API client secret #
# Parameter 6: Enter "yes" to validate API login #
###############################################################################

# Jamf Pro API login
url="YOUR_SERVER"
client_id="$4"
client_secret="$5"
verify="$6"

# Jamf API authentication function
jamfAPI_auth() {
response=$(curl --silent --location --request POST "${url}/api/oauth/token" \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=${client_id}" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_secret=${client_secret}")
token=$(echo "$response" | plutil -extract access_token raw -)
token_expires_in=$(echo "$response" | plutil -extract expires_in raw -)
token_expiration_epoch=$(($current_epoch + $token_expires_in - 1))
}

# Start authenticated API session
jamfAPI_auth

###############################################################################
# VALIDATE API LOGIN #
# The token and expiration time will be echoed into the script output #
# to verify that the API login credentials provided are working. #
###############################################################################

if [[ "$verify" == "yes" ]]; then
echo "API token: ${token}"
echo "Token expires in: ${token_expires_in} seconds"
fi

#####################################
# COMPUTER INFORMATION #
#####################################

# Computer serial number
serial=$(system_profiler SPHardwareDataType | grep Serial | /usr/bin/awk '{print $4}')
echo "Computer serial number is ${serial}"

# Jamf ID
jss_ID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${token}" ${url}/JSSResource/computers/serialnumber/"$serial" | xmllint --xpath '/computer/general/id/text()' -)
echo "Computer JSS ID is ${jss_ID}"

###################################################################
# ADD COMPUTER TO ENROLLMENT POLICY EXCLUSION GROUP #
###################################################################
group_id=""

# Adding the computer to the enrollment policy exclusion group will prevent the ZTP policy from running after enrollment.
echo "Excluding ${serial} from enrollment policies..."
curl -X PUT "${url}/JSSResource/computergroups/id/${group_id}" -H "Authorization: Bearer ${token}" -H "Content-Type: application/xml" -d "<computer_group><computer_additions><computer><id>$jss_ID</id></computer></computer_additions></computer_group>"

###################################################################
# RUN JAMF MANAGEMENT FRAMEWORK COMMAND TO ENROLL THE MAC #
###################################################################

# Remove Jamf framework
if [[ "$remove_framework" == "yes" ]]; then
echo "Removing Jamf framework"
/usr/local/jamf/bin/jamf removeFramework
fi

# MDM action to install and run a Jamf quick add package to reinstall the Jamf management framework and trigger a re-enrolllment.
echo "Running Jamf management framework command to trigger re-enroll"
curl -X 'POST' \
"${url}/api/v1/jamf-management-framework/redeploy/${jss_ID}" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" \
-d ''

 

3 replies

Chubs
Forum|alt.badge.img+23
  • Jamf Heroes
  • December 12, 2025

I wrote a launchdaemon that did something similar in the past when I had users remove the framework so the device would auto-reenroll (pre-MDM).

A lot of what you’ve specified above can be automated using a CI/CD platform (like GitHub or power automate with web hooks) and smart groups in JAMF.  This would be an awesome automation to add to Jamf Routines though!



 


mattjerome
Forum|alt.badge.img+9
  • Jamf Heroes
  • December 12, 2025

Check out this JNUC 2024 presentation 

 


howie_isaacks
Forum|alt.badge.img+23
  • Author
  • Esteemed Contributor
  • December 12, 2025

I have been thinking of deploying a launch daemon that would run a script to do some checks on Jamf agent and MDM health. Once I have these created I can proactively deploy them to help keep the Jamf agent and MDM healthy. It’s a shame that Jamf does not provide this ability as a built-in feature.