Lesson 1 Links, Notes, and Files from Instructor:
Jamf 300 Course
Jamf Pro Documentation
- https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/LDAP_Directory_Service_Integration.html
- https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Mobile_Device_Inventory_Collection_Settings.html
- https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Computer_Inventory_Collection_Settings.html
- https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Mobile_Device_Extension_Attributes.html
- https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Computer_Extension_Attributes.html
Jamf Technical Articles
LDAP
Navigational aid
- Settings > System > LDAP servers
- Settings > Computer management > Inventory collection
- Settings > Device management > Inventory collection
1: Setting up LDAP to Look in the Faculty OU
Test Users:
bross
jgreen
Test Groups:
Jamf Pro Auditors
Support
Lesson 2 Links, Notes, and Files from Instructor:
Jamf Pro Documentation
-
https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/About_Distribution_Points.html
-
https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Cloud_Distribution_Point.html
-
https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Jamf_Pro_Health_Check_Page.html
-
https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Network_Segments.html
-
https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Sites.html
Jamf Technical Articles
Self Service+ for macOS Deployment Guide
Apple
Navigational aid
- Settings > Server > Cloud distribution point
- Settings > Server > File share distribution points
- Settings > Network > Sites
- Settings > Network > Network segments
- Settings > Self Service > iOS Settings > Self Service > macOS
- https://JAMF_PRO_URL/healthCheck.html
Examples
- curl
-
Flag Explanation –max-time or -m Maximum time, in seconds, for the operation to complete –silent or -s Do not show a progress meter or error messages Display the Jamf Pro health status
curl -m 10 -s https://JAMF_PRO_URL/healthCheck.html
Files:
1. printNetworkSegment.zsh
#!/bin/zsh –no-rcs
interface=$(route get www.apple.com | awk ‘/interface/{print $NF}’)
network=$(ipconfig getifaddr $interface | awk -F. ‘{print $1″.”$2″.”$3}’)
echo “Starting IP: $network.1”
echo “Ending IP: $network.254”
Lesson 3 Links, Notes, and Files from Instructor:
Lesson 3: API Roles and Clients
Last updated February 19, 2026
Objective
Integrate tools into Jamf Pro using API Roles and Clients.
Discussion
- Jamf Pro API
- API Authentication
- API Roles and Clients
- Bearer Token
- Integrating Tools
- API Authentication
- Transfer data from or to a server, curl
Resources
Jamf Pro Documentation
Jamf Developer Portal
Jamf Sync
Navigational aid
Settings > System > API Roles and Clients
Examples
- curl
-
Obtain and save a bearer token as a variable
baseURL="JAMF_PRO_URL" client_id="CLIENT_ID" client_secret="CLIENT_SECRET" access_token=$(curl --silent --location \ --request POST "https://$baseURL/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" | plutil -extract "access_token" raw -) # Check that bearer token is saved successfully: curl --silent --header "Authorization: Bearer $access_token" https://$baseURL/api/v2/computers-inventory
Examples from Instructor:
1. printNetworkSegment.zsh
#!/bin/zsh –no-rcs
#
baseURL=”n300-1a.pro.jamf.training”
client_id=”4fe4b78d-a0f6-47b3-a3ea-b50dcb19c0e9″
client_secret=”8tsr4wzbStk17H-Akg4febxrl6sxA9HNdmpfFXpec12Hbm43Fvza84ZnDfKude96″
access_token=$(curl –silent –location \
–request POST “https://$baseURL/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” | plutil -extract “access_token” raw -)
# Check that bearer token is saved successfully:
curl –silent –header “Authorization: Bearer $access_token” https://$baseURL/api/v2/computers-inventory | jq .
Lesson 4 Links, Notes, and Files from Instructor:
Lesson 4: Enrollment
Last updated February 19, 2026
Objective
Enroll computers and mobile devices with an associated LDAP user.
Discussion
- Device Enrollment
- Supervision
- User-Initiated Enrollment
- LDAP
- Enrollment Invitations
- Enrollment Profile
- Local Administrator Password Solution (LAPS)
- Mobile Device Management (MDM)
- Jamf Management Framework (JMF)
- API
- Enablement
- View Configuration
- Manage Local Administrator Accounts
- View accounts and passwords
- Manage (Accounts)
- Login and Background Items (macOS 13 or later)
Resources
Jamf 300 Course
Jamf Pro Documentation
-
https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Enrollment_into_Jamf_MDM.html
-
https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/Enrollment_Profiles.html
Jamf Technical Articles
Jamf
Apple Platform Deployment
Navigational aid
- Settings > Global > User-initiated enrollment
- Settings > Computer Management > Security
- Devices > Enrollment Profiles
- Computers > Search Inventory > History > Managed Local Administrator Account History
- https://JAMF_PRO_URL/api/doc
Examples
- Jamf Pro API
-
https://server.pro.jamf.training/api/doc
Lesson 5 Links, Notes, and Files from Instructor:
Lesson 5: Framework
Last updated February 19, 2026
Objective
Configure the management framework and create scheduled tasks.
Discussion
- Login Events
- Check-in
- Daemons
- Agents
- A document of XML configuration details, man launchd.plist
- Access XML property lists, defaults
- Daemon and agent management tool,
launchctl- Bootout an agent or daemon from memory,
bootout - Bootstrap an agent or daemon into memory,
bootstrap
- Bootout an agent or daemon from memory,
- User identity utility,
id
Important:
In Jamf training courses, the term “print” is used to represent the action of displaying the output of a command in a script or Terminal window.
Resources
Jamf Pro Documentation
Daemons and Services Programming Guide
Terminal User Guide
Navigational aid
- Jamf Pro – Settings > Computer management > Check-in
- macOS
- /System/Library/LaunchDaemons/
- /Library/LaunchDaemons/
- /System/Library/LaunchAgents/
- /Library/LaunchAgents/
- ~/Library/LaunchAgents/
Examples
- defaults
-
Print a property list
defaults read /PATH/TO/FILEPrint a specific property
defaults read /PATH/TO/FILE SOME_KEYSet or modify a property
defaults write /PATH/TO/FILE SOME_KEY -boolean SOME_BOOLEANdefaults write /PATH/TO/FILE SOME_KEY -integer SOME_INTEGERdefaults write /PATH/TO/FILE SOME_KEY -string SOME_X_VALUERemove a property
defaults delete /PATH/TO/FILE SOME_KEY - id
-
List the current user’s unique ID
id -uList the unique ID for a user
id -u USER - launchctl
-
Bootout a user agent or daemon from memory
launchctl bootout gui/<USER_UID> /PATH/TO/FILEBootstrap a user agent or daemon into memory
launchctl bootstrap gui/<USER_UID> /PATH/TO/FILEBootout a system agent or daemon from memory
launchctl bootout system /PATH/TO/FILEBootstrap a system agent or daemon into memory
launchctl bootstrap system /PATH/TO/FILEStart an agent or daemon with the label identifier
launchctl start LABEL_IDENTIFIERList running agents or daemons and search for a specified service
launchctl list | grep SERVICE_NAMECheck the formatting on an agent or daemon
plutil -lint /PATH/TO/FILESet ownership and permission for a system agent or daemon
chown root:wheel /PATH/TO/FILE chmod 644 /PATH/TO/FILEBootout the Dock agent for user with unique ID 502
launchctl bootout gui/502 /System/Library/LaunchAgents/com.apple.Dock.plistBootstrap the Dock agent for user with unique ID 502
launchctl bootstrap gui/502 /System/Library/LaunchAgents/com.apple.Dock.plistStart the Dock process
launchctl start com.apple.Dock.agentCompose a daemon using the jamf binary
jamf scheduledTask -command "/bin/zsh "'"/PATH/TO/FILE"'"" -name CUSTOM_NAME -runAtLoad true -minute '*/NUMBER_OF_MINUTES/'Print the current date to a file
date -u +%F\ %T >> /PATH/TO/FILEUpdate Jamf management framework
/usr/local/jamf/bin/jamf manageBootout a system agent or daemon with label
launchctl bootout system/LABEL_IDENTIFIER - Example agent and daemon
-
Agent to open the Jamf Learning Hub
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>CUSTOM_LABEL_HERE</string> <key>ProgramArguments</key> <array> <string>/usr/bin/open</string> <string>https://learn.jamf.com</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>Daemon to call a script on a timer
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>CUSTOM_LABEL_HERE</string> <key>ProgramArguments</key> <array> <string>/bin/zsh</string> <string>/PATH/TO/FILE</string> </array> <key>RunAtLoad</key> <true/> <key>StartInterval</key> <integer>NUMBER_OF_SECONDS</integer> </dict> </plist>
Examples from Instructor:
1. 01-manipulating-jobs.sh
#!/bin/zsh –no-rcs
# Manipulating LaunchD Tasks
# Shows agents and applications I have in my user context
launchctl list
# Shows all of the launch daemons
sudo launchctl list
# Shows all of the launch daemons, minus any that contain “com.apple”
sudo launchctl list | grep -v com.apple
# Show me the Dock job
launchctl list | grep Dock
# Print the Dock job
launchctl print gui/$(id -u)/com.apple.Dock.agent
# Boot-out/de-register/unload
launchctl bootout gui/$(id -u) /System/Library/LaunchAgents/com.apple.Dock.plist
# Register/load/bootstrap the Dock job back
launchctl bootstrap gui/$(id -u) /System/Library/LaunchAgents/com.apple.Dock.plist
# Tell launchd to actually *start* the ProgramArguments in the job description
launchctl kickstart -p gui/$(id -u)/com.apple.Dock.agent
2. make-agent-to-open-url.sh
#!/bin/zsh –no-rcs
# Whenever anyone logs in, open a specific webpage
# Command the Launch Agent needs to run:
# open
# https://n300-1a.pro.jamf.training
# Label = com….
# ProgramArguments =
# – /usr/bin/open
# – $URL
# RunAtLoad = true
label=”com.demo.open.jamfproserver”
plistPath=”/Library/LaunchAgents/$label.plist”
URL=”https://n300-1a.pro.jamf.training”
#sudo launchctl bootout gui/$(id -u) “$plistPath”
sudo rm “$plistPath”
sudo launchctl bootout gui/$(id -u)/$label
sudo defaults write “$plistPath” Label -string “$label”
sudo defaults write “$plistPath” ProgramArguments -array -string “/usr/bin/open” -string “$URL”
sudo defaults write “$plistPath” RunAtLoad -boolean TRUE
#ls -la $plistPath
sudo chmod 644 “$plistPath”
sudo launchctl bootstrap gui/$(id -u) “$plistPath”
3. 03-fast-recon-8hrs.sh
#!/bin/zsh –no-rcs
# Run Inventory Update at Boot and every 8 hours
# Command to run:
# jamf recon
# Label = $label
# ProgramArguments =
# – path to jamf
# – recon
# RunAtLoad = true
# StartInterval = (int) 60*60*8 = 28,800 seconds
label=”com.demo.fastrecon.8hrs”
plistPath=”/Library/LaunchDaemons/$label.plist”
sudo rm “$plistPath”
sudo launchctl bootout system/$label
sudo defaults write “$plistPath” Label -string “$label”
sudo defaults write “$plistPath” ProgramArguments -array -string “/usr/local/bin/jamf” -string “recon”
sudo defaults write “$plistPath” RunAtLoad -boolean TRUE
sudo defaults write “$plistPath” StartInterval -integer 28800
#ls -la $plistPath
sudo chmod 644 “$plistPath”
sudo launchctl bootstrap system “$plistPath”
4. 04-fast-recon-logger.sh
#!/bin/zsh –no-rcs
#
/usr/local/bin/jamf recon
echo “Ran fast recon at $(date)” >> /var/log/recon.log
5. 05-fast-recon-with-script.sh
#!/bin/zsh –no-rcs
# Run Inventory Update at Boot and every 8 hours
# Command to run:
# jamf recon, plus some logging
# Label = $label
# ProgramArguments =
# – path to zsh
# – path to script
# RunAtLoad = true
# StartInterval = (int) 60*60*8 = 28,800 seconds
label=”com.demo.fastrecon.8hrs”
plistPath=”/Library/LaunchDaemons/$label.plist”
# Script was just manually placed here in Finder!
scriptPath=”/Library/Scripts/recon-logger.sh”
sudo rm “$plistPath”
sudo launchctl bootout system/$label
sudo defaults write “$plistPath” Label -string “$label”
sudo defaults write “$plistPath” ProgramArguments -array -string “/bin/zsh” -string “$scriptPath”
sudo defaults write “$plistPath” RunAtLoad -boolean TRUE
sudo defaults write “$plistPath” StartInterval -integer 28800
#ls -la $plistPath
sudo chmod 644 “$plistPath”
sudo chmod 744 “$scriptPath”
sudo chown root:wheel “$scriptPath”
sudo launchctl bootstrap system “$plistPath”
Completed Tasks
Task1.sh
#!/bin/zsh –no-rcs
# Task 01 – Compose an agent with the label com.Lesson5Task1.agent to open the Jamf Learning Hub: https://learn.jamf.com.
# Command the Launch Agent needs to run:
# open
# https://learn.jamf.com
# Label = com….
# ProgramArguments =
# – /usr/bin/open
# – $URL
# RunAtLoad = true
label=”com.Lesson5Task1.agent”
plistPath=”/Library/LaunchAgents/$label.plist”
URL=”https://learn.jamf.com”
sudo rm “$plistPath”
sudo defaults write “$plistPath” Label -string “$label”
sudo defaults write “$plistPath” ProgramArguments -array -string “/usr/bin/open” -string “$URL”
sudo defaults write “$plistPath” RunAtLoad -boolean TRUE
#ls -la $plistPath
sudo chmod 644 “$plistPath”
Task2.sh
#!/bin/zsh –no-rcs
# Task 02 – Compose a script to update the management framework and print the current time to the file /Users/Shared/managementTime.txt.
# Manually place this script somewhere on your test Mac’s filesystem (/Library/Scripts, e.g.) so your daemon can run it
/usr/local/bin/jamf manage
echo “Updated management framework at $(date)” >> /Users/Shared/managementTime.txt
Task3.sh
#!/bin/zsh –no-rcs
# Task 03 – Compose a daemon with the label com.Lesson5Task3.daemon to execute the script from Task 2 with a timed interval of 20 minutes.
# Command to run:
# a script that runs jamf manage, plus some logging
# Label = $label
# ProgramArguments =
# – path to zsh
# – path to script
# RunAtLoad = true
# StartInterval = (int) 60*20 = 1200 seconds
label=”com.Lesson5Task3.daemon”
plistPath=”/Library/LaunchDaemons/$label.plist”
# Script was just manually placed here in Finder!
scriptPath=”/Library/Scripts/Task-02.sh”
sudo rm “$plistPath”
sudo defaults write “$plistPath” Label -string “$label”
sudo defaults write “$plistPath” ProgramArguments -array -string “/bin/zsh” -string “$scriptPath”
#Technically we don’t really need this to happen right at boot, so this can be ommitted.
#sudo defaults write “$plistPath” RunAtLoad -boolean TRUE
sudo defaults write “$plistPath” StartInterval -integer 1200
#ls -la $plistPath
sudo chmod 644 “$plistPath”
sudo chmod 744 “$scriptPath”
sudo chown root:wheel “$scriptPath”
Task4.sh
#!/bin/zsh –no-rcs
# Task 04 – Bootstrap the agent and daemon from Tasks 1 and 3
# Bootstrap Agent
label=”com.Lesson5Task1.agent”
plistPath=”/Library/LaunchAgents/$label.plist”
launchctl bootout gui/$(id -u)/$label
launchctl bootstrap gui/$(id -u) “$plistPath”
# Bootstrap Daemon
label=”com.Lesson5Task3.daemon”
plistPath=”/Library/LaunchDaemons/$label.plist”
sudo launchctl bootout system/$label
sudo launchctl bootstrap system “$plistPath”
Lesson 6 Links, Notes, and Files from Instructor:
Lesson 6: User Management
Last updated February 19, 2026
Objective
Configure settings and preferences for users.
Discussion
- Mobile device configuration profiles
- Notifications
- Computer configuration profiles
- Computer-level configuration profiles
- Notifications
- Application & Custom Settings
- defaults
- plutil
- Property list utility
- Custom Schemas
- Managed App Schema Builder
- User-level configuration profiles
- MDM capable user
- Computer-level configuration profiles
- Payload variables
Resources
Jamf Pro Documentation
Jamf
Apple Platform Deployment
Third-party GitHub repositories
JSONLint
Command manual pages
Navigational aid
- Jamf Pro
- Computers > Configuration Profiles
- Devices > Configuration Profiles
- macOS
- /Library/Preferences/
- ~/Library/Preferences/
- /Library/Managed Preferences/
Examples
- defaults
-
Print a property list
defaults read /PATH/TO/FILEPrint a specific property
defaults read /PATH/TO/FILE SOME_KEYSet or modify a property
defaults write /PATH/TO/FILE SOME_KEY -boolean BOOLEAN_VALUEdefaults write /PATH/TO/FILE SOME_KEY -integer CUSTOM_INTEGERdefaults write /PATH/TO/FILE SOME_KEY -string CUSTOM_VALUERemove a property
defaults delete /PATH/TO/FILE SOME_KEY - Safari
-
Enforce Safari Smart Search Field setting
defaults write ~/Desktop/com.apple.Safari ShowFullURLInSmartSearchField -boolean trueEnforce Safari window behavior
defaults write ~/Desktop/com.apple.Safari.plist NewWindowBehavior -integer 0Enforce Safari homepage behavior
defaults write ~/Desktop/com.apple.Safari.plist HomePage https://trainingcatalog.jamf.comSet Safari homepage
defaults write ~/Desktop/com.apple.Safari.SandboxBroker.plist Homepage https://trainingcatalog.jamf.com - Convert a binary encoded file to XML
-
plutil -convert xml1 /PATH/TO/FILE - Dock Custom Schema
-
Item Value Preference Domain com.apple.dockDomain Description Manage the dock location Key Description of Key Value Type orientationDock location String
Examples from Instructor:
1. find-key-name-from-log-stream.sh
#!/bin/zsh –no-rcs
# Pull Preference Key changes from the Unified Log Stream
# Will need “Enable Private Log Data” Profile manually installed from
# https://eclecticlight.co/2026/04/30/control-what-gets-written-to-the-log/
# to see key names in output
/usr/bin/log stream –info –debug –predicate ‘process==”cfprefsd” && eventMessage CONTAINS “wrote the key”‘
2. write-out-secure-kb-entry-plist.sh
#!/bin/zsh –no-rcs
# Write out Secure Keyboard Entry setting to the desktop
# Key: SecureKeyboardEntry
# Type: Boolean
# Value: TRUE
defaults write ~/Desktop/securekeyboardentry.plist SecureKeyboardEntry -boolean TRUE
# Convert to XML plist
plutil -convert xml1 ~/Desktop/securekeyboardentry.plist -o ~/Desktop/securekeyboardentry-xml.plist
3. com.apple.dock.json
“_appTitle”: “Dock”,
“_exported”: “MASB”,
“title”: “com.apple.dock”,
“description”: “”,
“properties”: {
“orientation”: {
“title”: “Dock Orientation”,
“description”: “orientation”,
“default”: “bottom”,
“property_order”: 5,
“type”: “string”,
“options”: {
“enum_titles”: [“Screen Left”, “Screen Bottom”, “Screen Right”],
“infoText”: “”
},
“enum”: [“left”, “bottom”, “right”]
}
}
}
4. com.apple.Safari.plist
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=”1.0″>
<dict>
<key>ShowFullURLInSmartSearchField</key>
<true/>
</dict>
</plist>
5. com.krill.CodeRunner.json
“_appTitle”: “CodeRunner”,
“_exported”: “MASB”,
“title”: “com.krill.CodeRunner”,
“description”: “”,
“properties”: {
“AskToSaveWhenQuitting”: {
“title”: “Ask To Save When Quitting”,
“description”: “AskToSaveWhenQuitting”,
“default”: false,
“property_order”: 5,
“type”: “boolean”,
“options”: {
“infoText”: “”
}
},
“DefaultTabModeWidth”: {
“title”: “Default Tab Width”,
“description”: “DefaultTabModeWidth”,
“property_order”: 10,
“type”: “integer”,
“options”: {
“enum_titles”: [“Two”, “Three”, “Four”, “Six”, “Eight”],
“infoText”: “”
},
“enum”: [2,3,4,6,8]
},
“ColorTheme”: {
“title”: “Theme”,
“description”: “ColorTheme”,
“property_order”: 15,
“type”: “string”,
“options”: {
“enum_titles”: [“Blackboard”, “Mac Classic”, “Spacegrey”, “Sunburst”, “Dusk”],
“infoText”: “”
},
“enum”: [“Blackboard”, “Mac Classic”, “Spacegrey”, “Sunburst”, “Dusk”]
}
}
}
Lesson 7 Links, Notes, and Files from Instructor:
Lesson 7: Managed Login Items
Last updated February 19, 2026
Objective
Safelist and manage scheduled tasks and third-party helper apps.
Discussion
- Managed Login Items
- Apps
- Agents
- Daemons
- Executables
- Rule Type
- Bundle identifier
- Bundle identifier prefix
- Label
- Label prefix
- Team identifier
- Rule Values
Resources
Jamf Pro Documentation
Apple Platform Deployment
Navigational aid
- Jamf Pro – Computers > Configuration Profiles > Managed Login Items
- macOS – System Settings > General > Login Items
Examples
- Bundle Identifier
-
Obtain the bundle identifier and team id for an app
codesign --display --verbose /Applications/APPLICATION.appObtain the bundle identifier for an executable
codesign --display --verbose /PATH/TO/BINARY - Label
-
Print the labels of active agents or daemons
launchctl listPrint the label of an agent or daemon
defaults read /PATH/TO/FILE.plist Label
Completed Tasks and Examples:
get-teamID-bundleID.sh
#!/bin/zsh –no-rcs
# codesign – get Team ID or Bundle ID
codesign –display –verbose /Applications/OneDrive.app
#Executable=/Applications/OneDrive.app/Contents/MacOS/OneDrive
#Identifier=com.microsoft.OneDrive <<—- BUNDLE ID
#Format=app bundle with Mach-O universal (x86_64 arm64)
#CodeDirectory v=20500 size=119330 flags=0x10000(runtime) hashes=3718+7 location=embedded
#Signature size=9012
#Timestamp=Jul 10, 2026 at 6:33:49 PM
#Info.plist entries=38
#TeamIdentifier=UBF8T346G9 <<—— TEAM ID
#Runtime Version=26.0.0
#Sealed Resources version=2 rules=13 files=946
#Internal requirements count=1 size=184
echo; echo
codesign –display –verbose /Applications/zoom.us.app/
echo; echo
codesign –display –verbose /Applications/Google\ Chrome.app/