-
-
Notifications
You must be signed in to change notification settings - Fork 37
JamfUploader AutoPkg Processors
Note: these Processors are now hosted in the
autopkg/grahampugh-recipes
repo.
Users of AutoPkg can use the JamfScriptUploader
, JamfCategoryUploader
, JamfComputerGroupUploader
, JamfExtensionAttributeUploader
, JamfPackageUploader
and JamfPolicyUploader
processors to upload scripts, categories, computer groups, extension attributes, packages and policies (with icons) respectively. These Processors share the functionality of the standalone scripts, though will only upload one object per process. Multiple processors can be added to a single AutoPkg recipe.
For an introduction into JamfUploader, watch the 2021 JNUC presentation Making package uploading and deployment easier with JamfUploader by Graham Pugh and Anthony Reimer.
To use these processors, you need to add the grahampugh-recipes
repo to your AutoPkg preferences:
autopkg repo-add grahampugh-recipes
In a recipe, you call the processor as follows (in this example we are calling JamfPackageUploader
):
<dict>
<key>Processor</key>
<string>com.github.grahampugh.jamf-upload.processors/JamfPackageUploader</string>
</dict>
All the processors require these keys to be populated in your AutoPkg preferences, Input variables, or by command line keys:
JSS_URL
API_USERNAME
API_PASSWORD
If you haven't done so already, you'll need to create a service account with which the processors can interact with the API. It is recommended to create a user named something like "AutoPkg", which you can do in the Jamf Pro admin interface in Management Settings > Jamf Pro User Accounts and Groups.
NOTE: the API account password must not have an exclamation mark (!
) in it, otherwise authentication will fail.
The user will need Create, Read, and Update privileges on some or all of the following:
- Categories
- Computer Extension Attributes
- Smart Computer Groups
- Static Computer Groups
- File Share Distribution Points (only needs "Read")
- Cloud Distribution Points (only needs "Read")
- Packages
- Policies
- Scripts
- Computer Configuration Profiles
- Mac Applications
If you are using the jcds_mode
flag in conjunction with JamfPackageUploader, and your Jamf instance is configured to use Single Sign-On, your AutoPkg service account will require Update privileges on SSO settings. jcds_mode
essentially scrapes the web interface, so your service account needs to be able to make use of your failover log-in page.
If you are using Jamf Cloud or other Cloud Distribution Point, you do not need to provide any additional credentials.
If you are using an SMB Fileshare Distribution Point, you should additionally provide the following keys:
SMB_URL
SMB_USERNAME
SMB_PASSWORD
If you use the JamfPolicyDeleter
processor, you will need to add Delete permissions to Policies.
For people who just want to upload a package, JamfPackageUploader.py
can be run as a post-processor, e.g.:
autopkg run FoldingAtHome.pkg --post com.github.grahampugh.jamf-upload.processors/JamfPackageUploader
The processor could also be added to an override, or a new .jamf-upload
recipe could be made, with the .pkg
recipe as its parent.
Please do not use the
.jss
suffix for a package-upload-only recipe if you publish it, as that would confuse the recipe with recipes that use JSSImporter. I suggest.jamf-upload.recipe
.
The package at pkg_path
will be uploaded to Jamf Pro if a package of the same name is not already on the server. If no pkg_path
is supplied, JamfPackageUploader
will check if the file at pathname
ends with .pkg
and will use this package. This has the potential, in certain circumstances, to run the .download
recipe directly:
autopkg run AdoptOpenJDK11_Signed.download --post com.github.grahampugh.jamf-upload.processors/JamfPackageUploader --key pkg_path="%pathname%"
Note that you don't have control over the package name if you upload a package directly from a
.download
recipe. You can override thepkg_name
key in the command line, but there is no way to populate theversion
key into thepkg_name
key by this method. If no version is provided in a.download
recipe I recommend that you use or create a.pkg
recipe to achieve this.
These processors can be used instead of JSSImporter to perform an analogous workflow. The modular processors mean there is a higher degree of flexibility than JSSmporter. For example:
- You can create/update categories, scripts, extension attributes and computer groups from an AutoPkg recipe independent of policies.
- You can supply script parameter values to policies as well as parameter titles to scripts all in the same recipe.
- There is no need to supply a template XML file to upload scripts or extension attributes.
- Dependent icon, script and template files do not need to be copied to a
RecipeOverride
folder - they will be found if they are anywhere in theRECIPE_SEARCH_DIRS
. - You can create as many policies in one recipe as you like.
- You can add as many packages to a policy as you like.
- There is full flexibility as to whether you wish to replace (update) existing categories, packages, computer groups, scripts, extension attributes, policies and self-service policy icons.
- AutoPkg
.download
recipes that provide apkg
directly can be used as a parent recipe to.jamf
recipes - no need for a.pkg
recipe.
This additional flexibility means a slight increase in complexity of recipes and templates. Over time, I intend to provide extensive documentation, examples and automation scripts to make adoption of the Jamf-Upload Processors as easy as possible.
There are myriad variations of how you may want your policies in Jamf to look, and what is scoped. As a basis, here I explain how to set up a recipe that replicates the JSSImporter "standard" .jss
recipe format. This provides the following:
- A category is created with the
category_name
input variable, if not already on the Jamf Pro server. - The package is uploaded, with its category determined by the
pkg_category
input variable. - A Smart Computer Group is created or updated, called
%NAME%-update-smart
, whereNAME
is determined in the input variables of the recipe. Normally,NAME
corresponds to the Application Name, e.g.Google Chrome
,Visual Studio Code
, etc. The default criteria of this group is that a computer is in theTesting
Computer Group, and the application is installed, but not the current version. - A policy is created or updated, called
Install Latest %NAME%
. The policy is givenTesting
category and scoped to the%NAME%-update-smart
smart group. The install and reinstall buttons are given the labelInstall %version%
whereversion
was determined in the parent recipes. A Self Service Description is provided. The Self Service Name and Category match the policy name and category respectively. - The application icon is uploaded to the policy if it has not previously been uploaded, or the name does not match the existing icon.
These recipes can substitute for existing .jss
recipes with no change in workflow, i.e. you do not need to change your policy names.
However, the PolicyTemplate.xml
used in .jss
recipes cannot be used with .jamf
recipes. This repo provides the replacement which is called PolicyTemplate-install-latest.xml
. This policy template is designed to be more flexible than those used in JSSImporter - you can completely override the policy name, self service name and install/reinstall button labels. Note that there is no PROD_NAME
variable in .jamf
recipes (I never knew what this variable was used for). Instead we have NAME
(a value that is normally the name of the application), POLICY_NAME
(which in standard recipes is Install Latest %NAME%
, but can be overridden) and SELF_SERVICE_NAME
(which in standard recipes is the same as POLICY_NAME
, but can be independently overridden).
Similarly, the SmartGroupTemplate.xml
is slightly changed in comparison to that provided for the standard .jss
recipes. Here, we provide SmartGroupTemplate-update-smart.xml
. Note that the GROUP_NAME
value is provided in the Inputs, and by default is %NAME%-update-smart
. I have kept the JSS_INVENTORY_NAME
key that is used in JSSImporter, which by default equates to %NAME%.app
but can be overridden.
Please do not use the
.jss
suffix for recipes that use these new processors if you publish it, as that would confuse the recipe with recipes that use JSSImporter. I suggest.jamf.recipe
.
The package at pkg_path
will be uploaded to Jamf Pro if a package of the same name is not already on the server. If no pkg_path
is supplied, JamfPackageUploader
will check if the file at pathname
ends with .pkg
and will use this package.
Note that
.download
recipes that download a package directly may not provide a version, and the name of the file may not conform to your standard naming convention. If a.pkg
recipe exists, I recommend using this as the parent, and if not, and the.download
recipe does not provide a version, I recommend that you write a.pkg
recipe rather than add aVersioner
processor to your.jamf
recipe.
If you wish to enforce the overwrite of an existing package, set replace_pkg
to True
. I do not recommend this being set by default as it would hugely extend your AutoPkg run time, potentially unnecessarily, and also because package upload to Jamf Pro is not 100% reliable. I would therefore recommend only to override this value from the command line when you need to replace a package of the same name because something has changed, e.g.:
AutoPkg run GoogleChrome.jamf --key replace_pkg=True
When a package already exists on the server and is not overwritten, the computer group and policy are not touched when using standard .jamf
recipes as provided in this repo. This default is achieved using the StopProcessingIf
processor, with the predicate set by default to pkg_uploaded == False
, and is equivalent to setting STOP_IF_NO_JSS_UPLOAD
to True
when using JSSImporter. To override this default and force the creation/overwriting of the smart group and policy in the recipe every time, set the UPDATE_PREDICATE
value to FALSEPREDICATE
.
Unlike JSSImporter, Scripts and Extension Attributes do not require XML templates. Simply provide the path to the script/extension attribute. There are additional keys for each type of script that are provided directly in the recipe rather than via a template.
For scripts, the following keys are assignable:
script_path
script_category
script_priority
osrequirements
script_info
script_notes
script_parameter4
script_parameter5
script_parameter6
script_parameter7
script_parameter8
script_parameter9
script_parameter10
script_parameter11
Set replace_script
to True
to overwrite an existing script. This is set to False
by default.
For extension attributes, the following keys are assignable:
ea_name
ea_script_path
Set replace_ea
to True
to overwrite an existing extension attribute. This is set to False
by default.
It is not common to update category objects once created. However, I have made this possible with the JamfCategoryUploader
processor in case you wish to change the priority of the category while retaining the name. You can assign the category_priority
key in a .jamf
recipe.
Set replace_category
to True
to replace an existing category object when changing priority.
You can create and update configuration profiles with AutoPkg, using the JamfComputerProfileUploader
processor. As the name suggests, this can only update computer-based configuration profiles, as Mobile Device profiles have a different API endpoint. I would recommend that you only use this method for creating custom profiles. This is because the Jamf Classic API does not allow for the uploading of signed configuration profiles, so any profile that you upload which includes keys managed by Jamf will be mangled.
There are two ways in which you can create or update a configuration profile:
-
Similar to how you can upload a plist file to the Jamf Pro GUI to provide a custom payload, you can upload the same plist file using the
JamfComputerProfileUploader
processor. As with the GUI, you must additionally provide the profile name, identifier, organisation and description. These can be supplied in the AutoPkg recipe. What actually happens is that the processor compiles amobileconfig
file from the details you provided, generating a new UUID, and uploads it. If you are replacing an existing profile (identified by name), the processor will grab the existing UUID from the server and use the same one. It also ensures that the changes are pushed to all devices. -
The other option is to upload a complete
mobileconfig
file, similar to how you use the "Upload" button in the Jamf Pro GUI. In the case you don't need to supply the profile name, identifier, organisation or description, as these should already be embedded in themobileconfig
file. Again, if you are replacing an existing profile (identified by name), the processor will grab the existing UUID from the server and use the same one.
Both methods also need you to provide an XML template, similarly to what you provide for policies and smart groups in JamfUpload and JSSImporter recipes. The mobileconfig
contents are substituted into the template along with name, category and scope. You can also use the template to determine whether the profile should be issued automatically or made available in Self Service. Unfortunately, a bug (or probably more accurately, an oversight) in the Jamf Pro API means that you cannot upload an icon to a Self Service configuration profile.
Set replace_profile
to True
to replace an existing configuration profile object.
I have published some example/reference .jamf
recipes at grahampugh-recipes:Jamf_Recipes. To try out these recipes, don't forget to add this repo to your AutoPkg repo-list:
autopkg repo-add grahampugh-recipes
Then you can try out a recipe, for example the Firefox recipe:
autopkg make-override Firefox.jamf
autopkg run -v Firefox.jamf
I encourage you to try verbose runs (-vv
) and very verbose runs (-vvv
) to see the extent of output that is made available for debugging.
Example recipes involving scripts and profiles can also be found at autopkg/grahampugh-recipes:Jamf_Script_Recipes and grahampugh/recipes-yaml:Jamf_Profile_Recipes respectively. The templates are all found in autopkg/grahampugh-recipes:Jamf_Templates.
-
There is no support for copying packages to local repos or multiple distribution points at this time. Raise an Issue if this is important to you.
-
Mounting and/or unmounting may fail if you have the Jamf Admin app open and connected to the same FileShare that you have configured. It is therefore safest to close Jamf Admin before running AutoPkg recipes that use the
JamfPackageUploader
processor. -
An API account password must not have an exclamation mark (
!
) in it, otherwise authentication will fail.
Please raise any new issues concerning the processors in this repo, not in autopkg/grahampugh-recipes
.