One of the capabilities of mobile device management (MDM) on macOS is that you can use MDM commands to deploy installer packages, via the InstallEnterpriseApplication MDM command. If you’re using Jamf Pro for your MDM management, one of the capabilities of the Jamf Pro API is being able to leverage its ability to run MDM commands to send out InstallEnterpriseApplication commands to deploy installer packages. For more details, please see below the jump.
The relevant Jamf Pro API endpoint is the v1/deploy-package endpoint. Here are the required API permissions for using it:
API permissions using user account authentication:
Jamf Pro Server Objects:
Jamf Pro Server Actions:
API permissions using API client authentication:
Installer packages deployed using this method would need to be signed and built as a distribution-style package. I have a blog post describing the details available via the link below:
If you look at the Jamf Pro API documentation available with Jamf Pro, using the v1/deploy-package Jamf Pro API endpoint to successfully deploy a package requires sending a JSON block containing a manifest for the package along with some additional information on whether or not the package is set to be managed and which devices to install it on. Let’s take a look at the essential components of this block, using an example provided as part of the Jamf API documentation:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "manifest": { | |
| "url": "https://example.jamf.com/this/package", | |
| "hash": "dcb02a41cd6d842943459a88c96a5f72", | |
| "hashType": "MD5", | |
| "displayImageUrl": "https://example.jamf.com/img/display/this/package.jpg", | |
| "fullSizeImageUrl": "https://example.jamf.com/img/full/this/package.jpg", | |
| "bundleId": "com.jamf.example", | |
| "bundleVersion": "0.1.0", | |
| "subtitle": "Subtitle", | |
| "title": "Title", | |
| "sizeInBytes": 12345 | |
| }, | |
| "installAsManaged": false, | |
| "devices": [ | |
| 1, | |
| 2, | |
| 3 | |
| ], | |
| "groupId": "1" | |
| } |
This has several parts, so let’s break it down by section:
Manifest:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "manifest": { | |
| "url": "https://example.jamf.com/this/package", | |
| "hash": "dcb02a41cd6d842943459a88c96a5f72", | |
| "hashType": "MD5", | |
| "displayImageUrl": "https://example.jamf.com/img/display/this/package.jpg", | |
| "fullSizeImageUrl": "https://example.jamf.com/img/full/this/package.jpg", | |
| "bundleId": "com.jamf.example", | |
| "bundleVersion": "0.1.0", | |
| "subtitle": "Subtitle", | |
| "title": "Title", | |
| "sizeInBytes": 12345 | |
| }, |
This is providing the MDM command’s information about the package to be installed. Here are the essential parts you need to provide as part of the manifest:
Note: The hash type description must use capitalization. No lowercase letters allowed in this use case.
For more information on the topic of creating a manifest for installer packages deployed using the InstallEnterpriseApplication MDM command, please see the link below:
https://www.dersoldat.org/?p=1456
Next, there’s the choice to install as managed or not:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "installAsManaged": false, |
The installAsManaged configuration option defines if the installer package is defined as installing a managed app or not installing a managed app. For the most part, this defines whether or not the MDM would be able to uninstall the app following installation using the InstallEnterpriseApplication MDM command.
The default configuration for the InstallAsManaged configuration option is false, so unless you know you will need to define it as true, this configuration option does not need to be included as part of the API call.
For Mac admins, here are the considerations to keep in mind for this option:
installAsManaged = true:
installAsManaged = false:
Of course, if you’re choosing to deploy an installer package, you need to define what devices you’re installing it on. That’s the next two parts of the configuration:
This allows you to define the individual Jamf Pro ID numbers of the devices you want to install on.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This allows you to define the device static or smart group containing the devices you want to deploy the installer package to.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here’s an example API command to install a package named MyGreatInstaller.pkg as unmanaged from an S3 bucket named 75d831079efb4d02ada44eed4f8ae093 on individual devices with Jamf Pro device IDs 102, 103 and 104:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In this example, the JSON block being sent looks like this:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "manifest": { | |
| "url": "https://75d831079efb4d02ada44eed4f8ae093.s3.us-east-1.amazonaws.com/MyGreatInstaller.pkg", | |
| "hash": "75c9ed772b6c31e705597014983a276b", | |
| "hashType": "MD5", | |
| "bundleId": "com.company.MyGreatInstaller", | |
| "bundleVersion": "2.0.1", | |
| "title": "MyGreatInstaller", | |
| "sizeInBytes": 20582383 | |
| }, | |
| "devices": [ | |
| 102, | |
| 103, | |
| 104 | |
| ] | |
| } |
Here’s an example API command to install a package named MyGreatInstaller.pkg as unmanaged from an S3 bucket named 75d831079efb4d02ada44eed4f8ae093 on all devices in a Jamf Pro device group with Jamf Pro ID 37:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In this example, the JSON block being sent looks like this:
Once the API command is sent, there are two possible HTTP status codes which indicate the API command ran successfully:
Here’s an example of a successful API response from an installer package deployment to a device with the Jamf Pro ID of 67:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "queuedCommands": [ | |
| { | |
| "device": 67, | |
| "commandUuid": "c30d945d-23ff-4d6d-be25-295af24d9a92" | |
| } | |
| ], | |
| "errors": [] | |
| } |