Posted on 01-18-2019 12:38 PM
Perhaps someone has done this before, I didn’t really search around for it before I put this workflow together.
As we know, the jamf binary does not use APNs, so we haven’t had a way to “send a push command” to call the jamf binary for things like ‘jamf recon’, ‘jamf policy’, etc.. Until now. Sorta.
Here is my workflow for achieving this.
Create a LaunchDaemon that watches for a particular Managed Preference (MCX) plist
Run a script via the LaunchDaemon that reads the MCX file for the jamf verb (recon, policy, etc)
Create a Configuration Profile with the “Custom” payload to push the MCX file
Scope the Configuration Profile to a Static Group
Add a Mac to the static group to force a call to the jamf binary via MDM/APNs
The LaunchDaemon
File Name: /Library/LaunchDaemons/com.yourdomain.daemon.mdm_trigger.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.yourdomain.daemon.mdm_trigger</string> <key>ProgramArguments</key> <array> <string>sh</string> <string>-c</string> <string>/usr/local/bin/mcx_watcher.sh</string> </array> <key>WatchPaths</key> <array> <string>/Library/Managed Preferences/com.yourdomain.mdm_trigger.plist</string> </array> </dict> </plist>
The Script
File Name: mcx_watcher.sh
#!/bin/sh COMMAND=$(defaults read /Library/Managed Preferences/com.yourdomain.mdm_trigger Command) /usr/local/jamf/bin/jamf $COMMAND exit 0
The MCX
File Name: com.yourdomain.mdm_trigger.plist (make sure it matches the “WatchPaths” in the LaunchDaemon)
Value for the Command key: the jamf verb (ie recon, policy, manage, etc)
Upload this to the "Custom" payload in a Configuration Profile
<?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>Command</key> <string>recon</string> </dict> </plist>
The Static Group
Group Name: Recon Trigger
Scope the Configuration Profile to this group
Adding a Mac to this group puts it in scope for the Configuration Profile
Rather than changing the scope of the profile itself, which prompts if you want to “Distribute to All” each time, this just quietly scopes and un-scopes the the target Mac(s) to the Config Profile
Each time you add a Mac to this static group, it pushes the plist file which the LaunchDaemon is watching for, which triggers the script to read the “verb” for the jamf command, then runs the 'jamf verb' command
There may be a good way to use the API to trigger this process, but this basic workflow is working as a proof of concept.
Package the script and the LaunchDaemon with composer
/usr/local/bin/mcx_watcher.sh
/Library/LaunchDaemons/com.yourdomain.daemon.mdm_trigger.plist
Add a “postinstall” script to the pkg:
#!/bin/sh chown 0:0 /usr/local/bin/mcx_watcher.sh chmod u+x /usr/local/bin/mcx_watcher.sh chown 0:0 /Library/LaunchDaemons/com.yourdomain.daemon.mdm_trigger.plist chmod 644 /Library/LaunchDaemons/com.yourdomain.daemon.mdm_trigger.plist launchctl load /Library/LaunchDaemons/com.yourdomain.daemon.mdm_trigger.plist exit 0
Posted on 01-19-2019 07:46 PM
@B_Hanson Thanks for posting this. User @Rajeev described something like it in a thread named SuperMDM, but has since deleted the contents of the post describing his technique, and the GitHub page referenced in the thread is no longer accessible.
One extension I'd suggest for your approach is to handle additional parameters for command in addition to verb. That'd allow triggering a specific policy by adding -event or -id to the policy command.
Posted on 05-06-2024 08:32 AM
Hi @B_Hanson I tried this but it's not worked, I'm not sure what I missed here. can you help me?
Launch Daemons is up and running and I pushed the configuration profile from jamf but recon command not worked
Posted on 05-06-2024 08:47 AM
Original post is over 5 years old, I haven't maintained this workflow. I would confirm that your LaunchDaemon is triggering on the "WatchPaths". For example, just have your script just run something like this:
echo "Script Ran" >> /tmp/test.log
Then push the Config Profile to see if the LaunchDaemon actually runs when the managed preference is delivered to /Library/Managed Preferences/.
I notice "The Script" section in the original post isn't formatted quite right, the commands appear to run together without semicolons or line breaks, so it should look like this:
#!/bin/sh
COMMAND=$(defaults read /Library/Managed Preferences/com.yourdomain.mdm_trigger Command)
/usr/local/jamf/bin/jamf $COMMAND
exit 0