If you need to redeploy the Jamf management framework to client computers, the official method is to write or use a script that calls the Jamf API (see Redeploying the Jamf Management Framework Using the Jamf Pro API). There are two downsides to this:
- You have to write, find, or adapt a script to call the Jamf API.
- Redeploying the Jamf management framework like this also re-runs all policies like a new enrollment.
I’ve found that creating a Jamf policy to retrieve the Jamf binary, create a client configuration file, and run the “jamf enroll -prompt” command has several benefits:
- A policy can be scoped and re-scoped easily (instead of using a script to parse API query results).
- Previously executed policies do not re-run.
- Some computers may be too broken to retrieve the pending management command created by the API (the command just sits in the pending queue). This policy will work even on those broken computers (so long as they can still run policies provided by Jamf).
- You can also run this script from the command line (using sudo to execute the script as root).
Jamf Policy
- Trigger: Login, Recurring Check-in
- Execution Frequency: Once per computer
- Script: reinstall-jamf-management-framework.sh
Jamf Policy Log Details
The policy log includes information about the computer (useful for context or reference) and the output of the “jamf enroll -prompt” command:
Script result:
Mon Jan 1 12:00:00 PST 2026
mount_point = /
computer_name = ********
user_name = ********
hw_model_name = ********
hw_model_id = ********
hw_model_number = ********
hw_serial_no = ********
hw_ip_address = ********
hw_hostname = ********
MacOS version:
ProductName: macOS
ProductVersion: ********
BuildVersion: ********
Creating configuration file for https://********/...
The SSL Certificate for https://********/ must be trusted for the jamf binary to connect to it.
spawn /tmp/********
Enroll Begin
JSS Username:enroll
JSS Password:
The device certificate was created successfully.
This computer was successfully enrolled to the JSS with the following device certificate: "********"
Retrieving inventory preferences from https://********/...
Finding extension attributes...
Locating accounts...
Locating hard drive information...
Locating applications...
Searching path: /System/Applications
Locating package receipts...
Locating software updates...
Locating printers...
Gathering application usage information from the JamfDaemon...
Searching path: /Applications
2026-01-01 12:00:00.000 softwareupdate[********:********] XType: Using static font registry.
Locating hardware information (macOS ********)...
Submitting data to https://********/...
<computer_id>********</computer_id>
The management framework will be enforced as soon as all policies are done executing.
Upgrading jamfHelper.app...
Upgrading JAMF notification service...
Upgrading Jamf.app...
The management framework will be enforced as soon as all policies are done executing.
Checking in the background for policies that use the Enrollment Complete trigger
Enroll return code: 0
Enroll End
Jamf Policy Script
This policy script requires a Jamf account (username and password) to enroll the computer.
The default Jamf Settings > System > User accounts and groups users list includes an “enroll” account with “Enrollment Only” privileges. The default “Enrollment Only” privileges are insufficient, so you will have to change the Privilege Set to “Custom” and also enable the Jamf Pro Server Objects > Computers: Update privilege.
After downloading the script, make sure you update these values:
jss_username='enroll' # Modify this (to use a different account name).
jss_password='{enroll-account-password}' # Modify this.
jamf_url='https://{jamf-server-url}/' # Modify this.
You can download the reinstall-jamf-management-framework.sh script here.
Leave a comment or suggestion below.
#!/bin/bash
#
# reinstall-jamf-management-framework.sh
#
# Authored by Jean-Sebastien Morisset <https://surniaulula.com/>.
#
# Copyright 2025-2026 Jean-Sebastien Morisset <https://surniaulula.com/> and
# School District 46 <https://sd46.bc.ca/>.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# See <https://www.gnu.org/licenses/> for the GNU General Public License.
#
function hw_model_name {
/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/sed -n 's/^ *Model Name: //p'
}
function hw_model_id {
/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/sed -n 's/^ *Model Identifier: //p'
}
function hw_model_number {
/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/sed -n 's/^ *Model Number: //p'
}
function hw_serial_number {
/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/sed -n 's/^ *Serial Number (system): //p'
}
function hw_ip_address {
for i in `/sbin/ifconfig -l -u inet` # Only IPv4 interfaces that are UP.
do
/usr/sbin/ipconfig getifaddr "$i" && break
done
}
mount_point="$1"
computer_name="$2"
user_name="$3"
hw_model_name="`hw_model_name`"
hw_model_id="`hw_model_id`"
hw_model_number="`hw_model_number`"
hw_serial_no="`hw_serial_number`"
hw_ip_address="`hw_ip_address`"
hw_hostname="`hostname -s`"
#
# PLEASE NOTE:
#
# The enroll account must be assigned custom privileges based on the
# "Enrollment Only" privilege set: choose privilege set "Enrollment Only", then
# choose privilege set "Custom", then under the custom privileges tab, add the
# Jamf Pro Server Objects > Computers: Update privilege.
#
jss_username='enroll' # Modify this (to use a different account name).
jss_password='{enroll-account-password}' # Modify this.
jamf_url='https://{jamf-server-url}/' # Modify this.
#
# Include basic information about the computer for the Jamf policy log.
#
echo ""
echo ""
/bin/date
echo ""
echo "mount_point = $mount_point"
echo "computer_name = $computer_name"
echo "user_name = $user_name"
echo "hw_model_name = $hw_model_name"
echo "hw_model_id = $hw_model_id"
echo "hw_model_number = $hw_model_number"
echo "hw_serial_no = $hw_serial_no"
echo "hw_ip_address = $hw_ip_address"
echo "hw_hostname = $hw_hostname"
echo ""
echo "MacOS version:"
echo ""
/usr/bin/sw_vers
echo ""
#
# Down to business: retrieve the latest jamf binary, copy it to
# /usr/local/jamf/bin, link it in /usr/local/bin, recreate the Jamf config,
# and then reenroll the computer.
#
/usr/bin/curl -ks "${jamf_url}bin/jamf" -o /tmp/jamf
/bin/mkdir -p /usr/local/jamf/bin /usr/local/bin
/bin/mv /tmp/jamf /usr/local/jamf/bin
/bin/chmod +x /usr/local/jamf/bin/jamf
/bin/ln -fs /usr/local/jamf/bin/jamf /usr/local/bin/jamf
/bin/rm -f /usr/local/jamf/bin/jamfAAD
/usr/local/jamf/bin/jamf createConf -k -url "${jamf_url}"
/bin/cat <<EOF >/tmp/enroll.$$
echo "Enroll Begin"
/usr/local/jamf/bin/jamf enroll -prompt
echo "Enroll End"
EOF
/bin/chmod 700 /tmp/enroll.$$
/usr/bin/expect 2>/dev/null <<EOF
set timeout -1
spawn /tmp/enroll.$$
expect "JSS Username:"
send "$jss_username\n"
expect "JSS Password:"
send "$jss_password\n"
expect "Enroll End"
exit 0
EOF