├── .pylintrc ├── setup.cfg ├── JamfUploaderProcessors ├── JamfUploaderLib │ └── __init__.py ├── JamfUploaderProcessors.recipe.yaml ├── README.md ├── READMEs │ ├── JamfPackageRecalculator.md │ ├── JamfPolicyDeleter.md │ ├── JamfComputerGroupDeleter.md │ ├── JamfObjectDeleter.md │ ├── JamfPolicyLogFlusher.md │ ├── JamfExtensionAttributePopupChoiceAdjuster.md │ ├── JamfComputerGroupUploader.md │ ├── JamfCategoryUploader.md │ ├── JamfMobileDeviceGroupUploader.md │ ├── JamfDockItemUploader.md │ ├── JamfAPIRoleUploader.md │ ├── JamfUploaderTeamsNotifier.md │ ├── JamfObjectStateChanger.md │ ├── JamfScopeAdjuster.md │ ├── JamfAccountUploader.md │ ├── JamfUploaderSlacker.md │ ├── JamfPatchChecker.md │ ├── JamfPackageCleaner.md │ ├── JamfMacAppUploader.md │ ├── JamfPolicyUploader.md │ ├── JamfUploaderJiraIssueCreator.md │ ├── JamfPatchUploader.md │ ├── JamfMSUPlanUploader.md │ ├── JamfAPIClientUploader.md │ ├── JamfMobileDeviceAppUploader.md │ ├── JamfMobileDeviceProfileUploader.md │ ├── JamfMobileDeviceExtensionAttributeUploader.md │ ├── JamfSoftwareRestrictionUploader.md │ ├── JamfExtensionAttributeUploader.md │ ├── JamfComputerProfileUploader.md │ ├── JamfObjectUploader.md │ └── JamfScriptUploader.md ├── JamfPackageRecalculator.py └── JamfPolicyDeleter.py ├── _tests ├── templates │ ├── Category-Template-Testing.json │ ├── org.videolan.vlc.plist.yaml │ ├── StaticGroupTemplate-Testing.xml │ ├── local-admin-password-settings.json │ ├── APIRoleTemplate-example.json │ ├── Cisco AnyConnect System Extension and Content Filter Whitelist.signed.mobileconfig │ ├── MicrosoftAutoUpdate-EA.sh │ ├── org.videolan.vlc.plist │ ├── self-service-settings.json │ ├── SmartGroupTemplate-test-users.xml │ ├── AppConfig.xml │ ├── us.zoom.config.plist │ ├── AllowScreenRecording-mobiledevicegroup.xml │ ├── com.github.macadmins.Nudge.plist.yaml │ ├── RestrictionTemplate-allcomputers.xml │ ├── Account-User-groupaccess.xml │ ├── RestrictionTemplate-no-scope.xml │ ├── com.bombich.ccc.plist │ ├── SmartGroup-testing-test.xml │ ├── SmartGroupTemplate-installed.xml │ ├── RestrictionTemplate-singlegroup.xml │ ├── ProfileTemplate-test-users.xml │ ├── computer-inventory-collection-settings.json │ ├── MobileDeviceProfileTemplate-test-users.xml │ ├── MacApp-noscope-autoinstall.xml │ ├── SmartGroupTemplate-Firefox-update-smart.xml │ ├── enrollment.json │ ├── SmartGroupTemplate-example-update-smart.xml │ ├── SmartGroupTemplate-test-version-installed.xml │ ├── Firefox-nonokeys.jamf.recipe.yaml │ ├── app-installer-deployment-example.json │ ├── PolicyTemplate-trigger.xml │ ├── TestProfileIdentifiers.mobileconfig │ ├── AllowScreenRecording.mobileconfig │ ├── PolicyTemplate-example-Firefox.xml │ ├── PatchTemplate-automatic.xml │ ├── MacApp-allcomputers.xml │ ├── PolicyTemplate-runcommand.xml │ ├── MacApp-noscope.xml │ ├── ProfileTemplate-1-group-1-exclusion.xml │ ├── TestProfileIdentifiers2.mobileconfig │ ├── MobileDeviceApp-noscope-autoinstall.xml │ ├── PolicyTemplate-example.xml │ ├── Firefox-nokeys.jamf.recipe.yaml │ ├── PatchTemplate-selfservice.xml │ ├── MicrosoftAutoUpdate-notifications.mobileconfig │ ├── MobileDeviceApp-noscope.xml │ ├── PolicyTemplate-example-postinstall.xml │ ├── Account-User-fullaccess.xml │ ├── Kernel Extension Whitelist.mobileconfig │ ├── LDAPServerTemplate.xml │ ├── computer-prestage-example-account.json │ ├── computer-prestage-example.json │ └── Cisco AnyConnect System Extension and Content Filter Whitelist.mobileconfig ├── _DownloadPolicyListTest.jamf.recipe.yaml ├── _DownloadAllPoliciesTest.jamf.recipe.yaml ├── _ReadAndParseTest.jamf.recipe.yaml ├── _ParseAndUploadTest.jamf.recipe.yaml ├── run_all_recipes.sh ├── _ChangePolicyNameTest.jamf.recipe.yaml ├── jira-test.sh ├── transfer-to-grahampugh-recipes.sh ├── api_test_pkg.sh └── pkg_upload.py ├── .prettierrc.yaml ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── requirements.txt ├── Jamf_Helper_Recipes ├── RecalculatePackages.jamf.recipe.yaml ├── DeleteUnusedPackages.jamf.recipe.yaml ├── DownloadObjectList.jamf.recipe.yaml ├── DownloadAllObjects.jamf.recipe.yaml ├── DeleteObject.jamf.recipe.yaml ├── blueprints-Update to Latest macOS.json ├── Blueprint-Deploy-SoftwareUpdate.jamf.recipe.yaml ├── Blueprint-Undeploy-SoftwareUpdate.jamf.recipe.yaml ├── DeleteOldPackages.jamf.recipe.yaml ├── Blueprint-SoftwareUpdate.jamf.recipe.yaml ├── APIRoleClient-AutoPkg.jamf.recipe.yaml ├── CopyObject.jamf.recipe.yaml ├── Computer-EA-Choice-Remove.jamf.recipe.yaml ├── Computer-EA-Choice-Add.jamf.recipe.yaml └── APIRole-AutoPkg.json ├── _Templates_Examples ├── SmartGroup-script-self-service.xml ├── SmartGroup-application-installed.xml ├── MobileDeviceProfile-no-scope.xml ├── Profile-no-scope.xml ├── blueprints-Update to Latest macOS By Eligibility.json ├── SmartGroup-OSVersionLimits.xml ├── SmartGroup-uninstall-self-service.xml ├── SmartGroup-script-self-service-EA.xml ├── SmartGroup-update-smart-EA.xml ├── Policy-install-latest.xml ├── SmartGroup-update-smart-EA-regex.xml ├── ExamplePatchCheck.jamf.recipe.yaml ├── SmartGroup-update-smart.xml ├── Policy-script-self-service.xml ├── Policy-install-latest-script.xml ├── Profile-single-group.xml ├── SmartGroup-update-smart-regex.xml ├── Policy-install-latest-MicrosoftOffice365.xml ├── Policy-uninstall-self-service.xml └── SmartGroup-update-smart-MicrosoftOffice365.xml ├── README.md └── .gitignore /.pylintrc: -------------------------------------------------------------------------------- 1 | [FORMAT] 2 | max-line-length=100 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 100 -------------------------------------------------------------------------------- /JamfUploaderProcessors/JamfUploaderLib/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_tests/templates/Category-Template-Testing.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "Testing", 4 | "priority": 9 5 | } -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | semi: false 2 | overrides: 3 | - files: 4 | - "*.md" 5 | options: 6 | tabWidth: 2 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: ['https://grahamrpugh.com/sponsor.html'] 4 | -------------------------------------------------------------------------------- /_tests/templates/org.videolan.vlc.plist.yaml: -------------------------------------------------------------------------------- 1 | SUEnableAutomaticChecks: false 2 | SUHasLaunchedBefore: true 3 | SUSendProfileInfo: false 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi>=2020.6.20 2 | chardet>=3.0.4 3 | idna>=2.10 4 | requests>=2.24.0 5 | requests-toolbelt>=0.9.1 6 | six>=1.15.0 7 | urllib3>=1.26.5 8 | -------------------------------------------------------------------------------- /_tests/templates/StaticGroupTemplate-Testing.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Testing 4 | false 5 | 6 | -------------------------------------------------------------------------------- /_tests/templates/local-admin-password-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "autoDeployEnabled": true, 3 | "autoRotateEnabled": true, 4 | "autoRotateExpirationTime": 2592000, 5 | "passwordRotationTime": 86400 6 | } 7 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/JamfUploaderProcessors.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: Recipe stub for any Processors in this directory. 2 | Identifier: com.github.grahampugh.jamf-upload.processors 3 | Input: {} 4 | MinimumVersion: "2.3" 5 | Process: [] 6 | -------------------------------------------------------------------------------- /_tests/templates/APIRoleTemplate-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "%api_role_name%", 3 | "privileges": [ 4 | "Create Static Computer Groups", 5 | "Update Static Computer Groups", 6 | "Read Static Computer Groups" 7 | ] 8 | } -------------------------------------------------------------------------------- /_tests/templates/Cisco AnyConnect System Extension and Content Filter Whitelist.signed.mobileconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grahampugh/jamf-upload/HEAD/_tests/templates/Cisco AnyConnect System Extension and Content Filter Whitelist.signed.mobileconfig -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/RecalculatePackages.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: Recalculates the package inventory on a Jamf Cloud Distribution Server. 2 | Identifier: com.github.grahampugh.recipes.jamf.RecalculatePackages 3 | MinimumVersion: "2.3" 4 | 5 | Input: {} 6 | 7 | Process: 8 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPackageRecalculator 9 | -------------------------------------------------------------------------------- /_tests/_DownloadPolicyListTest.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.grahampugh.recipes.tests.DownloadPolicyList 2 | MinimumVersion: "2.3" 3 | Input: {} 4 | 5 | Process: 6 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 7 | Arguments: 8 | list_only: True 9 | object_type: policy 10 | output_dir: /Users/Shared/Jamf/JamfUploaderTests 11 | -------------------------------------------------------------------------------- /_tests/_DownloadAllPoliciesTest.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.grahampugh.recipes.tests.DownloadAllPolicies 2 | MinimumVersion: "2.3" 3 | Input: {} 4 | 5 | Process: 6 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 7 | Arguments: 8 | all_objects: True 9 | object_type: policy 10 | output_dir: /Users/Shared/Jamf/JamfUploaderTests 11 | -------------------------------------------------------------------------------- /_tests/templates/MicrosoftAutoUpdate-EA.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | MAUVersion="None" 3 | if [ -f "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/Info.plist" ]; then 4 | MAUVersion=$(/usr/bin/defaults read "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/Info.plist" CFBundleVersion) 5 | fi 6 | 7 | echo "$MAUVersion" 8 | 9 | exit 0 -------------------------------------------------------------------------------- /_tests/templates/org.videolan.vlc.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SUEnableAutomaticChecks 6 | 7 | SUHasLaunchedBefore 8 | 9 | SUSendProfileInfo 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/DeleteUnusedPackages.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.autopkg.grahampugh-recipes.jamf.DeleteUnusedPackages 2 | MinimumVersion: "2.3" 3 | 4 | Input: 5 | DRY_RUN: "True" 6 | 7 | Process: 8 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfUnusedPackageCleaner 9 | Arguments: 10 | output_dir: /Users/Shared/Jamf/JamfUploader 11 | dry_run: "%DRY_RUN%" 12 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/DownloadObjectList.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.grahampugh.recipes.jamf.DownloadObjectList 2 | MinimumVersion: "2.3" 3 | Input: 4 | OUTPUT_DIR: /Users/Shared/Jamf/JamfUploader 5 | 6 | Process: 7 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 8 | Arguments: 9 | object_type: "%OBJECT_TYPE%" 10 | list_only: True 11 | output_dir: "%OUTPUT_DIR%" 12 | -------------------------------------------------------------------------------- /_tests/_ReadAndParseTest.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.grahampugh.recipes.tests.ReadAndParse 2 | MinimumVersion: "2.3" 3 | 4 | Input: {} 5 | 6 | Process: 7 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 8 | Arguments: 9 | object_name: Firefox 10 | object_type: policy 11 | output_path: /Users/Shared/Jamf/JamfUploaderTests 12 | elements_to_remove: 13 | - site 14 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/DownloadAllObjects.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.grahampugh.recipes.jamf.Helper-DownloadAllObjects 2 | MinimumVersion: "2.3" 3 | Input: 4 | OUTPUT_DIR: /Users/Shared/Jamf/JamfUploader 5 | 6 | Process: 7 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 8 | Arguments: 9 | object_type: "%OBJECT_TYPE%" 10 | all_objects: "True" 11 | output_dir: "%OUTPUT_DIR%" 12 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/DeleteObject.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: | 2 | Deletes an object from Jamf Pro. 3 | Requires the object type and object name to be specified as input variables. 4 | Identifier: com.github.grahampugh.recipes.jamf.DeleteObject 5 | MinimumVersion: "2.3" 6 | Input: {} 7 | 8 | Process: 9 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectDeleter 10 | Arguments: 11 | object_type: "%OBJECT_TYPE%" 12 | object_name: "%NAME%" 13 | -------------------------------------------------------------------------------- /_tests/templates/self-service-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "installSettings": { 3 | "installAutomatically": true, 4 | "installLocation": "/Applications" 5 | }, 6 | "loginSettings": { 7 | "userLoginLevel": "NotRequired", 8 | "allowRememberMe": true, 9 | "useFido2": true, 10 | "authType": "Saml" 11 | }, 12 | "configurationSettings": { 13 | "notificationsEnabled": false, 14 | "alertUserApprovedMdm": true, 15 | "defaultLandingPage": "HOME", 16 | "defaultHomeCategoryId": -1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-script-self-service.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Computer Group 8 | 0 9 | and 10 | member of 11 | %TESTING_GROUP_NAME% 12 | false 13 | false 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /_tests/templates/SmartGroupTemplate-test-users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %POLICY_NAME% test users 4 | true 5 | 6 | 1 7 | 8 | Computer Group 9 | 0 10 | and 11 | member of 12 | Testing 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-application-installed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %INSTALLED_GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | false 13 | false 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /_tests/_ParseAndUploadTest.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.grahampugh.recipes.tests.ParseAndUpload 2 | MinimumVersion: "2.3" 3 | 4 | Input: {} 5 | 6 | Process: 7 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 8 | Arguments: 9 | object_name: Firefox 10 | object_type: policy 11 | object_template: /Users/Shared/Jamf/JamfUploaderTests/jssimporter-policies-Firefox.xml 12 | elements_to_remove: 13 | - scope 14 | - category 15 | - self_service 16 | - trigger_checkin 17 | - frequency 18 | replace_object: True 19 | -------------------------------------------------------------------------------- /_tests/templates/AppConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | INVITATION_STRING 3 | $MOBILEDEVICEAPPINVITE 4 | JSS_ID 5 | $JSSID 6 | SERIAL_NUMBER 7 | $SERIALNUMBER 8 | DEVICE_NAME 9 | $DEVICENAME 10 | MAC_ADDRESS 11 | $MACADDRESS 12 | MANAGEMENT_ID 13 | $MANAGEMENTID 14 | JSS_URL 15 | $JPS_URL 16 | JAMFUPLOAD_VARIABLE 17 | %CATEGORY% 18 | 19 | -------------------------------------------------------------------------------- /_tests/templates/us.zoom.config.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ForceLoginWithSSO 6 | 0 7 | LastLoginType 8 | 1 9 | ZAutoSSOLogin 10 | 0 11 | ZAutoUpdate 12 | 0 13 | keepsignedin 14 | 1 15 | nofacebook 16 | 1 17 | nogoogle 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /_tests/run_all_recipes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # these repos needed 4 | autopkg repo-add nstrauss-recipes recipes hjuutilainen-recipes ahousseini-recipes homebysix-recipes novaksam-recipes nzmacgeek-recipes hansen-m-recipes keeleysam-recipes rtrouton-recipes joshua-d-miller-recipes nmcspadden-recipes dataJAR-recipes tbridge-recipes amsysuk-recipes killahquam-recipes crystalllized-recipes scriptingosx-recipes 5 | 6 | for recipe in "$HOME/Library/AutoPkg/RecipeRepos/com.github.autopkg.grahampugh-recipes/Jamf_Recipes/"*; do 7 | echo 8 | echo "RUNNING ${recipe/\.recipe$/}" 9 | autopkg run -v "${recipe/\.recipe$/}" 10 | echo 11 | done 12 | -------------------------------------------------------------------------------- /_Templates_Examples/MobileDeviceProfile-no-scope.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobileconfig_name% 5 | %description% 6 | 7 | %category% 8 | 9 | Install Automatically 10 | false 11 | System 12 | %uuid% 13 | All 14 | %payload% 15 | 16 | 17 | -------------------------------------------------------------------------------- /_Templates_Examples/Profile-no-scope.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobileconfig_name% 5 | %description% 6 | 7 | %category% 8 | 9 | Install Automatically 10 | false 11 | computer 12 | %uuid% 13 | All 14 | %payload% 15 | 16 | 17 | -------------------------------------------------------------------------------- /_tests/templates/AllowScreenRecording-mobiledevicegroup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 1 7 | 8 | Mobile Device Group 9 | 0 10 | and 11 | member of 12 | %TESTING_GROUP_NAME% 13 | false 14 | false 15 | 16 | 17 | -------------------------------------------------------------------------------- /_tests/templates/com.github.macadmins.Nudge.plist.yaml: -------------------------------------------------------------------------------- 1 | PayloadContent: 2 | - osVersionRequirements: 3 | - aboutUpdateURLs: 4 | - _language: en 5 | aboutUpdateURL: https://support.apple.com/en-us/HT211896#macos1121 6 | majorUpgradeAppPath: /Applications/Install macOS Big Sur.app 7 | requiredInstallationDate: 2021-02-28 00:00:00 8 | requiredMinimumOSVersion: 11.2.2 9 | targetedOSVersions: 10 | - "11.0" 11 | - 11.0.1 12 | - "11.1" 13 | - "11.2" 14 | - "11.2.1" 15 | userInterface: 16 | simpleMode: true 17 | optionalFeatures: 18 | enforceMinorUpdates: true 19 | -------------------------------------------------------------------------------- /_tests/templates/RestrictionTemplate-allcomputers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %restriction_name% 5 | %process_name% 6 | %match_exact_process_name% 7 | %send_notification% 8 | %kill_process% 9 | %delete_executable% 10 | %display_message% 11 | 12 | 13 | true 14 | 15 | 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FR] " 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. E.g. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/blueprints-Update to Latest macOS.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Update to Latest macOS", 3 | "description": "Keep all eligible MacOS devices updated to the last major version", 4 | "scope": { 5 | "deviceGroups": [ 6 | "%GROUP_ID%" 7 | ] 8 | }, 9 | "steps": [ 10 | { 11 | "components": [ 12 | { 13 | "configuration": { 14 | "targetOSVersion": "26.0.1", 15 | "targetLocalDateTime": "2025-11-08T09:25:00" 16 | }, 17 | "identifier": "com.jamf.ddm.sw-updates" 18 | } 19 | ], 20 | "name": "Step 1" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /_tests/templates/Account-User-groupaccess.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %account_name% 4 | %ACCOUNT_PASSWORD% 5 | false 6 | %ACCOUNT_FULLNAME% 7 | %ACCOUNT_EMAIL% 8 | %ACCOUNT_EMAIL% 9 | Enabled 10 | false 11 | Group Access 12 | Custom 13 | 14 | 15 | %GROUP_NAME% 16 | 17 | -1 18 | None 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /_tests/templates/RestrictionTemplate-no-scope.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %restriction_name% 5 | %process_name% 6 | %match_exact_process_name% 7 | %send_notification% 8 | %kill_process% 9 | %delete_executable% 10 | %display_message% 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/README.md: -------------------------------------------------------------------------------- 1 | # JamfUploader processors for AutoPkg 2 | 3 | These processors are developed in [grahampugh/jamf-upload][1] and periodicially copied into [autopkg/grahampugh-recipes][2]. 4 | 5 | I welcome contributions to this project. **Please only issue PRs to [grahampugh/jamf-upload][1]** 6 | 7 | ## Documentation 8 | 9 | Details of these processors can be found in the [wiki][3]. 10 | 11 | There are also descriptions of the input and output variables in the [READMEs folder][4]. 12 | 13 | [1]: https://github.com/grahampugh/jamf-upload/tree/main/JamfUploaderProcessors 14 | [2]: https://github.com/autopkg/grahampugh-recipes/tree/main/JamfUploaderProcessors 15 | [3]: https://github.com/grahampugh/jamf-upload/wiki/JamfUploader-AutoPkg-Processors 16 | [4]: READMEs/ -------------------------------------------------------------------------------- /_Templates_Examples/blueprints-Update to Latest macOS By Eligibility.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Update to Latest macOS By Eligibility", 3 | "description": "Keep all eligible MacOS devices updated to the last major version", 4 | "scope": { 5 | "deviceGroups": [ 6 | "%GROUP_ID%" 7 | ] 8 | }, 9 | "steps": [ 10 | { 11 | "components": [ 12 | { 13 | "configuration": { 14 | "targetOSVersion": "15.6", 15 | "targetLocalDateTime": "2025-08-08T09:25:00" 16 | }, 17 | "identifier": "com.jamf.ddm.sw-updates" 18 | } 19 | ], 20 | "name": "Step 1" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /_tests/templates/com.bombich.ccc.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | RegistrationCode 6 | %REGISTRATION_CODE% 7 | RegistrationEmail 8 | %REGISTRATION_EMAIL% 9 | RegistrationName 10 | %REGISTRATION_NAME% 11 | RegistrationProductName 12 | %REGISTRATION_PRODUCT_NAME% 13 | SUCheckAtStartup 14 | 15 | SUScheduledCheckInterval 16 | 0 17 | userAgreedToLicenseAgreement 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/Blueprint-Deploy-SoftwareUpdate.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: Recalculates the package inventory on a Jamf Cloud Distribution Server. 2 | Identifier: com.github.grahampugh.recipes.jamf.Blueprint-Deploy-SoftwareUpdate 3 | MinimumVersion: "2.3" 4 | 5 | Input: 6 | REGION: eu 7 | 8 | Process: 9 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 10 | Arguments: 11 | JSS_URL: https://%REGION%.apigw.jamf.com 12 | object_type: blueprint 13 | object_name: Update to Latest macOS 14 | 15 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 16 | Arguments: 17 | JSS_URL: https://%REGION%.apigw.jamf.com 18 | object_type: blueprint_deploy_command 19 | replace_object: "true" 20 | -------------------------------------------------------------------------------- /_tests/templates/SmartGroup-testing-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Testing 4 | true 5 | 6 | 1 7 | 8 | Username 9 | 0 10 | and 11 | matches regex 12 | 4ea$ 13 | 14 | 15 | Computer Group 16 | 1 17 | or 18 | member of 19 | Testing-static 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/Blueprint-Undeploy-SoftwareUpdate.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: Recalculates the package inventory on a Jamf Cloud Distribution Server. 2 | Identifier: com.github.grahampugh.recipes.jamf.Blueprint-Undeploy-SoftwareUpdate 3 | MinimumVersion: "2.3" 4 | 5 | Input: 6 | REGION: eu 7 | 8 | Process: 9 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 10 | Arguments: 11 | JSS_URL: https://%REGION%.apigw.jamf.com 12 | object_type: blueprint 13 | object_name: Update to Latest macOS 14 | 15 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 16 | Arguments: 17 | JSS_URL: https://%REGION%.apigw.jamf.com 18 | object_type: blueprint_undeploy_command 19 | replace_object: "true" 20 | -------------------------------------------------------------------------------- /_tests/templates/SmartGroupTemplate-installed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %POLICY_NAME% installed 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | 13 | 14 | Computer Group 15 | 1 16 | and 17 | member of 18 | %USERS_GROUP_NAME% 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/DeleteOldPackages.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: | 2 | Recipe to delete old packages from Jamf Pro server. Requires the NAME key. 3 | Identifier: com.github.autopkg.grahampugh-recipes.jamf.DeleteOldPackages 4 | MinimumVersion: "2.3" 5 | 6 | Input: 7 | PACKAGE_NAME_MATCH: "%NAME%-" 8 | VERSIONS_TO_KEEP: 5 9 | MINIMUM_NAME_LENGTH: 3 10 | MAXIMUM_ALLOWED_PACKAGES_TO_DELETE: 20 11 | DRY_RUN: "True" 12 | 13 | Process: 14 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPackageCleaner 15 | Arguments: 16 | pkg_name_match: "%PACKAGE_NAME_MATCH%" 17 | versions_to_keep: "%VERSIONS_TO_KEEP%" 18 | minimum_name_length: "%MINIMUM_NAME_LENGTH%" 19 | maximum_allowed_packages_to_delete: "%MAXIMUM_ALLOWED_PACKAGES_TO_DELETE%" 20 | dry_run: "%DRY_RUN%" 21 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-OSVersionLimits.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %OS_LIMITS_GROUP_NAME% 4 | true 5 | 6 | 7 | Operating System Version 8 | 0 9 | and 10 | less than or equal 11 | %OS_EXCLUDE_MAX% 12 | 13 | 14 | Operating System Version 15 | 1 16 | and 17 | greater than or equal 18 | %OS_EXCLUDE_MIN% 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-uninstall-self-service.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | false 13 | false 14 | 15 | 16 | Computer Group 17 | 1 18 | and 19 | member of 20 | %TESTING_GROUP_NAME% 21 | false 22 | false 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /_tests/templates/RestrictionTemplate-singlegroup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %restriction_name% 5 | %process_name% 6 | %match_exact_process_name% 7 | %send_notification% 8 | %kill_process% 9 | %delete_executable% 10 | %display_message% 11 | 12 | 13 | 14 | 15 | %computergroup_name% 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/Blueprint-SoftwareUpdate.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: Recalculates the package inventory on a Jamf Cloud Distribution Server. 2 | Identifier: com.github.grahampugh.recipes.jamf.Blueprint-SoftwareUpdate 3 | MinimumVersion: "2.3" 4 | 5 | Input: 6 | REGION: eu 7 | 8 | Process: 9 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 10 | Arguments: 11 | object_type: group 12 | object_name: All Managed 13 | 14 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 15 | Arguments: 16 | JSS_URL: https://%REGION%.apigw.jamf.com 17 | GROUP_ID: "%object_id%" 18 | object_id: "" 19 | object_type: blueprint 20 | object_name: Update to Latest macOS 21 | object_template: blueprints-Update to Latest macOS.json 22 | replace_object: "true" 23 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-script-self-service-EA.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | %EXTENSION_ATTRIBUTE_NAME% 8 | 0 9 | and 10 | is not 11 | %EXTENSION_ATTRIBUTE_VALUE% 12 | false 13 | false 14 | 15 | 16 | Computer Group 17 | 1 18 | and 19 | member of 20 | %TESTING_GROUP_NAME% 21 | false 22 | false 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /_tests/_ChangePolicyNameTest.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.grahampugh.recipes.tests.ChangePolicyName 2 | Comment: | 3 | Designed to work in a wrapper script, using an edited JSON file based on a list_only output from JamfObjectReader. 4 | Requires: 5 | - OBJECT_ID 6 | - NEW_NAME 7 | MinimumVersion: "2.3" 8 | Input: {} 9 | 10 | Process: 11 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 12 | Arguments: 13 | object_id: "%OBJECT_ID%" 14 | object_type: policy 15 | output_dir: /Users/Shared/Jamf/JamfUploaderTests 16 | 17 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 18 | Arguments: 19 | object_id: "%OBJECT_ID%" 20 | object_name: "%NEW_NAME%" 21 | object_type: policy 22 | object_template: "%output_path%" 23 | replace_object: True 24 | -------------------------------------------------------------------------------- /_tests/templates/ProfileTemplate-test-users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobileconfig_name% 5 | %description% 6 | 7 | %category% 8 | 9 | Install Automatically 10 | false 11 | computer 12 | %uuid% 13 | All 14 | %payload% 15 | 16 | 17 | 18 | 19 | %profile_computergroup% 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/APIRoleClient-AutoPkg.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: | 2 | Creates an API Role and Client for AutoPkg. 3 | Requires the following keys to be overridden: 4 | API_ROLE_NAME 5 | API_CLIENT_NAME 6 | Identifier: com.github.grahampugh.recipes.jamf.APIRoleClient-AutoPkg 7 | MinimumVersion: "2.3" 8 | 9 | Input: 10 | # Common Settings start here 11 | API_ROLE_TEMPLATE: APIRole-AutoPkg.json 12 | 13 | Process: 14 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfAPIRoleUploader 15 | Arguments: 16 | api_role_name: "%API_ROLE_NAME%" 17 | api_role_template: "%API_ROLE_TEMPLATE%" 18 | replace_api_role: "True" 19 | 20 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfAPIClientUploader 21 | Arguments: 22 | api_client_name: "%API_CLIENT_NAME%" 23 | api_client_enabled: "True" 24 | replace_api_client: "True" 25 | -------------------------------------------------------------------------------- /_tests/templates/computer-inventory-collection-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "computerInventoryCollectionPreferences": { 3 | "monitorApplicationUsage": true, 4 | "includeFonts": true, 5 | "includePlugins": true, 6 | "includePackages": true, 7 | "includeSoftwareUpdates": true, 8 | "includeSoftwareId": true, 9 | "includeAccounts": true, 10 | "calculateSizes": false, 11 | "includeHiddenAccounts": true, 12 | "includePrinters": true, 13 | "includeServices": true, 14 | "collectSyncedMobileDeviceInfo": false, 15 | "updateLdapInfoOnComputerInventorySubmissions": false, 16 | "monitorBeacons": true, 17 | "allowChangingUserAndLocation": true, 18 | "useUnixUserPaths": true, 19 | "collectUnmanagedCertificates": true 20 | }, 21 | "applicationPaths": [], 22 | "fontPaths": [], 23 | "pluginPaths": [] 24 | } 25 | -------------------------------------------------------------------------------- /_tests/templates/MobileDeviceProfileTemplate-test-users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobileconfig_name% 5 | %description% 6 | 7 | %category% 8 | 9 | Install Automatically 10 | false 11 | System 12 | %uuid% 13 | All 14 | %payload% 15 | 16 | 17 | false 18 | 19 | 20 | %profile_mobiledevicegroup% 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /_tests/templates/MacApp-noscope-autoinstall.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %macapp_name% 5 | %macapp_version% 6 | %macapp_is_free% 7 | %bundleid% 8 | %appstore_url% 9 | 10 | %CATEGORY% 11 | 12 | 13 | None 14 | 15 | %DEPLOYMENT_TYPE% 16 | 17 | 18 | false 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | true 28 | %vpp_id% 29 | 30 | 31 | -------------------------------------------------------------------------------- /_tests/templates/SmartGroupTemplate-Firefox-update-smart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Firefox-update-smart 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | Firefox.app 12 | 13 | 14 | Application Version 15 | 1 16 | and 17 | is 18 | %version% 19 | 20 | 21 | Computer Group 22 | 2 23 | and 24 | member of 25 | Testing 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /_tests/templates/enrollment.json: -------------------------------------------------------------------------------- 1 | { 2 | "installSingleProfile": false, 3 | "signingMdmProfileEnabled": false, 4 | "mdmSigningCertificate": { 5 | "filename": "null" 6 | }, 7 | "restrictReenrollment": false, 8 | "flushLocationInformation": true, 9 | "flushLocationHistoryInformation": true, 10 | "flushPolicyHistory": true, 11 | "flushExtensionAttributes": true, 12 | "flushMdmCommandsOnReenroll": "DELETE_EVERYTHING", 13 | "macOsEnterpriseEnrollmentEnabled": false, 14 | "createManagementAccount": true, 15 | "hideManagementAccount": false, 16 | "allowSshOnlyManagementAccount": false, 17 | "ensureSshRunning": true, 18 | "launchSelfService": false, 19 | "signQuickAdd": false, 20 | "developerCertificateIdentity": { 21 | "filename": "null" 22 | }, 23 | "iosEnterpriseEnrollmentEnabled": true, 24 | "iosPersonalEnrollmentEnabled": false, 25 | "personalDeviceEnrollmentType": "PERSONALDEVICEPROFILES", 26 | "accountDrivenUserEnrollmentEnabled": false 27 | } 28 | -------------------------------------------------------------------------------- /_tests/templates/SmartGroupTemplate-example-update-smart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | 13 | 14 | %VERSION_CRITERION% 15 | 1 16 | and 17 | is 18 | %version% 19 | 20 | 21 | Computer Group 22 | 2 23 | and 24 | member of 25 | %TESTING_STATIC_GROUP% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /_tests/templates/SmartGroupTemplate-test-version-installed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %POLICY_NAME% test version installed 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | 13 | 14 | Application Version 15 | 1 16 | and 17 | is 18 | %version% 19 | 20 | 21 | Computer Group 22 | 2 23 | and 24 | member of 25 | %POLICY_NAME% test users 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/CopyObject.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: | 2 | Recipe to copy objects from one Jamf Pro server to another. Requires SOURCE_URL and DESTINATION_URL keys. By default, the source URL is defined as the JSS_URL variable. Also requires the OBJECT_TYPE key to define which object type to copy, and the name of the object to copy via the NAME key. 3 | 4 | Credentials for each URL must be defined. These may be defined in the Keychain or via variables. 5 | Identifier: com.github.autopkg.grahampugh-recipes.jamf.CopyObject 6 | MinimumVersion: "2.3" 7 | 8 | Input: 9 | SOURCE_URL: "%JSS_URL%" 10 | REPLACE_OBJECT: "True" 11 | 12 | Process: 13 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 14 | Arguments: 15 | output_dir: /Users/Shared/Jamf/JamfUploader 16 | object_type: "%OBJECT_TYPE%" 17 | object_name: "%NAME%" 18 | JSS_URL: "%SOURCE_URL%" 19 | 20 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 21 | Arguments: 22 | JSS_URL: "%DESTINATION_URL%" 23 | replace_object: "%REPLACE_OBJECT%" 24 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-update-smart-EA.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | 13 | 14 | %EXTENSION_ATTRIBUTE_NAME% 15 | 1 16 | and 17 | is not 18 | %version% 19 | 20 | 21 | %EXTENSION_ATTRIBUTE_NAME% 22 | 2 23 | and 24 | does not match regex 25 | ^$ 26 | 27 | 28 | Computer Group 29 | 3 30 | and 31 | member of 32 | %TESTING_GROUP_NAME% 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /_tests/templates/Firefox-nonokeys.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: | 2 | Downloads the latest version of Firefox and makes a pkg. Then, uploads the package to the Jamf Pro Server and creates a Self Service Policy and Smart Group. 3 | Identifier: com.github.grahampugh.recipes.jamf.Firefox 4 | MinimumVersion: "2.3" 5 | ParentRecipe: com.github.autopkg.pkg.Firefox_EN 6 | 7 | Input: 8 | NAME: Firefox 9 | 10 | Process: 11 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfCategoryUploader 12 | Arguments: 13 | category_name: Productivity 14 | 15 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPackageUploader 16 | 17 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfComputerGroupUploader 18 | Arguments: 19 | computergroup_template: SmartGroupTemplate-Firefox-update-smart.xml 20 | computergroup_name: Firefox-update-smart 21 | 22 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPolicyUploader 23 | Arguments: 24 | policy_template: PolicyTemplate-Install-Latest-Firefox.xml 25 | policy_name: Install Latest Firefox 26 | icon: Firefox.png 27 | -------------------------------------------------------------------------------- /_tests/templates/app-installer-deployment-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Sublime Text 4", 3 | "enabled": true, 4 | "appTitleId": "355", 5 | "deploymentType": "SELF_SERVICE", 6 | "updateBehavior": "AUTOMATIC", 7 | "smartGroupId": "7", 8 | "installPredefinedConfigProfiles": true, 9 | "titleAvailableInAis": true, 10 | "triggerAdminNotifications": false, 11 | "notificationSettings": { 12 | "notificationMessage": "Please update as soon as possible", 13 | "notificationInterval": 24, 14 | "deadlineMessage": "Closing app to allow update", 15 | "deadline": 168, 16 | "quitDelay": 5, 17 | "completeMessage": "Update is complete", 18 | "relaunch": true, 19 | "suppress": null 20 | }, 21 | "selfServiceSettings": { 22 | "includeInFeaturedCategory": false, 23 | "includeInComplianceCategory": false, 24 | "forceViewDescription": false, 25 | "description": null, 26 | "categories": [ 27 | { 28 | "id": "12", 29 | "featured": false 30 | } 31 | ] 32 | }, 33 | "selectedVersion": "", 34 | "latestAvailableVersion": "Build 4192", 35 | "versionRemoved": false 36 | } 37 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfPackageRecalculator.md: -------------------------------------------------------------------------------- 1 | # JamfPackageRecalculator 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will recalculate the JCDS packages endpoint. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | 25 | ## Output variables 26 | 27 | - **jamfpackagerecalculator_summary_result:** 28 | - **description:** Description of interesting results. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] " 5 | labels: bug 6 | assignees: grahampugh 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior. For example: 15 | - Which Processor was running at the time of the crash [e.g. `JamfPackageUploader`? 16 | - Which parameters were being sent [e.g. `jcds2_mode=True`]? 17 | 18 | In most cases, a full, verbose AutoPkg output (with any secrets obfuscated) will be most helpful. 19 | 20 | **Expected behaviour** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Log output** 24 | If applicable, add a full, verbose AutoPkg output (with any secrets obfuscated) to help explain your problem. 25 | 26 | ``` 27 | Paste output here or attach a file 28 | ``` 29 | 30 | **Environment (please complete the following information):** 31 | - OS: [e.g. macOS 15] 32 | - AutoPkg version [e.g. 2.7.3, 3.0.0b2] 33 | - Are you using the processors in `grahampugh/jamf-upload` (bleeding edge) or `autopkg/grahampugh-recipes` (stable)? 34 | - Are you running a different branch to `main`? 35 | 36 | **Additional context** 37 | Add any other context about the problem here. 38 | -------------------------------------------------------------------------------- /_Templates_Examples/Policy-install-latest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | Ongoing 7 | 8 | %POLICY_CATEGORY% 9 | 10 | 11 | 12 | 13 | 14 | %GROUP_NAME% 15 | 16 | 17 | 18 | 19 | 20 | 1 21 | 22 | %pkg_name% 23 | Install 24 | 25 | 26 | 27 | 28 | 0 29 | 30 | 31 | true 32 | %INSTALL_BUTTON_TEXT% 33 | %REINSTALL_BUTTON_TEXT% 34 | %SELF_SERVICE_DISPLAY_NAME% 35 | %SELF_SERVICE_DESCRIPTION% 36 | 37 | 38 | true 39 | 40 | 41 | %POLICY_RUN_COMMAND% 42 | 43 | 44 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/Computer-EA-Choice-Remove.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: Removes a choice to a computer extension attribute and removes the associated Computer Smart Group 2 | Comment: | 3 | Requires the following keys to be set or overridden: 4 | * EXTENSION_ATTRIBUTE_NAME 5 | * EXTENSION_ATTRIBUTE_VALUE 6 | Identifier: com.github.autopkg.grahampugh-recipes.jamf.Computer-EA-Choice-Remove 7 | MinimumVersion: "2.3" 8 | 9 | Input: 10 | COMPUTER_ROLE_EXTENSION_ATTRIBUTE_NAME: "%display_name_prefix%Role" 11 | REPLACE: "True" 12 | 13 | Process: 14 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 15 | Arguments: 16 | object_name: "%EXTENSION_ATTRIBUTE_NAME%" 17 | object_type: computer_extension_attribute 18 | 19 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfExtensionAttributePopupChoiceAdjuster 20 | Arguments: 21 | choice_operation: remove 22 | choice_value: "%EXTENSION_ATTRIBUTE_VALUE%" 23 | 24 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 25 | Arguments: 26 | replace_object: "%REPLACE%" 27 | 28 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectDeleter 29 | Arguments: 30 | object_name: "%EXTENSION_ATTRIBUTE_NAME% - %EXTENSION_ATTRIBUTE_VALUE%" 31 | object_type: computer_group 32 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-update-smart-EA-regex.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | 13 | 14 | %EXTENSION_ATTRIBUTE_NAME% 15 | 1 16 | and 17 | does not match regex 18 | %version_regex% 19 | 20 | 21 | %EXTENSION_ATTRIBUTE_NAME% 22 | 2 23 | and 24 | does not match regex 25 | %version_regex_2% 26 | 27 | 28 | %EXTENSION_ATTRIBUTE_NAME% 29 | 3 30 | and 31 | does not match regex 32 | ^$ 33 | 34 | 35 | Computer Group 36 | 4 37 | and 38 | member of 39 | %TESTING_GROUP_NAME% 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /_Templates_Examples/ExamplePatchCheck.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Identifier: com.github.example.jamf.patchcheck 2 | 3 | Input: {} 4 | 5 | Process: 6 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPatchChecker 7 | Arguments: 8 | patch_softwaretitle: '%PATCH_SOFTWARE_TITLE%' 9 | pkg_name: '%NAME% %version%.pkg' 10 | 11 | - Processor: StopProcessingIf 12 | Arguments: 13 | predicate: patch_version_found == False 14 | 15 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPackageUploader 16 | Arguments: 17 | pkg_name: '%NAME% %version%.pkg' 18 | pkg_category: '%CATEGORY%' 19 | 20 | - Processor: StopProcessingIf 21 | Arguments: 22 | predicate: pkg_uploaded == False 23 | 24 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPolicyUploader 25 | Arguments: 26 | policy_name: '%POLICY_NAME%' 27 | policy_template: '%POLICY_TEMPLATE%' 28 | policy_category: '%CATEGORY%' 29 | icon: '%app_icon_path%' 30 | replace_icon: 'True' 31 | replace_policy: 'True' 32 | 33 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPatchUploader 34 | Arguments: 35 | patch_name: '%PATCH_POLICY_NAME%' 36 | patch_softwaretitle: '%PATCH_SOFTWARE_TITLE%' 37 | patch_template: '%PATCH_POLICY_TEMPLATE%' 38 | patch_icon_policy_name: '%POLICY_NAME%' 39 | replace_patch: 'True' 40 | 41 | -------------------------------------------------------------------------------- /_tests/templates/PolicyTemplate-trigger.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | EVENT 7 | false 8 | false 9 | false 10 | false 11 | false 12 | false 13 | %TRIGGER_NAME% 14 | Ongoing 15 | 16 | %CATEGORY% 17 | 18 | 19 | 20 | true 21 | 22 | 23 | 24 | 1 25 | 26 | %pkg_name% 27 | Install 28 | 29 | 30 | 31 | 32 | 0 33 | 34 | 35 | false 36 | 37 | 38 | true 39 | 40 | 41 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-update-smart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | true 13 | false 14 | 15 | 16 | Application Version 17 | 1 18 | and 19 | is not 20 | %version% 21 | false 22 | false 23 | 24 | 25 | Application Title 26 | 2 27 | or 28 | is not 29 | %JSS_INVENTORY_NAME% 30 | false 31 | true 32 | 33 | 34 | Computer Group 35 | 3 36 | and 37 | member of 38 | %TESTING_GROUP_NAME% 39 | false 40 | false 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /_tests/templates/TestProfileIdentifiers.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | PayloadDisplayName 9 | Spotlight 10 | PayloadIdentifier 11 | com.apple.Spotlight.56235E14-85C7-43C3-9485-ABDF869B8CC9 12 | PayloadType 13 | com.apple.Spotlight 14 | PayloadUUID 15 | 56235E14-85C7-43C3-9485-ABDF869B8CC9 16 | PayloadVersion 17 | 1 18 | orderedItems 19 | 20 | 21 | enabled 22 | 23 | name 24 | APPLICATIONS 25 | 26 | 27 | 28 | 29 | PayloadDisplayName 30 | Another Test Profile for Identifiers 31 | PayloadIdentifier 32 | 49d6f994-0271-497e-9d83-d18932b2a809 33 | PayloadOrganization 34 | memyselfandi.com 35 | PayloadType 36 | Configuration 37 | PayloadUUID 38 | 49d6f994-0271-497e-9d83-d18932b2a809 39 | PayloadVersion 40 | 1 41 | 42 | 43 | -------------------------------------------------------------------------------- /_Templates_Examples/Policy-script-self-service.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | Ongoing 7 | 8 | %POLICY_CATEGORY% 9 | 10 | 11 | 12 | 13 | 14 | %GROUP_NAME% 15 | 16 | 17 | 18 | 19 | 20 | 0 21 | 22 | 23 | 24 | 1 25 | 37 | 38 | 39 | true 40 | %INSTALL_BUTTON_TEXT% 41 | %REINSTALL_BUTTON_TEXT% 42 | %SELF_SERVICE_DISPLAY_NAME% 43 | %SELF_SERVICE_DESCRIPTION% 44 | true 45 | 46 | 47 | true 48 | 49 | 50 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/Computer-EA-Choice-Add.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: Adds a choice to a computer extension attribute and creates a Computer Smart Group 2 | Comment: | 3 | Requires the following keys to be set or overridden: 4 | * EXTENSION_ATTRIBUTE_NAME 5 | * EXTENSION_ATTRIBUTE_VALUE 6 | Identifier: com.github.autopkg.grahampugh-recipes.jamf.Computer-EA-Choice-Add 7 | MinimumVersion: "2.3" 8 | 9 | Input: 10 | REPLACE: "True" 11 | 12 | Process: 13 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectReader 14 | Arguments: 15 | object_name: "%EXTENSION_ATTRIBUTE_NAME%" 16 | object_type: computer_extension_attribute 17 | 18 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfExtensionAttributePopupChoiceAdjuster 19 | Arguments: 20 | choice_operation: add 21 | choice_value: "%EXTENSION_ATTRIBUTE_VALUE%" 22 | strict_mode: "False" 23 | 24 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfObjectUploader 25 | Arguments: 26 | replace_object: "%REPLACE%" 27 | 28 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfComputerGroupUploader 29 | Arguments: 30 | EXTENSION_ATTRIBUTE_OPERATOR: is 31 | EXTENSION_ATTRIBUTE_VALUE: "%EXTENSION_ATTRIBUTE_VALUE%" 32 | TARGET_GROUP_NAME: "%EXTENSION_ATTRIBUTE_NAME% - %EXTENSION_ATTRIBUTE_VALUE%" 33 | computergroup_name: "%TARGET_GROUP_NAME%" 34 | computergroup_template: ComputerGroup-EA.xml 35 | replace_group: "%REPLACE%" 36 | -------------------------------------------------------------------------------- /_Templates_Examples/Policy-install-latest-script.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | Ongoing 7 | 8 | %POLICY_CATEGORY% 9 | 10 | 11 | 12 | 13 | 14 | %GROUP_NAME% 15 | 16 | 17 | 18 | 19 | 20 | 1 21 | 22 | %pkg_name% 23 | Install 24 | 25 | 26 | 27 | 28 | 1 29 | 41 | 42 | 43 | true 44 | %INSTALL_BUTTON_TEXT% 45 | %REINSTALL_BUTTON_TEXT% 46 | %SELF_SERVICE_DISPLAY_NAME% 47 | %SELF_SERVICE_DESCRIPTION% 48 | 49 | 50 | true 51 | 52 | 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JamfUploader 2 | 3 | JamfUploader is a name given to a set of [AutoPkg](https://github.com/autopkg/autopkg) Processors designed to interact with the Jamf Pro APIs. Most of these processors are concerned with uploading things to a Jamf Pro Server. This includes: 4 | 5 | * Packages 6 | * Categories 7 | * Computer Groups 8 | * Configuration Profiles 9 | * Scripts 10 | * Extension Attributes 11 | * Policies (and their icons) 12 | * Patch Policies 13 | * Dock Items 14 | * Accounts 15 | 16 | There are some additional processors. 17 | 18 | This repo contains the sourcecode of the JamfUploader processors. Identical copies of the processors are hosted in the [autopkg/grahampugh-recipes](https://github.com/autopkg/grahampugh-recipes) repo, in the [JamfUploaderProcessors](https://github.com/autopkg/grahampugh-recipes/tree/main/JamfUploaderProcessors) folder). 19 | 20 | **Please see the [Wiki](https://github.com/grahampugh/jamf-upload/wiki/JamfUploader-AutoPkg-Processors) for instructions on using the AutoPkg processors.** 21 | 22 | ## Additional Resources 23 | 24 | The `jamf-upload.sh` script can be used to take advantage of the JamfUploader processors without needing any AutoPkg recipes. 25 | 26 | ## Notice 27 | 28 | The `jamf-api-tool.py` script has been moved to its own repository, [jamf-api-tool](https://github.com/grahampugh/jamf-api-tool). 29 | 30 | Please see the [Wiki](https://github.com/grahampugh/jamf-upload/wiki) for instructions on using both the standalone script, `jamf-upload.sh`, the AutoPkg processors, and other tips and tricks. 31 | -------------------------------------------------------------------------------- /_tests/templates/AllowScreenRecording.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | PayloadDisplayName 9 | Restrictions Payload 10 | PayloadIdentifier 11 | F761063D-B566-40A2-8E7D-9D24800754EE 12 | PayloadOrganization 13 | JAMF Software 14 | PayloadType 15 | com.apple.applicationaccess 16 | PayloadUUID 17 | F761063D-B566-40A2-8E7D-9D24800754EE 18 | PayloadVersion 19 | 1 20 | allowScreenShot 21 | 22 | 23 | 24 | PayloadDescription 25 | 26 | PayloadDisplayName 27 | Allow Screen Recording 28 | PayloadEnabled 29 | 30 | PayloadIdentifier 31 | 4136D54E-A564-4AE9-9F63-E19B5254B9C5 32 | PayloadOrganization 33 | ETH Zurich 34 | PayloadRemovalDisallowed 35 | 36 | PayloadScope 37 | System 38 | PayloadType 39 | Configuration 40 | PayloadUUID 41 | 4136D54E-A564-4AE9-9F63-E19B5254B9C5 42 | PayloadVersion 43 | 1 44 | 45 | 46 | -------------------------------------------------------------------------------- /_tests/templates/PolicyTemplate-example-Firefox.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Install latest Firefox 5 | true 6 | Ongoing 7 | 8 | Browsers 9 | 10 | 11 | 12 | 13 | 14 | Firefox testers 15 | 16 | 17 | 18 | 19 | 20 | 21 | Firefox latest version installed 22 | 23 | 24 | 25 | 26 | 27 | 28 | 1 29 | 30 | %pkg_name% 31 | Install 32 | 33 | 34 | 35 | 36 | 0 37 | 38 | 39 | true 40 | Install 41 | Reinstall 42 | Install latest Firefox 43 | Firefox is a web browser from the Mozilla foundation. 44 | 45 | 46 | true 47 | 48 | 49 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfPolicyDeleter.md: -------------------------------------------------------------------------------- 1 | # JamfPolicyDeleter 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will delete a policy from a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **policy_name:** 25 | - **required:** False 26 | - **description:** Policy name 27 | - **max_tries:** 28 | - **required:** False 29 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 30 | - **default:** "5" 31 | 32 | ## Output variables 33 | 34 | - **jamfpolicydeleter_summary_result:** 35 | - **description:** Description of interesting results. 36 | -------------------------------------------------------------------------------- /_tests/templates/PatchTemplate-automatic.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %patch_name% 5 | %PATCH_ENABLED% 6 | %version% 7 | prompt 8 | false 9 | true 10 | 11 | 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 240 35 | Update 36 | $APP_NAMES will be closed in $DELAY_MINUTES minutes, so that $SOFTWARE_TITLE can be updated. Please save all documents now. 37 | 38 | 39 | %patch_softwaretitle_id% 40 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfComputerGroupDeleter.md: -------------------------------------------------------------------------------- 1 | # JamfComputerGroupDeleter 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will delete a computer group from a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **computer_group_name:** 25 | - **required:** False 26 | - **description:** Computer Group name 27 | - **max_tries:** 28 | - **required:** False 29 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 30 | - **default:** "5" 31 | 32 | ## Output variables 33 | 34 | - **jamfcomputergroupdeleter_summary_result:** 35 | - **description:** Description of interesting results. 36 | -------------------------------------------------------------------------------- /_tests/jira-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # test script for Jira issues. 4 | # Parameters: 5 | # $1 - subdomain (without .atlassian.net) 6 | # $2 - username (email address) 7 | # $3 - API token (generated in Jira) 8 | # $4 - project id 9 | 10 | subdomain="$1" 11 | USERNAME="$2" 12 | API_TOKEN="$3" 13 | project_id="$4" 14 | 15 | issuetype_id="10001" 16 | priority_id="2" 17 | description="Please ignore this issue. This is a test issue created by $USERNAME using a script to test Jira integration." 18 | summary="Test issue created by $USERNAME" 19 | 20 | 21 | token=$(echo -n $USERNAME:$API_TOKEN | base64) 22 | echo "Using token: $token" 23 | 24 | template='{ 25 | 26 | "fields": { 27 | "summary": "%s", 28 | "issuetype": { 29 | "id": "%s" 30 | }, 31 | "project": { 32 | "id": "%s" 33 | }, 34 | "priority": { 35 | "id": "%s" 36 | }, 37 | 38 | "description": { 39 | "type": "doc", 40 | "version": 1, 41 | "content": [ 42 | { 43 | "type": "paragraph", 44 | "content": [ 45 | { 46 | "text": "%s", 47 | "type": "text" 48 | } 49 | ] 50 | } 51 | ] 52 | } 53 | } 54 | }' 55 | 56 | json_final=$(printf "$template" \ 57 | "$summary" \ 58 | "$issuetype_id" \ 59 | "$project_id" \ 60 | "$priority_id" \ 61 | "$description") 62 | 63 | curl --location -X POST \ 64 | -H "Authorization: Basic $token" \ 65 | -H "Content-Type:application/json" \ 66 | "https://$subdomain.atlassian.net/rest/api/3/issue/" \ 67 | -d \ 68 | "$json_final" 69 | -------------------------------------------------------------------------------- /_Templates_Examples/Profile-single-group.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobileconfig_name% 5 | %description% 6 | 7 | %category% 8 | 9 | Install Automatically 10 | false 11 | computer 12 | %uuid% 13 | All 14 | %payload% 15 | 16 | 17 | false 18 | false 19 | 20 | 21 | 22 | 23 | 24 | %computergroup_name% 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfObjectDeleter.md: -------------------------------------------------------------------------------- 1 | # JamfObjectDeleter 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg to delete an API object. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **object_name**: 25 | - **required**: False 26 | - **description**: The name of the API object 27 | - **object_type**: 28 | - **required**: True 29 | - **description**: The API object type. This is in the singular form - the name of the key in the XML template. See the [Object Reference](./Object%20Reference.md) for valid objects. 30 | 31 | ## Output variables 32 | 33 | - **jamfobjectdeleter_summary_result:** 34 | - **description:** Description of interesting results. 35 | - **object_name**: 36 | - **description**: The name of the API object 37 | -------------------------------------------------------------------------------- /_tests/transfer-to-grahampugh-recipes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # copy JamfUploaderProcessors changes to grahampugh-recipes 4 | 5 | source_folder="$HOME/sourcecode" 6 | 7 | # 1. check branches and confirm to proceed 8 | if echo "jamf-upload:" && git -C "$source_folder/jamf-upload" status -sb && echo "grahampugh-recipes:" && git -C "$source_folder/grahampugh-recipes" status -sb; then 9 | printf '%s' "WARNING! This will overwrite "$source_folder/grahampugh-recipes/JamfUploaderProcessors". Are you sure? (Y/N) : " 10 | read -r are_you_sure < /dev/tty 11 | case "$are_you_sure" in 12 | Y|y) 13 | echo "Confirmed, proceeding" 14 | ;; 15 | *) 16 | echo "Declined, quitting" 17 | exit 0 18 | ;; 19 | esac 20 | else 21 | echo "ERROR connecting to remote repo" 22 | exit 1 23 | fi 24 | 25 | 26 | # 2. ensure repos are up-to-date 27 | 28 | if git -C "$source_folder/jamf-upload" pull; then 29 | echo "jamf-upload repo up to date" 30 | else 31 | echo "ERROR: repo could not be pulled, aborting" 32 | exit 1 33 | fi 34 | 35 | if git -C "$source_folder/grahampugh-recipes" pull; then 36 | echo "jamf-upload repo up to date" 37 | else 38 | echo "ERROR: repo could not be pulled, aborting" 39 | exit 1 40 | fi 41 | 42 | # 2. copy 43 | echo "Copying JamfUploaderProcessors folder" 44 | if cp -r "$source_folder/jamf-upload/JamfUploaderProcessors" "$source_folder/grahampugh-recipes/"; then 45 | echo "Copying was successful, now proceed to commit and push (manual process)" 46 | else 47 | echo "ERROR with copying the JamfUploaderProcessors folder - check and retry" 48 | exit 1 49 | fi 50 | 51 | -------------------------------------------------------------------------------- /_tests/templates/MacApp-allcomputers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %macapp_name% 5 | %bundleid% 6 | %appstore_url% 7 | 8 | %CATEGORY% 9 | 10 | 11 | None 12 | 13 | %DEPLOYMENT_TYPE% 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | 22 | 23 | Install 24 | false 25 | 26 | %selfservice_icon_uri% 27 | 28 | false 29 | 30 | 31 | %CATEGORY% 32 | true 33 | false 34 | 35 | 36 | false 37 | Self Service 38 | 39 | 40 | 41 | 42 | 43 | true 44 | %vpp_id% 45 | 46 | 47 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfPolicyLogFlusher.md: -------------------------------------------------------------------------------- 1 | # JamfPolicyLogFlusher 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will flush logs for a policy on a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **policy_name:** 25 | - **required:** True 26 | - **description:** Policy whose log is to be flushed 27 | - **logflush_interval:** 28 | - **required:** False 29 | - **description:** Log interval to be flushed 30 | - **default:** "Zero Days" 31 | - **max_tries:** 32 | - **required:** False 33 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 34 | - **default:** "5" 35 | 36 | ## Output variables 37 | 38 | - **jamfpolicylogflusher_summary_result:** 39 | - **description:** Description of interesting results. 40 | -------------------------------------------------------------------------------- /_tests/templates/PolicyTemplate-runcommand.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% v%version% 5 | true 6 | Ongoing 7 | 8 | %POLICY_CATEGORY% 9 | 10 | 11 | 12 | 13 | 14 | %POLICY_NAME% test users 15 | 16 | 17 | 18 | 19 | 20 | 21 | %POLICY_NAME% test version installed 22 | 23 | 24 | 25 | 26 | 27 | 28 | 0 29 | 30 | 31 | 32 | 0 33 | 34 | 35 | true 36 | Install 37 | Install 38 | %POLICY_NAME% v%version% 39 | %SELF_SERVICE_DESCRIPTION% 40 | 41 | 42 | 43 | false 44 | 45 | false 46 | 47 | 48 | false 49 | %RUN_COMMAND% 50 | 51 | 52 | true 53 | 54 | 55 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-update-smart-regex.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | true 13 | false 14 | 15 | 16 | Application Version 17 | 1 18 | and 19 | does not match regex 20 | %version_regex% 21 | false 22 | false 23 | 24 | 25 | Application Version 26 | 2 27 | and 28 | does not match regex 29 | %version_regex_2% 30 | false 31 | false 32 | 33 | 34 | Application Title 35 | 3 36 | or 37 | is not 38 | %JSS_INVENTORY_NAME% 39 | false 40 | true 41 | 42 | 43 | Computer Group 44 | 4 45 | and 46 | member of 47 | %TESTING_GROUP_NAME% 48 | false 49 | false 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /_Templates_Examples/Policy-install-latest-MicrosoftOffice365.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | Ongoing 7 | 8 | %POLICY_CATEGORY% 9 | 10 | 11 | 12 | 13 | 14 | %GROUP_NAME% 15 | 16 | 17 | 18 | 19 | 20 | %OS_LIMITS_GROUP_NAME% 21 | 22 | 23 | 24 | 25 | 26 | 27 | 1 28 | 29 | %pkg_name% 30 | Install 31 | 32 | 33 | 34 | 35 | 1 36 | 48 | 49 | 50 | true 51 | %INSTALL_BUTTON_TEXT% 52 | %REINSTALL_BUTTON_TEXT% 53 | %SELF_SERVICE_DISPLAY_NAME% 54 | %SELF_SERVICE_DESCRIPTION% 55 | 56 | 57 | true 58 | 59 | 60 | -------------------------------------------------------------------------------- /_tests/templates/MacApp-noscope.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %macapp_name% 5 | %macapp_version% 6 | %macapp_is_free% 7 | %bundleid% 8 | %appstore_url% 9 | 10 | %CATEGORY% 11 | 12 | 13 | None 14 | 15 | %DEPLOYMENT_TYPE% 16 | 17 | 18 | false 19 | 20 | 21 | 22 | 23 | 24 | 25 | Install 26 | false 27 | 28 | %selfservice_icon_uri% 29 | 30 | false 31 | 32 | 33 | %CATEGORY% 34 | true 35 | false 36 | 37 | 38 | false 39 | Self Service 40 | 41 | 42 | 43 | 44 | 45 | true 46 | %vpp_id% 47 | 48 | 49 | -------------------------------------------------------------------------------- /_tests/templates/ProfileTemplate-1-group-1-exclusion.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobileconfig_name% 5 | %description% 6 | 7 | %category% 8 | 9 | Install Automatically 10 | false 11 | computer 12 | %uuid% 13 | All 14 | %payload% 15 | 16 | 17 | false 18 | false 19 | 20 | 21 | 22 | 23 | 24 | %computergroup_name% 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | %EXCLUSION_GROUP_NAME% 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /_tests/templates/TestProfileIdentifiers2.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | PayloadDisplayName 9 | Spotlight 10 | PayloadIdentifier 11 | com.apple.Spotlight.56235E14-85C7-43C3-9485-ABDF869B8CC9 12 | PayloadType 13 | com.apple.Spotlight 14 | PayloadUUID 15 | 56235E14-85C7-43C3-9485-ABDF869B8CC9 16 | PayloadVersion 17 | 1 18 | orderedItems 19 | 20 | 21 | enabled 22 | 23 | name 24 | APPLICATIONS 25 | 26 | 27 | 28 | 29 | PayloadDisplayName 30 | Another Test Profile for Identifiers 31 | PayloadIdentifier 32 | Test2.189833B6-0BE6-4563-8ACB-4F44494785FD 33 | PayloadOrganization 34 | memyselfandi.com 35 | PayloadType 36 | Configuration 37 | PayloadUUID 38 | 189833B6-0BE6-4563-8ACB-4F44494785FD 39 | PayloadVersion 40 | 1 41 | 42 | 43 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfExtensionAttributePopupChoiceAdjuster.md: -------------------------------------------------------------------------------- 1 | # JamfExtensionAttributePopupChoiceAdjuster 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that adds or removes pop-up choices from a Jamf Pro Extension Attribute. It modifies XML or JSON files representing Jamf objects and can be used independently or as part of a larger workflow. 6 | 7 | ## Input variables 8 | 9 | - **object_template**: 10 | - **required**: False 11 | - **description**: Full path of the object file to modify. 12 | - **parsed_object**: 13 | - **required**: False 14 | - **description**: XML or JSON parsed object string to modify. Used if `object_template` is not supplied, e.g., if taking input from `JamfObjectReader`. 15 | - **choice_operation**: 16 | - **required**: True 17 | - **description**: Specify `'add'` to add a choice or `'remove'` to remove a choice. 18 | - **choice_value**: 19 | - **required**: True 20 | - **description**: Pop-up choice value to add or remove. 21 | - **strict_mode**: 22 | - **required**: False 23 | - **description**: Raise a `ProcessorError` when adding a choice that already exists or removing a choice that does not exist in the parsed object. If set to `False`, continues without modifying the parsed object. This ensures no unintended changes are made to the Jamf API, but incorrect choice names may go unnoticed. 24 | - **default**: `True` 25 | - **output_dir**: 26 | - **required**: False 27 | - **description**: Directory to save the modified XML or JSON file. Defaults to `RECIPE_CACHE_DIR`. 28 | 29 | ## Output variables 30 | 31 | - **object_template**: 32 | - **description**: Full path of the modified object file. Intended to pass to `JamfObjectUploader`. 33 | - **parsed_object**: 34 | - **description**: Parsed processed object string. For chaining additional `JamfExtensionAttributePopupChoiceAdjuster` processors. 35 | -------------------------------------------------------------------------------- /_tests/templates/MobileDeviceApp-noscope-autoinstall.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobiledeviceapp_name% 5 | %bundleid% 6 | %mobiledeviceapp_version% 7 | 8 | %CATEGORY% 9 | 10 | %itunes_store_url% 11 | true 12 | %DEPLOYMENT_TYPE% 13 | true 14 | true 15 | false 16 | false 17 | true 18 | false 19 | false 20 | false 21 | %mobiledeviceapp_free% 22 | true 23 | 24 | 25 | false 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | true 35 | %vpp_id% 36 | 37 | 38 | %appconfig% 39 | 40 | 41 | -------------------------------------------------------------------------------- /_tests/templates/PolicyTemplate-example.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | Ongoing 7 | 8 | %POLICY_CATEGORY% 9 | 10 | 11 | 12 | 13 | 14 | %GROUP_NAME% 15 | 16 | 17 | 18 | 19 | 20 | 21 | %EXCLUSION_GROUP_NAME% 22 | 23 | 24 | 25 | 26 | 27 | 28 | 1 29 | 30 | %pkg_name% 31 | Install 32 | 33 | 34 | 35 | 36 | 0 37 | 38 | 39 | true 40 | %SELF_SERVICE_INSTALL_BUTTON% 41 | %SELF_SERVICE_REINSTALL_BUTTON% 42 | %SELF_SERVICE_POLICY_NAME% 43 | %SELF_SERVICE_DESCRIPTION% 44 | 45 | 46 | 47 | false 48 | 49 | false 50 | 51 | 52 | false 53 | %POLICY_RUN_COMMAND% 54 | 55 | 56 | true 57 | 58 | 59 | -------------------------------------------------------------------------------- /_tests/templates/Firefox-nokeys.jamf.recipe.yaml: -------------------------------------------------------------------------------- 1 | Description: | 2 | Downloads the latest version of Firefox and makes a pkg. Then, uploads the package to the Jamf Pro Server and creates a Self Service Policy and Smart Group. 3 | Identifier: com.github.grahampugh.recipes.jamf.Firefox 4 | MinimumVersion: "2.3" 5 | ParentRecipe: com.github.autopkg.pkg.Firefox_EN 6 | 7 | Input: 8 | NAME: Firefox 9 | CATEGORY: Productivity 10 | GROUP_NAME: "%NAME%-update-smart" 11 | GROUP_TEMPLATE: SmartGroup-update-smart.xml 12 | VERSION_CRITERION: Application Version 13 | TESTING_GROUP_NAME: Testing 14 | POLICY_CATEGORY: Testing 15 | POLICY_TEMPLATE: Policy-install-latest.xml 16 | POLICY_NAME: "Install Latest %NAME%" 17 | POLICY_RUN_COMMAND: 'chown -R "$(stat -f%Su /dev/console):staff" "/Applications/%NAME%.app" && echo "Corrected permissions for %NAME%."' 18 | SELF_SERVICE_DISPLAY_NAME: "Install Latest %NAME%" 19 | SELF_SERVICE_DESCRIPTION: Mozilla Firefox is a free and open source web browser. 20 | SELF_SERVICE_ICON: "%NAME%.png" 21 | INSTALL_BUTTON_TEXT: "Install %version%" 22 | REINSTALL_BUTTON_TEXT: "Install %version%" 23 | UPDATE_PREDICATE: "pkg_uploaded == False" 24 | 25 | Process: 26 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfCategoryUploader 27 | Arguments: 28 | category_name: "%CATEGORY%" 29 | 30 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPackageUploader 31 | 32 | - Processor: StopProcessingIf 33 | Arguments: 34 | predicate: "%UPDATE_PREDICATE%" 35 | 36 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfComputerGroupUploader 37 | Arguments: 38 | computergroup_template: "%GROUP_TEMPLATE%" 39 | computergroup_name: "%GROUP_NAME%" 40 | 41 | - Processor: com.github.grahampugh.jamf-upload.processors/JamfPolicyUploader 42 | Arguments: 43 | policy_template: "%POLICY_TEMPLATE%" 44 | policy_name: "%POLICY_NAME%" 45 | icon: "%SELF_SERVICE_ICON%" 46 | -------------------------------------------------------------------------------- /_tests/api_test_pkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | : < 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | EVENT 7 | false 8 | false 9 | false 10 | false 11 | false 12 | false 13 | 14 | Ongoing 15 | 16 | %POLICY_CATEGORY% 17 | 18 | 19 | 20 | 21 | 22 | %GROUP_NAME% 23 | 24 | 25 | 26 | 27 | 28 | 1 29 | 41 | 42 | 43 | true 44 | %INSTALL_BUTTON_TEXT% 45 | %REINSTALL_BUTTON_TEXT% 46 | %SELF_SERVICE_DISPLAY_NAME% 47 | %SELF_SERVICE_DESCRIPTION% 48 | 49 | 50 | true 51 | 52 | 53 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfComputerGroupUploader.md: -------------------------------------------------------------------------------- 1 | # JamfComputerGroupUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a computer group (smart or static) to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **computergroup_name**: 25 | - **required**: False 26 | - **description**: Computer Group name 27 | - **computergroup_template**: 28 | - **required**: False 29 | - **description**: Path to Computer Group template file 30 | - **eplace_group**: 31 | - **required**: False 32 | - **description**: overwrite an existing Computer Group if True. 33 | - **default**: False 34 | - **sleep:** 35 | - **required:** False 36 | - **description:** Pause after running this processor for specified seconds. 37 | - **default:** "0" 38 | - **max_tries:** 39 | - **required:** False 40 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 41 | - **default:** "5" 42 | 43 | ## Output variables 44 | 45 | - **jamfcomputergroupuploader_summary_result:** 46 | - **description:** Description of interesting results. 47 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfCategoryUploader.md: -------------------------------------------------------------------------------- 1 | # JamfCategoryUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a category to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **category_name**: 25 | - **required**: False 26 | - **description**: Category 27 | - **category_priority**: 28 | - **required**: False 29 | - **description**: Category priority 30 | - **default**: 10 31 | - **replace_category**: 32 | - **required**: False 33 | - **description**: Overwrite an existing category if True. 34 | - **default**: False 35 | - **sleep:** 36 | - **required:** False 37 | - **description:** Pause after running this processor for specified seconds. 38 | - **default:** "0" 39 | - **max_tries:** 40 | - **required:** False 41 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 42 | - **default:** "5" 43 | 44 | ## Output variables 45 | 46 | - **category:** 47 | - **description:** The created/updated category. 48 | - **jamfcategoryuploader_summary_result:** 49 | - **description:** Description of interesting results. 50 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfMobileDeviceGroupUploader.md: -------------------------------------------------------------------------------- 1 | # JamfMobileDeviceUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a mobile device group (smart or static) to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **mobiledevice_name**: 25 | - **required**: False 26 | - **description**: Mobile Device Group name 27 | - **mobiledevice_template**: 28 | - **required**: False 29 | - **description**: Path to Mobile Device Group template file 30 | - **replace_group**: 31 | - **required**: False 32 | - **description**: overwrite an existing Mobile Device Group if True. 33 | - **default**: False 34 | - **sleep:** 35 | - **required:** False 36 | - **description:** Pause after running this processor for specified seconds. 37 | - **default:** "0" 38 | - **max_tries:** 39 | - **required:** False 40 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 41 | - **default:** "5" 42 | 43 | ## Output variables 44 | 45 | - **jamfmobiledeviceuploader_summary_result:** 46 | - **description:** Description of interesting results. 47 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfDockItemUploader.md: -------------------------------------------------------------------------------- 1 | # JamfDockItemUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a Dock item to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **dock_item_name**: 25 | - **required**: True 26 | - **description**: Dock Item name 27 | - **dock_item_type**: 28 | - **required**: True 29 | - **description**: Type of Dock Item - either 'App', 'File' or 'Folder' 30 | - **dock_item_path**: 31 | - **required**: True 32 | - **description**: Path of Dock Item - e.g. 'file:///Applications/Safari.app/' 33 | - **replace_dock_item**: 34 | - **required**: False 35 | - **description**: Overwrite an existing Dock Item if True. 36 | - **default**: False 37 | - **sleep:** 38 | - **required:** False 39 | - **description:** Pause after running this processor for specified seconds. 40 | - **default:** "0" 41 | - **max_tries:** 42 | - **required:** False 43 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 44 | - **default:** "5" 45 | 46 | ## Output variables 47 | 48 | - **jamfdockitemuploader_summary_result:** 49 | - **description:** Description of interesting results. 50 | -------------------------------------------------------------------------------- /_tests/templates/PatchTemplate-selfservice.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %patch_name% 5 | %PATCH_ENABLED% 6 | %version% 7 | selfservice 8 | false 9 | true 10 | 11 | 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Update 34 | 35 | 36 | %patch_icon_id% 37 | 38 | 39 | true 40 | Self Service and Notification Center 41 | Google Chrome update available 42 | 43 | 44 | true 45 | 1 46 | 47 | 48 | 49 | false 50 | 7 51 | 52 | 53 | %patch_softwaretitle_id% 54 | -------------------------------------------------------------------------------- /_tests/templates/MicrosoftAutoUpdate-notifications.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | NotificationSettings 9 | 10 | 11 | AlertType 12 | 1 13 | BadgesEnabled 14 | 15 | BundleIdentifier 16 | com.microsoft.autoupdate2 17 | CriticalAlertEnabled 18 | 19 | NotificationsEnabled 20 | 21 | PreviewType 22 | 1 23 | ShowInCarPlay 24 | 25 | ShowInLockScreen 26 | 27 | ShowInNotificationCenter 28 | 29 | SoundsEnabled 30 | 31 | 32 | 33 | PayloadDescription 34 | Enables notifications for Microsoft AutoUpdate 35 | PayloadDisplayName 36 | Notifications Payload 37 | PayloadIdentifier 38 | com.apple.notificationsettings.88D65FD9-1711-4EC4-9CE2-741668AC72C1 39 | PayloadType 40 | com.apple.notificationsettings 41 | PayloadUUID 42 | 88D65FD9-1711-4EC4-9CE2-741668AC72C1 43 | PayloadVersion 44 | 1 45 | 46 | 47 | PayloadDescription 48 | Enables notifications for Microsoft AutoUpdate 49 | PayloadDisplayName 50 | Microsoft AutoUpdate Notifications 51 | PayloadIdentifier 52 | 95f2b0ff-deda-4f63-a9fe-8c1093ec2c26 53 | PayloadOrganization 54 | Microsoft 55 | PayloadType 56 | Configuration 57 | PayloadUUID 58 | 95f2b0ff-deda-4f63-a9fe-8c1093ec2c26 59 | PayloadVersion 60 | 1 61 | 62 | 63 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfAPIRoleUploader.md: -------------------------------------------------------------------------------- 1 | # JamfAPIRoleUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will create or amend an API Role to a Jamf Pro server, with privileges supplied by a template json file. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **api_role_name:** 25 | - **required:** True 26 | - **description:** API Role name 27 | - **api_role_template:** 28 | - **required:** True 29 | - **description:** Full path to the JSON template 30 | - **replace_api_role:** 31 | - **required:** False 32 | - **description:** Overwrite an existing API Role if True. 33 | - **default:** False 34 | - **sleep:** 35 | - **required:** False 36 | - **description:** Pause after running this processor for specified seconds. 37 | - **default:** "0" 38 | - **max_tries:** 39 | - **required:** False 40 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 41 | - **default:** "5" 42 | 43 | ## Output variables 44 | 45 | - **jamfapiroleuploader_summary_result:** 46 | - **description:** Description of interesting results. 47 | - **api_role_name:** 48 | - **description:** API Role name. 49 | - **api_role_updated:** 50 | - **description:** Boolean - True if the API Role was changed. 51 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfUploaderTeamsNotifier.md: -------------------------------------------------------------------------------- 1 | # JamfUploaderTeamsNotifier 2 | 3 | ## Description 4 | 5 | A postprocessor for AutoPkg that will send details about a recipe run to a Microsoft Teams webhook based on the output of a JamfPolicyUploader process. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server. Used to display which JSS server the recipe was run against. 12 | - **POLICY_CATEGORY:** 13 | - **required:** False 14 | - **description:** Category for the created/updated policy. 15 | - **PKG_CATEGORY:** 16 | - **required:** False 17 | - **description:** Category for the created/updated pkg. 18 | - **NAME:** 19 | - **required:** True 20 | - **description:** Name of the application being created/updated. 21 | - **patch_name:** 22 | - **required:** False 23 | - **description:** Name of the Patch Policy being updated. 24 | - **pkg_name:** 25 | - **required:** False 26 | - **description:** File name of the pkg being uploaded. 27 | - **policy_name:** 28 | - **required:** False 29 | - **description:** The uploaded policy name. 30 | - **jamfpackageuploader_summary_result:** 31 | - **required:** False 32 | - **description:** Result of JamfPackageUploader. 33 | - **jamfpatchuploader_summary_result:** 34 | - **required:** False 35 | - **description:** Result of JamfPatchUploader. 36 | - **jamfpolicyuploader_summary_result:** 37 | - **required:** False 38 | - **description:** Result of JamfPolicyUploader. 39 | - **teams_webhook_url:** 40 | - **required:** True 41 | - **description:** Teams webhook URL to send the message to. 42 | - **teams_username:** 43 | - **required:** False 44 | - **description:** Sets the display name shown in the AdaptiveCard in Teams. Defaults to AutoPkg. 45 | - **teams_icon_url:** 46 | - **required:** False 47 | - **description:** Sets the icon shown in the AdaptiveCard in Teams. Defaults to a Jamf Pro product icon. Recommended that you use a square image that is publicly reachable. 48 | - **max_tries:** 49 | - **required:** False 50 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 51 | - **default:** "5" 52 | -------------------------------------------------------------------------------- /_tests/templates/MobileDeviceApp-noscope.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %mobiledeviceapp_name% 5 | %bundleid% 6 | %mobiledeviceapp_version% 7 | 8 | %CATEGORY% 9 | 10 | %itunes_store_url% 11 | true 12 | %DEPLOYMENT_TYPE% 13 | false 14 | true 15 | false 16 | false 17 | true 18 | false 19 | false 20 | false 21 | %mobiledeviceapp_free% 22 | true 23 | 24 | 25 | false 26 | 27 | 28 | 29 | 30 | 31 | 32 | Install 33 | 34 | %selfservice_icon_uri% 35 | 36 | false 37 | 38 | false 39 | 40 | 41 | 42 | 43 | 44 | true 45 | 3 46 | 47 | 48 | %appconfig% 49 | 50 | 51 | -------------------------------------------------------------------------------- /_tests/templates/PolicyTemplate-example-postinstall.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %POLICY_NAME% 5 | true 6 | Ongoing 7 | 8 | %CATEGORY% 9 | 10 | 11 | 12 | 13 | 14 | %GROUP_NAME% 15 | 16 | 17 | 18 | 19 | 20 | 21 | %EXCLUSION_GROUP_NAME% 22 | 23 | 24 | 25 | 26 | 27 | 28 | 1 29 | 30 | %pkg_name% 31 | Install 32 | 33 | 34 | 35 | 36 | 1 37 | 49 | 50 | 51 | true 52 | %SELF_SERVICE_INSTALL_BUTTON% 53 | %SELF_SERVICE_REINSTALL_BUTTON% 54 | %SELF_SERVICE_POLICY_NAME% 55 | %SELF_SERVICE_DESCRIPTION% 56 | 57 | 58 | 59 | false 60 | 61 | false 62 | 63 | 64 | false 65 | %POLICY_RUN_COMMAND% 66 | 67 | 68 | true 69 | 70 | 71 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfObjectStateChanger.md: -------------------------------------------------------------------------------- 1 | # JamfObjectStateChanger 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will change the state of an object on a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **object_name**: 25 | - **required**: False 26 | - **description**: The name of the API object 27 | - **object_type**: 28 | - **required**: True 29 | - **description**: The API object type. This is in the singular form - for Classic API endpoints this is the name of the key in the XML template. For JSON objects it is a construction made interally for this project. See the [Object Reference](./Object%20Reference.md) for valid objects. Valid values are `policy`, `computer_extension_attribute`, `app_installers_deployment`. Note that only script-based extension attributes may be enabled or disabled. 30 | - **default:** "policy" 31 | - **object_state:** 32 | - **required:** True 33 | - **description:** The desired state of the object, either `enable` or `disable`. 34 | - **default:** "disable" 35 | - **max_tries:** 36 | - **required:** False 37 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 38 | - **default:** "5" 39 | 40 | ## Output variables 41 | 42 | - **jamfobjectstatechanger_summary_result:** 43 | - **description:** Description of interesting results. 44 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfScopeAdjuster.md: -------------------------------------------------------------------------------- 1 | # JamfScopeAdjuster 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that adds or removes a scopeable object (target, limitation, or exclusion) to or from a Jamf API object. 6 | 7 | ## Input variables 8 | 9 | - **object_template:** 10 | - **required:** False 11 | - **description:** Full path of the object file to modify. 12 | - **raw_object:** 13 | - **required:** False 14 | - **description:** XML object string to modify. Used if `object_template` is not supplied, e.g., when taking input from `JamfObjectReader`. 15 | - **scoping_operation:** 16 | - **required:** True 17 | - **description:** Specify `add` or `remove`. 18 | - **scoping_type:** 19 | - **required:** True 20 | - **description:** Type of scope. Specify `target`, `limitation`, or `exclusion`. 21 | - **scopeable_type:** 22 | - **required:** True 23 | - **description:** Type of scopeable object. Specify `user_group`, `computer_group`, `mobile_device_group`, `network_segment`, `building`, or `department`. 24 | - **scopeable_name:** 25 | - **required:** True 26 | - **description:** Name of the scopable object. 27 | - **strict_mode:** 28 | - **required:** False 29 | - **description:** Raise a `ProcessorError` when adding a scopable object that already exists or removing one that does not exist in the raw object. If set to `False`, the processor continues without changing the raw object. Errors or oversights in specifying scopable object names may go unnoticed. 30 | - **default:** True 31 | - **strip_raw_xml:** 32 | - **required:** False 33 | - **description:** Strip all XML tags except for `scope`. Set to `True` if input is from a `JamfObjectReader` raw object, ensuring only the scope is written back to the Jamf API. Set to `False` if input is from an `object_template` file. 34 | - **default:** True 35 | - **output_dir:** 36 | - **required:** False 37 | - **description:** Directory to save the modified object file. Defaults to `RECIPE_CACHE_DIR`. 38 | 39 | ## Output variables 40 | 41 | - **object_template:** 42 | - **description:** Full path of the modified object file. Intended to be passed to `JamfObjectUploader`. 43 | - **raw_object:** 44 | - **description:** Raw processed XML object string. Can be used for chaining additional `JamfScopeAdjuster` processors. 45 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfAccountUploader.md: -------------------------------------------------------------------------------- 1 | # JamfAccountUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload an account to a Jamf Cloud or on-prem server, with privileges supplied by a template xml file. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **account_name:** 25 | - **required:** True 26 | - **description:** Account name 27 | - **account_type:** 28 | - **required:** True 29 | - **description:** Account type; "user" or "group" 30 | - **account_template:** 31 | - **required:** True 32 | - **description:** Full path to the XML template 33 | - **replace_account:** 34 | - **required:** False 35 | - **description:** Overwrite an existing account if True. 36 | - **default:** False 37 | - **sleep:** 38 | - **required:** False 39 | - **description:** Pause after running this processor for specified seconds. 40 | - **default:** "0" 41 | - **max_tries:** 42 | - **required:** False 43 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 44 | - **default:** "5" 45 | 46 | ## Output variables 47 | 48 | - **jamfaccountuploader_summary_result:** 49 | - **description:** Description of interesting results. 50 | - **account_name:** 51 | - **description:** Account name. 52 | - **account_updated:** 53 | - **description:** Boolean - True if the account was changed. 54 | - **changed_account_id:** 55 | - **description:** Jamf object ID of the newly created or modified account. 56 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfUploaderSlacker.md: -------------------------------------------------------------------------------- 1 | # JamfUploaderSlacker 2 | 3 | ## Description 4 | 5 | A postprocessor for AutoPkg that will send details about a recipe run to a Slack webhook based on the output of a JamfPolicyUploader process. 6 | 7 | Takes elements from [this gist](https://gist.github.com/devStepsize/b1b795309a217d24566dcc0ad136f784) and [Yo.py processor](https://github.com/autopkg/nmcspadden-recipes/blob/master/PostProcessors/Yo.py). 8 | 9 | ## Input variables 10 | 11 | - **JSS_URL:** 12 | - **required:** True 13 | - **description:** URL to a Jamf Pro server. Used to display which JSS server the recipe was run against. 14 | - **POLICY_CATEGORY:** 15 | - **required:** False 16 | - **description:** Category for the created/updated policy. 17 | - **PKG_CATEGORY:** 18 | - **required:** False 19 | - **description:** Category for the created/updated pkg. 20 | - **NAME:** 21 | - **required:** True 22 | - **description:** Name of the application being created/updated. 23 | - **pkg_name:** 24 | - **required:** False 25 | - **description:** File name of the pkg being uploaded. 26 | - **version:** 27 | - **required:** False 28 | - **description:** Package version. 29 | - **policy_name:** 30 | - **required:** False 31 | - **description:** The uploaded policy name. 32 | - **jamfpackageuploader_summary_result:** 33 | - **required:** False 34 | - **description:** Result of JamfPackageUploader. 35 | - **jamfpolicyuploader_summary_result:** 36 | - **required:** False 37 | - **description:** Result of JamfPolicyUploader. 38 | - **slack_webhook_url:** 39 | - **required:** True 40 | - **description:** Slack webhook URL to send the message to. 41 | - **slack_username:** 42 | - **required:** False 43 | - **description:** Sets the display name shown in the message in Slack. Defaults to AutoPkg. 44 | - **slack_icon_url:** 45 | - **required:** False 46 | - **description:** Sets the icon shown in the Slack notification. 47 | - **slack_channel:** 48 | - **required:** False 49 | - **description:** Slack channel (for overriding the default). 50 | - **slack_icon_emoji:** 51 | - **required:** False 52 | - **description:** Sets the icon shown in the Slack notification as an emoji. 53 | - **max_tries:** 54 | - **required:** False 55 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 56 | - **default:** "5" 57 | -------------------------------------------------------------------------------- /_Templates_Examples/SmartGroup-update-smart-MicrosoftOffice365.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %GROUP_NAME% 4 | true 5 | 6 | 7 | Application Title 8 | 0 9 | and 10 | is 11 | %JSS_INVENTORY_NAME% 12 | true 13 | false 14 | 15 | 16 | Application Version 17 | 1 18 | and 19 | matches regex 20 | %INSTALLED_REGEX_MATCH% 21 | false 22 | false 23 | 24 | 25 | Application Version 26 | 2 27 | and 28 | does not match regex 29 | %version_regex% 30 | false 31 | true 32 | 33 | 34 | Application Title 35 | 3 36 | or 37 | is 38 | %JSS_INVENTORY_NAME% 39 | true 40 | false 41 | 42 | 43 | Application Version 44 | 4 45 | and 46 | does not match regex 47 | %INSTALLED_REGEX_MATCH% 48 | false 49 | true 50 | 51 | 52 | Application Title 53 | 5 54 | or 55 | is not 56 | %JSS_INVENTORY_NAME% 57 | false 58 | false 59 | 60 | 61 | Computer Group 62 | 6 63 | and 64 | member of 65 | %TESTING_GROUP_NAME% 66 | false 67 | false 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfPatchChecker.md: -------------------------------------------------------------------------------- 1 | # JamfPatchChecker 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will check and report whether a Patch Software Title has the version that AutoPkg has found or not. This can be used with a subsequent `StopProcessingIf` processor to prevent updating a Patch Policy with a version that does not yet exist in the Patch Software Title, allowing the recipe to run again on a subsequent recipe run. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **patch_softwaretitle**: 25 | - **required**: True 26 | - **description**: Name of the patch softwaretitle (e.g. 'Mozilla Firefox') used in Jamf. You need to create the patch softwaretitle by hand, since there is currently no way to create these via the API. 27 | - **pkg_name**: 28 | - **required**: True 29 | - **description**: Name of package which should be used in the patch. Mostly provided by previous AutoPKG recipe/processor. 30 | - **version**: 31 | - **required**: True 32 | - **description**: Version string - provided by previous pkg recipe/processor. 33 | - **sleep:** 34 | - **required:** False 35 | - **description:** Pause after running this processor for specified seconds. 36 | - **default:** "0" 37 | - **max_tries:** 38 | - **required:** False 39 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 40 | - **default:** "5" 41 | 42 | ## Output variables 43 | 44 | - **jamfpatchuploader_summary_result:** 45 | - **description:** Description of interesting results. 46 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfPackageCleaner.md: -------------------------------------------------------------------------------- 1 | # JamfPackageCleaner 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will remove packages matching a pattern from a Jamf Cloud or on-prem server. Requires Package delete permissions. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **pkg_name_match**: 25 | - **required**: False 26 | - **description**: The name at the beginning of the package. This is used as a base for cleaning. If omitted, `%NAME%-`, e.g. `Google Chrome-`, or `%NAME%_`, e.g. =`Google Chrome_`, will be matched. 27 | - **versions_to_keep**: 28 | - **required**: False 29 | - **description**: The number of `pkg_name_match` values to keep in Jamf Pro. This is based on the package ID. 30 | - **default**: 3 31 | - **minimum_name_length**: 32 | - **required**: False 33 | - **description**: The minimum number of characters required in `pkg_name_match`. This is used as a failsafe. 34 | - **default**: 3 35 | - **maximum_allowed_packages_to_delete**: 36 | - **required**: False 37 | - **description**: The maximum number of packages that can be deleted. This is used as a failsafe. 38 | - **default**: 20 39 | - **dry_run**: 40 | - **required**: False 41 | - **description**: If set to True, nothing is deleted from Jamf Pro. Use together with `-vv` for detailed information. This is used for testing 42 | - **default**: False 43 | - **max_tries:** 44 | - **required:** False 45 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 46 | - **default:** "5" 47 | 48 | ## Output variables 49 | 50 | - **jamfpackagecleaner_summary_result:** 51 | - **description:** Description of interesting results. 52 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfMacAppUploader.md: -------------------------------------------------------------------------------- 1 | # JamfMacAppUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will update or clone a Mac App Store app object on a Jamf Pro server. A new one cannot be created. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **macapp_name:** 25 | - **required:** False 26 | - **description:** Mac App Store app name 27 | - **default:** "" 28 | - **clone_from:** 29 | - **required:** False 30 | - **description:** Mac App Store app name from which to clone this entry 31 | - **default:** "" 32 | - **selfservice_icon_uri:** 33 | - **required:** False 34 | - **description:** Mac App Store app icon URI 35 | - **default:** "" 36 | - **macapp_template:** 37 | - **required:** False 38 | - **description:** Full path to the XML template 39 | - **replace_macapp:** 40 | - **required:** False 41 | - **description:** Overwrite an existing Mac App Store app if True. 42 | - **default:** False 43 | - **sleep:** 44 | - **required:** False 45 | - **description:** Pause after running this processor for specified seconds. 46 | - **default:** "0" 47 | - **max_tries:** 48 | - **required:** False 49 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 50 | - **default:** "5" 51 | 52 | ## Output variables 53 | 54 | - **jamfmacappuploader_summary_result:** 55 | - **description:** Description of interesting results. 56 | - **macapp_name:** 57 | - **description:** Jamf object name of the newly created or modified macapp. 58 | - **macapp_updated:** 59 | - **description:** Boolean - True if the macapp was changed. 60 | - **changed_macapp_id:** 61 | - **description:** Jamf object ID of the newly created or modified macapp. 62 | -------------------------------------------------------------------------------- /_tests/templates/Account-User-fullaccess.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %account_name% 4 | false 5 | %ACCOUNT_FULLNAME% 6 | %ACCOUNT_EMAIL% 7 | %ACCOUNT_EMAIL% 8 | Enabled 9 | false 10 | Full Access 11 | Custom 12 | 13 | 14 | 15 | Create Categories 16 | Read Categories 17 | Update Categories 18 | Delete Categories 19 | Create Computer Extension Attributes 20 | Read Computer Extension Attributes 21 | Update Computer Extension Attributes 22 | Read Distribution Points 23 | Create Packages 24 | Read Packages 25 | Update Packages 26 | Create Policies 27 | Read Policies 28 | Update Policies 29 | Delete Policies 30 | Create Scripts 31 | Read Scripts 32 | Update Scripts 33 | Create Dock Items 34 | Read Dock Items 35 | Update Dock Items 36 | Create Smart Computer Groups 37 | Read Smart Computer Groups 38 | Update Smart Computer Groups 39 | Create Static Computer Groups 40 | Read Static Computer Groups 41 | Update Static Computer Groups 42 | Create macOS Configuration Profiles 43 | Read macOS Configuration Profiles 44 | Update macOS Configuration Profiles 45 | Create Mac Applications 46 | Read Mac Applications 47 | Update Mac Applications 48 | Read Volume Purchasing Administrator Accounts 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /_tests/templates/Kernel Extension Whitelist.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadUUID 6 | 40C19D5B-76D7-4C1C-BC9D-2F7EB29CFF4D 7 | PayloadType 8 | Configuration 9 | PayloadOrganization 10 | ETH Zürich 11 | PayloadIdentifier 12 | 40C19D5B-76D7-4C1C-BC9D-2F7EB29CFF4D 13 | PayloadDisplayName 14 | Approved Kernel Extensions 15 | PayloadDescription 16 | This profile configures your Mac to automatically enable third-party kernel extensions from specified vendors. 17 | PayloadVersion 18 | 1 19 | PayloadEnabled 20 | 21 | PayloadRemovalDisallowed 22 | 23 | PayloadScope 24 | System 25 | PayloadContent 26 | 27 | 28 | PayloadUUID 29 | 98D01A7B-ADC1-43C8-AB8E-8BDC25FCA3C9 30 | PayloadType 31 | com.apple.syspolicy.kernel-extension-policy 32 | PayloadOrganization 33 | ETH Zürich 34 | PayloadIdentifier 35 | 98D01A7B-ADC1-43C8-AB8E-8BDC25FCA3C9 36 | PayloadDisplayName 37 | Approved Kernel Extensions 38 | PayloadDescription 39 | 40 | PayloadVersion 41 | 1 42 | PayloadEnabled 43 | 44 | AllowUserOverrides 45 | 46 | AllowedTeamIdentifiers 47 | 48 | 2H5GFH3774 49 | DE8Y96K9QP 50 | KBVSJ83SS9 51 | 4C6364ACXT 52 | EG7KH642X6 53 | 94DN422U8R 54 | 6HB5Y2QTA3 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfPolicyUploader.md: -------------------------------------------------------------------------------- 1 | # JamfPolicyUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a policy to a Jamf Cloud or on-prem server. Optionally, an icon can be uploaded and associated with the policy. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **policy_name:** 25 | - **required:** True 26 | - **description:** Policy name 27 | - **icon:** 28 | - **required:** False 29 | - **description:** Full path to Self Service icon 30 | - **policy_template:** 31 | - **required:** True 32 | - **description:** Full path to the XML template 33 | - **replace_policy:** 34 | - **required:** False 35 | - **description:** Overwrite an existing policy if True. 36 | - **default:** False 37 | - **replace_icon:** 38 | - **required:** False 39 | - **description:** Overwrite an existing policy icon if True. 40 | - **default:** False 41 | - **retain_scope**: 42 | - **required**: False 43 | - **description**: retain the existing scope of an existing policy if True. 44 | - **default**: False 45 | - **sleep:** 46 | - **required:** False 47 | - **description:** Pause after running this processor for specified seconds. 48 | - **default:** "0" 49 | - **max_tries:** 50 | - **required:** False 51 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 52 | - **default:** "5" 53 | 54 | ## Output variables 55 | 56 | - **jamfpolicyuploader_summary_result:** 57 | - **description:** Description of interesting results. 58 | - **policy_name:** 59 | - **description:** Policy name. 60 | - **policy_updated:** 61 | - **description:** Boolean - True if the policy was changed. 62 | - **changed_policy_id:** 63 | - **description:** Jamf object ID of the newly created or modified policy. 64 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfUploaderJiraIssueCreator.md: -------------------------------------------------------------------------------- 1 | # JamfUploaderJiraIssueCreator 2 | 3 | ## Description 4 | 5 | A postprocessor for AutoPkg that will create a Jira issue based on the output of a JamfUploader process. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server. Used to display which JSS server the recipe was run against. 12 | - **POLICY_CATEGORY:** 13 | - **required:** False 14 | - **description:** Category for the created/updated policy. 15 | - **PKG_CATEGORY:** 16 | - **required:** False 17 | - **description:** Category for the created/updated pkg. 18 | - **NAME:** 19 | - **required:** True 20 | - **description:** Name of the application being created/updated. 21 | - **patch_name:** 22 | - **required:** False 23 | - **description:** Name of the Patch Policy being updated. 24 | - **pkg_name:** 25 | - **required:** False 26 | - **description:** File name of the pkg being uploaded. 27 | - **policy_name:** 28 | - **required:** False 29 | - **description:** The uploaded policy name. 30 | - **jamfpackageuploader_summary_result:** 31 | - **required:** False 32 | - **description:** Result of JamfPackageUploader. 33 | - **jamfpatchuploader_summary_result:** 34 | - **required:** False 35 | - **description:** Result of JamfPatchUploader. 36 | - **jamfpolicyuploader_summary_result:** 37 | - **required:** False 38 | - **description:** Result of JamfPolicyUploader. 39 | - **jira_url:** 40 | - **required:** True 41 | - **description:** Jira base URL to send the message to (e.g. - API endpoint not required). 42 | - **jira_product_id:** 43 | - **required:** True 44 | - **description:** Jira Product ID 45 | - **jira_username:** 46 | - **required:** True 47 | - **description:** Account name with access to Jira Issues. 48 | - **jira_api_token:** 49 | - **required:** True 50 | - **description:** API Token created in the account supplied in jira_username. 51 | - **jira_issuetype_id:** 52 | - **required:** False 53 | - **description:** Jira Issue Type. Default is 10001 ('Story'). See . 54 | - **default:** 10001 55 | - **jira_priority_id:** 56 | - **required:** False 57 | - **description:** Jira Priority. Default is 5 (the lowest priority). See . 58 | - **default:** 5 59 | - **max_tries:** 60 | - **required:** False 61 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 62 | - **default:** "5" 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .slackrc 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | pip-wheel-metadata/ 25 | share/python-wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | .python-version 87 | 88 | # pipenv 89 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 90 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 91 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 92 | # install all needed dependencies. 93 | #Pipfile.lock 94 | 95 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 96 | __pypackages__/ 97 | 98 | # Celery stuff 99 | celerybeat-schedule 100 | celerybeat.pid 101 | 102 | # SageMath parsed files 103 | *.sage.py 104 | 105 | # Environments 106 | .env 107 | .venv 108 | env/ 109 | venv/ 110 | ENV/ 111 | env.bak/ 112 | venv.bak/ 113 | 114 | # Spyder project settings 115 | .spyderproject 116 | .spyproject 117 | 118 | # Rope project settings 119 | .ropeproject 120 | 121 | # mkdocs documentation 122 | /site 123 | 124 | # mypy 125 | .mypy_cache/ 126 | .dmypy.json 127 | dmypy.json 128 | 129 | # Pyre type checker 130 | .pyre/ 131 | 132 | # Mac artefacts 133 | .DS_Store 134 | 135 | # Visual Studio Code settings 136 | .vscode/ 137 | 138 | # temporary ignore for prospective projects 139 | jamf_signed_computerprofile_upload.py 140 | jira-creds.txt 141 | jira-creds.sh 142 | 143 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfPatchUploader.md: -------------------------------------------------------------------------------- 1 | # JamfPatchUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a Patch Policy to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **patch_softwaretitle**: 25 | - **required**: True 26 | - **description**: Name of the patch softwaretitle (e.g. 'Mozilla Firefox') used in Jamf. You need to create the patch softwaretitle by hand, since there is currently no way to create these via the API. 27 | - **patch_name**: 28 | - **required**: False 29 | - **description**: Name of the patch policy (e.g. 'Mozilla Firefox - 93.02.10'). 30 | - **default**: '%patch_softwaretitle% - %version%' 31 | - **patch_template**: 32 | - **required**: False 33 | - **description**: XML-Template used for the patch policy. If none is provided, only the installer will be linked to the corresponding version and no patch policy will be created. 34 | - **patch_icon_policy_name**: 35 | - **required**: False 36 | - **description**: Name of an already existing (!) policy (not a patch policy). The icon of this policy will be extracted and can be used in the patch template with the variable `%patch_icon_id%`. There is currently no reasonable way to upload a custom icon for patch policies. 37 | - **replace_patch**: 38 | - **required**: False 39 | - **description**: Overwrite an existing patch policy if True. 40 | - **default**: False 41 | - **sleep:** 42 | - **required:** False 43 | - **description:** Pause after running this processor for specified seconds. 44 | - **default:** "0" 45 | - **max_tries:** 46 | - **required:** False 47 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 48 | - **default:** "5" 49 | 50 | ## Output variables 51 | 52 | - **jamfpatchuploader_summary_result:** 53 | - **description:** Description of interesting results. 54 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfMSUPlanUploader.md: -------------------------------------------------------------------------------- 1 | # JamfObjectUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will create a Managed Software Update Plan. Currently restricted to the DOWNLOAD_INSTALL_SCHEDULE plan type (the only DDM plan available in Jamf Pro). 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **device_type**: 25 | - **required**: True 26 | - **description**: Device type, must be one of 'computer', 'mobile-device', 'apple-tv' (case-insensitive). 27 | - **group_name**: 28 | - **required**: True 29 | - **description**: Name of the target computer group or mobile device group. 30 | - **version**: 31 | - **required**: False 32 | - **description**: OS Version to deploy, must be one of 'latest-minor', 'latest-major', 'latest-any', or a valid specific version string for the OS to be applied. 33 | - **days_until_force_install**: 34 | - **required**: False 35 | - **description**: Days until forced installation of planned managed software update. 36 | - **default**: 7 37 | - **sleep:** 38 | - **required:** False 39 | - **description:** Pause after running this processor for specified seconds. 40 | - **default:** "0" 41 | - **max_tries:** 42 | - **required:** False 43 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 44 | - **default:** "5" 45 | 46 | ## Output variables 47 | 48 | - **jamfmsuplanuploader_summary_result:** 49 | - **description:** Description of interesting results. 50 | - **device_type**: 51 | - **description**: Device type. 52 | - **version_type**: 53 | - **description**: Version type, one of 'latest_minor', 'latest_major', 'latest_any', or 'specific_version'. 54 | - **specific_version**: 55 | - **description**: Specific version, if 'version_type' is set to 'specific_version'. 56 | - **object_updated**: 57 | - **description**: The date and time of the plan's forced installation deadline. 58 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfAPIClientUploader.md: -------------------------------------------------------------------------------- 1 | # JamfAPIRoleUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will create or amend an API Client to a Jamf Pro server. Only one API Role can be given to each API Client using this processor. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **api_client_name:** 25 | - **required:** True 26 | - **description:** API Client name. 27 | - **api_client_id:** 28 | - **required:** False 29 | - **description:** API Client ID. 30 | - **api_role_name:** 31 | - **required:** True 32 | - **description:** API Role name that will be assigned to this API Client. Only one API Role can be given to each API Client using this processor. 33 | - **access_token_lifetime:** 34 | - **required:** False 35 | - **description:** Access Token lifetime in seconds. 36 | - **default:** "300" 37 | - **api_client_enabled:** 38 | - **required:** False 39 | - **description:** Set the API Client to enabled if True 40 | - **default:** False 41 | - **replace_api_client:** 42 | - **required:** False 43 | - **description:** Overwrite an existing API Role if True. 44 | - **default:** False 45 | - **sleep:** 46 | - **required:** False 47 | - **description:** Pause after running this processor for specified seconds. 48 | - **default:** "0" 49 | - **max_tries:** 50 | - **required:** False 51 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 52 | - **default:** "5" 53 | 54 | ## Output variables 55 | 56 | - **jamfapiclientuploader_summary_result:** 57 | - **description:** Description of interesting results. 58 | - **api_client_name:** 59 | - **description:** API Client name. 60 | - **api_client_id:** 61 | - **description:** API Client ID. 62 | - **api_client_secret:** 63 | - **description:** API Client Secret. 64 | - **api_client_updated:** 65 | - **description:** Boolean - True if the API Client was changed. 66 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfMobileDeviceAppUploader.md: -------------------------------------------------------------------------------- 1 | # JamfMobileDeviceAppUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will update or clone a Mobile Device app object on a Jamf Pro server. A new one cannot be created. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **mobiledeviceapp_name:** 25 | - **required:** False 26 | - **description:** Mobile Device app name 27 | - **default:** "" 28 | - **clone_from:** 29 | - **required:** False 30 | - **description:** Mobile Device app name from which to clone this entry 31 | - **default:** "" 32 | - **selfservice_icon_uri:** 33 | - **required:** False 34 | - **description:** Mobile Device app icon URI 35 | - **default:** "" 36 | - **mobiledeviceapp_template:** 37 | - **required:** False 38 | - **description:** Full path to the XML template 39 | - **appconfig_template:** 40 | - **required:** False 41 | - **description:** Full path to the AppConfig XML template 42 | - **replace_mobiledeviceapp:** 43 | - **required:** False 44 | - **description:** Overwrite an existing Mobile Device app if True. 45 | - **default:** False 46 | - **sleep:** 47 | - **required:** False 48 | - **description:** Pause after running this processor for specified seconds. 49 | - **default:** "0" 50 | - **max_tries:** 51 | - **required:** False 52 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 53 | - **default:** "5" 54 | 55 | ## Output variables 56 | 57 | - **jamfmobiledeviceappuploader_summary_result:** 58 | - **description:** Description of interesting results. 59 | - **mobiledeviceapp_name:** 60 | - **description:** Jamf object name of the newly created or modified mobiledeviceapp. 61 | - **mobiledeviceapp_updated:** 62 | - **description:** Boolean - True if the mobiledeviceapp was changed. 63 | - **changed_mobiledeviceapp_id:** 64 | - **description:** Jamf object ID of the newly created or modified mobiledeviceapp. 65 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfMobileDeviceProfileUploader.md: -------------------------------------------------------------------------------- 1 | # JamfMobileDeviceProfileUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a mobile device configuration profile to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **profile_name**: 25 | - **required**: False 26 | - **description**: Configuration Profile name 27 | - **mobileconfig**: 28 | - **required**: False 29 | - **description**: Path to Configuration Profile mobileconfig file 30 | - **identifier**: 31 | - **required**: False 32 | - **description**: Configuration Profile payload identifier 33 | - **profile_template**: 34 | - **required**: False 35 | - **description**: Path to Configuration Profile XML template file 36 | - **profile_category**: 37 | - **required**: False 38 | - **description**: a category to assign to the profile 39 | - **organization**: 40 | - **required**: False 41 | - **description**: Organization to assign to the profile 42 | - **profile_description**: 43 | - **required**: False 44 | - **description**: a description to assign to the profile 45 | - **profile_mobiledevicegroup**: 46 | - **required**: False 47 | - **description**: a mobile device group that will be scoped to the profile 48 | - **unsign_profile**: 49 | - **required**: False 50 | - **description**: Unsign a mobileconfig file prior to uploading if it is signed, if true. 51 | - **default**: False 52 | - **replace_profile**: 53 | - **required**: False 54 | - **description**: overwrite an existing Configuration Profile if True. 55 | - **default**: False 56 | - **sleep:** 57 | - **required:** False 58 | - **description:** Pause after running this processor for specified seconds. 59 | - **default:** "0" 60 | - **max_tries:** 61 | - **required:** False 62 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 63 | - **default:** "5" 64 | 65 | ## Output variables 66 | 67 | - **jamfmobiledeviceprofileuploader_summary_result:** 68 | - **description:** Description of interesting results. 69 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfMobileDeviceExtensionAttributeUploader.md: -------------------------------------------------------------------------------- 1 | # JamfMobileDeviceExtensionAttributeUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a Mobile Device Extension Attribute item to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **ea_name**: 25 | - **required**: False 26 | - **description**: Mobile Device Extension Attribute name 27 | - **replace_ea**: 28 | - **required**: False 29 | - **description**: Overwrite an existing Mobile Device Extension Attribute if True. 30 | - **default**: False 31 | - **ea_inventory_display:** 32 | - **required:** False 33 | - **description:** Inventory Display value for the Mobile Device Extension Attribute. 34 | - **default:** "Extension Attributes" 35 | - **ea_data_type:** 36 | - **required:** False 37 | - **description:** Data type for the Mobile Device Extension Attribute. One of String, Integer or Date. 38 | - **default:** "String" 39 | - **ea_popup_choices:** 40 | - **required:** False 41 | - **description:** Comma-separated list of popup choices for the Mobile Device Extension Attribute. 42 | - **ea_input_type:** 43 | - **required:** False 44 | - **description:** Type of Mobile Device Extension Attribute. One of popup, text, or ldap. 45 | - **default:** "text" 46 | - **ea_description:** 47 | - **required:** False 48 | - **description:** Description for the Mobile Device Extension Attribute. 49 | - **ea_directory_service_attribute_mapping:** 50 | - **required:** False 51 | - **description:** Directory Service (LDAP) attribute mapping. Currently this must be manually set. 52 | - **sleep:** 53 | - **required:** False 54 | - **description:** Pause after running this processor for specified seconds. 55 | - **default:** "0" 56 | - **max_tries:** 57 | - **required:** False 58 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 59 | - **default:** "5" 60 | 61 | ## Output variables 62 | 63 | - **jamfmobiledeviceextensionattributeuploader_summary_result:** 64 | - **description:** Description of interesting results. 65 | -------------------------------------------------------------------------------- /Jamf_Helper_Recipes/APIRole-AutoPkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "%API_ROLE_NAME%", 3 | "privileges": [ 4 | "Delete Patch Management Software Titles", 5 | "Read Dock Items", 6 | "Delete Static Computer Groups", 7 | "Update iOS Configuration Profiles", 8 | "Read API Integrations", 9 | "Create Computer Extension Attributes", 10 | "Update Computer Extension Attributes", 11 | "Read macOS Configuration Profiles", 12 | "Read Patch Management Software Titles", 13 | "Create Mac Applications", 14 | "Read Scripts", 15 | "Update Mobile Device Applications", 16 | "Update Engage Settings", 17 | "Read Mobile Device Applications", 18 | "Delete Packages", 19 | "Create Patch Policies", 20 | "Read Patch Policies", 21 | "Read Smart Computer Groups", 22 | "Update Mac Applications", 23 | "Create Patch Management Software Titles", 24 | "Create iOS Configuration Profiles", 25 | "Read Packages", 26 | "Create Policies", 27 | "Read Computer Extension Attributes", 28 | "Update Policies", 29 | "Update Packages", 30 | "Update Patch Management Software Titles", 31 | "Read iOS Configuration Profiles", 32 | "Update Static Computer Groups", 33 | "Create Mobile Device Applications", 34 | "Delete Patch Policies", 35 | "Update Static Mobile Device Groups", 36 | "Update Categories", 37 | "Read Static Computer Groups", 38 | "Read API Roles", 39 | "Read Re-enrollment", 40 | "Update Scripts", 41 | "Update API Integrations", 42 | "Create Static Mobile Device Groups", 43 | "Read Mac Applications", 44 | "Delete Scripts", 45 | "Create API Roles", 46 | "Update API Roles", 47 | "Read Mobile Device Extension Attributes", 48 | "Read Engage Settings", 49 | "Update Smart Computer Groups", 50 | "Create macOS Configuration Profiles", 51 | "Create Smart Computer Groups", 52 | "Delete Mobile Device Extension Attributes", 53 | "Update Enrollment Profiles", 54 | "Delete Static Mobile Device Groups", 55 | "Create Smart Mobile Device Groups", 56 | "Delete Smart Computer Groups", 57 | "Read Static Mobile Device Groups", 58 | "Delete Policies", 59 | "Create Static Computer Groups", 60 | "Read Categories", 61 | "Update Patch Policies", 62 | "Update Mobile Device Extension Attributes", 63 | "Create Packages", 64 | "Create Categories", 65 | "Update macOS Configuration Profiles", 66 | "Create API Integrations", 67 | "Update Smart Mobile Device Groups", 68 | "Read Smart Mobile Device Groups", 69 | "Create Dock Items", 70 | "Update Re-enrollment", 71 | "Create Scripts", 72 | "Delete Smart Mobile Device Groups", 73 | "Read Policies", 74 | "Update Dock Items", 75 | "Create Mobile Device Extension Attributes" 76 | ] 77 | } -------------------------------------------------------------------------------- /_tests/templates/LDAPServerTemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %NAME% 5 | %HOSTNAME% 6 | Active Directory 7 | 636 8 | true 9 | simple 10 | %Base64EncodedCertificateData% 11 | 12 | %DOMAIN_ACCOUNT_DN% 13 | %DOMAIN_ACCOUNT_PW% 14 | 15 | 15 16 | 60 17 | true 18 | 19 | 20 | 21 | all 22 | organizationalPerson, user 23 | %USERS_SEARCH_BASE% 24 | All Subtrees 25 | uSNCreated 26 | sAMAccountName 27 | displayName 28 | mail 29 | 30 | 31 | 32 | 33 | 34 | 35 | objectGUID 36 | 37 | 38 | all 39 | top, group 40 | %GROUPS_SEARCH_BASE% 41 | All Subtrees 42 | uSNCreated 43 | name 44 | objectGUID 45 | 46 | 47 | user object 48 | memberOf 49 | 50 | true 51 | true 52 | 53 | false 54 | all 55 | 56 | 57 | All Subtrees 58 | 59 | 60 | true 61 | 62 | 63 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfSoftwareRestrictionUploader.md: -------------------------------------------------------------------------------- 1 | # JamfSoftwareRestrictionUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a restricted software record to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **restriction_name**: 25 | - **required**: False 26 | - **description**: Software Restriction name 27 | - **restriction_template**: 28 | - **required**: False 29 | - **description**: Path to Software Restriction XML template file 30 | - **restriction_computergroup**: 31 | - **required**: False 32 | - **description**: A single computer group to add to the scope. 33 | - **process_name**: 34 | - **required**: False 35 | - **description**: Process name to restrict. 36 | - **display_message**: 37 | - **required**: False 38 | - **description**: Message to display to users when the restriction is invoked. 39 | - **match_exact_process_name**: 40 | - **required**: False 41 | - **description**: Match only the exact process name if True. 42 | - **default**: False 43 | - **restriction_send_notification**: 44 | - **required**: False 45 | - **description**: Send a notification when the restriction is invoked if True. 46 | - **default**: False 47 | - **kill_process**: 48 | - **required**: False 49 | - **description**: Kill the process when the restriction is invoked if True. 50 | - **default**: False 51 | - **delete_executable**: 52 | - **required**: False 53 | - **description**: Delete the executable when the restriction is invoked if True. 54 | - **default**: False 55 | - **replace_restriction**: 56 | - **required**: False 57 | - **description**: Overwrite an existing Software Restriction if True. 58 | - **default**: False 59 | - **sleep:** 60 | - **required:** False 61 | - **description:** Pause after running this processor for specified seconds. 62 | - **default:** "0" 63 | - **max_tries:** 64 | - **required:** False 65 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 66 | - **default:** "5" 67 | 68 | ## Output variables 69 | 70 | - **jamfsoftwarerestrictionuploader_summary_result:** 71 | - **description:** Description of interesting results. 72 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/JamfPackageRecalculator.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/autopkg/python 2 | 3 | """ 4 | Copyright 2023 Graham Pugh, Henrik Engström 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | NOTES: 19 | This processor was written by Henrik Engström based on other JamfUploader processors 20 | All functions are in JamfUploaderLib/JamfPackageCleanerBase.py 21 | """ 22 | 23 | import os.path 24 | import sys 25 | 26 | # to use a base module in AutoPkg we need to add this path to the sys.path. 27 | # this violates flake8 E402 (PEP8 imports) but is unavoidable, so the following 28 | # imports require noqa comments for E402 29 | sys.path.insert(0, os.path.dirname(__file__)) 30 | 31 | from JamfUploaderLib.JamfPackageRecalculatorBase import ( # noqa: E402 32 | JamfPackageRecalculatorBase, 33 | ) 34 | 35 | __all__ = ["JamfPackageRecalculator"] 36 | 37 | 38 | class JamfPackageRecalculator(JamfPackageRecalculatorBase): 39 | description = ( 40 | "A processor for AutoPkg that will force a recalculation of packages on a JCDS" 41 | ) 42 | 43 | input_variables = { 44 | "JSS_URL": { 45 | "required": True, 46 | "description": "URL to a Jamf Pro server that the API user has write access to.", 47 | }, 48 | "API_USERNAME": { 49 | "required": False, 50 | "description": "Username of account with appropriate access to " 51 | "jss, optionally set as a key in the com.github.autopkg " 52 | "preference file.", 53 | }, 54 | "API_PASSWORD": { 55 | "required": False, 56 | "description": "Password of api user, optionally set as a key in " 57 | "the com.github.autopkg preference file.", 58 | }, 59 | "CLIENT_ID": { 60 | "required": False, 61 | "description": "Client ID with access to " 62 | "jss, optionally set as a key in the com.github.autopkg " 63 | "preference file.", 64 | }, 65 | "CLIENT_SECRET": { 66 | "required": False, 67 | "description": "Secret associated with the Client ID, optionally set as a key in " 68 | "the com.github.autopkg preference file.", 69 | }, 70 | } 71 | 72 | output_variables = { 73 | "jamfpackagerecalculator_summary_result": { 74 | "description": "Description of interesting results.", 75 | } 76 | } 77 | 78 | def main(self): 79 | """Run the execute function""" 80 | 81 | self.execute() 82 | 83 | 84 | if __name__ == "__main__": 85 | PROCESSOR = JamfPackageRecalculator() 86 | PROCESSOR.execute_shell() 87 | -------------------------------------------------------------------------------- /_tests/pkg_upload.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | A script to upload a package to the Jamf Cloud Distribution Point S3 bucket (JCDS 2.0) 5 | 6 | Requirements from pip 7 | boto3 8 | requests 9 | """ 10 | 11 | import boto3 12 | from botocore.exceptions import ClientError 13 | import os.path 14 | import requests 15 | from requests.exceptions import HTTPError 16 | import sys 17 | import threading 18 | 19 | 20 | # REQUIRED AUTHENTICATION VARIABLES 21 | jamfProUser = "" 22 | jamfProPassword = "" 23 | jamfProBaseURL = "" 24 | 25 | # path to package - UPDATE AS APPROPRIATE 26 | pkg_path = os.path.join( 27 | "/Users/gpugh/sourcecode", 28 | "erase-install/pkg/erase-install/build/erase-install-30.0.pkg", 29 | ) 30 | 31 | 32 | class ProgressPercentage(object): 33 | """display upload progress""" 34 | 35 | def __init__(self, filename): 36 | self._filename = filename 37 | self._size = float(os.path.getsize(filename)) 38 | self._seen_so_far = 0 39 | self._lock = threading.Lock() 40 | 41 | def __call__(self, bytes_amount): 42 | # To simplify, assume this is hooked up to a single filename 43 | with self._lock: 44 | self._seen_so_far += bytes_amount 45 | percentage = (self._seen_so_far / self._size) * 100 46 | sys.stdout.write( 47 | "\r%s %s / %s (%.2f%%)" 48 | % (self._filename, self._seen_so_far, self._size, percentage) 49 | ) 50 | sys.stdout.flush() 51 | 52 | 53 | try: 54 | pkg = os.path.basename(pkg_path) 55 | 56 | response = requests.post( 57 | jamfProBaseURL + "/api/v1/auth/token", 58 | auth=(jamfProUser, jamfProPassword), 59 | data="", 60 | ) 61 | response.raise_for_status() 62 | 63 | jsonResponse = response.json() 64 | print("Retreived Token: ") 65 | jamfProToken = jsonResponse["token"] 66 | print(jamfProToken) 67 | 68 | # Initiate Upload via Jamf Pro API 69 | headers = {"Accept": "application/json", "Authorization": "Bearer " + jamfProToken} 70 | 71 | print(headers) 72 | 73 | response = requests.post( 74 | jamfProBaseURL + "/api/v1/jcds/files", headers=headers, data="" 75 | ) 76 | response.raise_for_status() 77 | 78 | credentials = response.json() 79 | print("Retreived Credentials Object: ") 80 | print(credentials) 81 | 82 | 83 | except HTTPError as http_err: 84 | print(f"HTTP error occurred: {http_err}") 85 | except Exception as err: 86 | print(f"Other error occurred: {err}") 87 | 88 | 89 | # Upload File To AWS S3 90 | s3_client = boto3.client( 91 | "s3", 92 | aws_access_key_id=credentials["accessKeyID"], 93 | aws_secret_access_key=credentials["secretAccessKey"], 94 | aws_session_token=credentials["sessionToken"], 95 | ) 96 | try: 97 | response = s3_client.upload_file( 98 | pkg_path, 99 | credentials["bucketName"], 100 | credentials["path"] + pkg, 101 | Callback=ProgressPercentage(pkg_path), 102 | ) 103 | print(response) 104 | except ClientError as e: 105 | print(f"Failure uploading to S3: {e}") 106 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfExtensionAttributeUploader.md: -------------------------------------------------------------------------------- 1 | # JamfExtensionAttributeUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload an Extension Attribute item to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **ea_name**: 25 | - **required**: False 26 | - **description**: Extension Attribute name 27 | - **ea_script_path**: 28 | - **required**: False 29 | - **description**: Full path to the script to be uploaded 30 | - **replace_ea**: 31 | - **required**: False 32 | - **description**: Overwrite an existing Extension Attribute if True. 33 | - **default**: False 34 | - **ea_inventory_display:** 35 | - **required:** False 36 | - **description:** Inventory Display value for the EA. 37 | - **default:** "Extension Attributes" 38 | - **ea_data_type:** 39 | - **required:** False 40 | - **description:** Data type for the EA. One of String, Integer or Date. 41 | - **default:** "String" 42 | - **ea_popup_choices:** 43 | - **required:** False 44 | - **description:** Comma-separated list of popup choices for the EA. 45 | - **ea_input_type:** 46 | - **required:** False 47 | - **description:** Type of EA. One of script, popup, text, or ldap. 48 | - **ea_description:** 49 | - **required:** False 50 | - **description:** Description for the EA. 51 | - **ea_directory_service_attribute_mapping:** 52 | - **required:** False 53 | - **description:** Directory Service (LDAP) attribute mapping. Currently this must be manually set. 54 | - **ea_enabled:** 55 | - **required:** False 56 | - **description:** String-based EAs can be disabled. 57 | - **default:** True 58 | - **skip_script_key_substitution**: 59 | - **required**: False 60 | - **description**: Skip substitution of keys marked between `%` signs in the script. 61 | - **default**: False 62 | - **sleep:** 63 | - **required:** False 64 | - **description:** Pause after running this processor for specified seconds. 65 | - **default:** "0" 66 | - **max_tries:** 67 | - **required:** False 68 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 69 | - **default:** "5" 70 | 71 | ## Output variables 72 | 73 | - **jamfextensionattributeuploader_summary_result:** 74 | - **description:** Description of interesting results. 75 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfComputerProfileUploader.md: -------------------------------------------------------------------------------- 1 | # JamfComputerProfileUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a computer configuration profile to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **profile_name**: 25 | - **required**: False 26 | - **description**: Configuration Profile name 27 | - **payload**: 28 | - **required**: False 29 | - **description**: Path to Configuration Profile payload plist file 30 | - **mobileconfig**: 31 | - **required**: False 32 | - **description**: Path to Configuration Profile mobileconfig file 33 | - **identifier**: 34 | - **required**: False 35 | - **description**: Configuration Profile payload identifier 36 | - **profile_template**: 37 | - **required**: False 38 | - **description**: Path to Configuration Profile XML template file 39 | - **profile_category**: 40 | - **required**: False 41 | - **description**: a category to assign to the profile 42 | - **organization**: 43 | - **required**: False 44 | - **description**: Organization to assign to the profile 45 | - **profile_description**: 46 | - **required**: False 47 | - **description**: a description to assign to the profile 48 | - **profile_computergroup**: 49 | - **required**: False 50 | - **description**: a computer group that will be scoped to the profile 51 | - **unsign_profile**: 52 | - **required**: False 53 | - **description**: Unsign a mobileconfig file prior to uploading if it is signed, if true. 54 | - **default**: False 55 | - **replace_profile**: 56 | - **required**: False 57 | - **description**: overwrite an existing Configuration Profile if True. 58 | - **default**: False 59 | - **retain_scope**: 60 | - **required**: False 61 | - **description**: retain the existing scope of an existing Configuration Profile if True. 62 | - **default**: False 63 | - **sleep:** 64 | - **required:** False 65 | - **description:** Pause after running this processor for specified seconds. 66 | - **default:** "0" 67 | - **max_tries:** 68 | - **required:** False 69 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 70 | - **default:** "5" 71 | 72 | ## Output variables 73 | 74 | - **jamfcomputerprofileuploader_summary_result:** 75 | - **description:** Description of interesting results. 76 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfObjectUploader.md: -------------------------------------------------------------------------------- 1 | # JamfObjectUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload various Classic API or Jamf Pro API objects to a Jamf Cloud or on-prem server. To be used when no specific processor is available for the required object type. Note that many objects may not work due to exceptions to the API object from "standard" - test first! 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **object_name**: 25 | - **required**: False 26 | - **description**: The name of the API object 27 | - **object_template**: 28 | - **required**: True 29 | - **description**: Path to the API object template file. For Classic API endpoints this must be XML, for Jamf Pro API endpoints this must be JSON. 30 | - **object_type**: 31 | - **required**: True 32 | - **description**: The API object type. This is in the singular form - for Classic API endpoints this is the name of the key in the XML template. For JSON objects it is a construction made interally for this project. See the [Object Reference](./Object%20Reference.md) for valid objects. 33 | - **elements_to_remove**: 34 | - **required**: False 35 | - **description**: A list of XML or JSON elements that should be removed from the downloaded XML. Note that `id` and `self_service_icon` are removed automatically. 36 | - **replace_object**: 37 | - **required**: False 38 | - **description**: overwrite an existing Computer Group if True. 39 | - **default**: False 40 | - **sleep:** 41 | - **required:** False 42 | - **description:** Pause after running this processor for specified seconds. 43 | - **default:** "0" 44 | - **max_tries:** 45 | - **required:** False 46 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 47 | - **default:** "5" 48 | 49 | ## Output variables 50 | 51 | - **jamfobjectuploader_summary_result:** 52 | - **description:** Description of interesting results. 53 | - **object_name**: 54 | - **description**: The name of the API object 55 | - **object_type**: 56 | - **description**: This is in the singular form - for Classic API endpoints this is the name of the key in the XML template. For JSON objects it is a construction made interally for this project. See the [Object Reference](./Object%20Reference.md) for valid objects. 57 | - **object_updated**: 58 | - **description**: Boolean - True if the object was changed. 59 | -------------------------------------------------------------------------------- /_tests/templates/computer-prestage-example-account.json: -------------------------------------------------------------------------------- 1 | { 2 | "keepExistingSiteMembership": false, 3 | "displayName": "%NAME%", 4 | "supportPhoneNumber": "", 5 | "supportEmailAddress": "", 6 | "department": "", 7 | "mandatory": true, 8 | "mdmRemovable": false, 9 | "defaultPrestage": false, 10 | "keepExistingLocationInformation": false, 11 | "requireAuthentication": false, 12 | "authenticationPrompt": "", 13 | "profileUuid": "", 14 | "deviceEnrollmentProgramInstanceId": "1", 15 | "versionLock": 8, 16 | "siteId": "-1", 17 | "skipSetupItems": { 18 | "Biometric": false, 19 | "TermsOfAddress": true, 20 | "FileVault": false, 21 | "iCloudDiagnostics": true, 22 | "Diagnostics": true, 23 | "Accessibility": false, 24 | "Intelligence": true, 25 | "AppleID": true, 26 | "ScreenTime": true, 27 | "Siri": true, 28 | "DisplayTone": true, 29 | "Restore": true, 30 | "Appearance": false, 31 | "Privacy": true, 32 | "Payment": true, 33 | "Registration": true, 34 | "TOS": true, 35 | "EnableLockdownMode": true, 36 | "Welcome": false, 37 | "Wallpaper": true, 38 | "iCloudStorage": true, 39 | "Location": false 40 | }, 41 | "locationInformation": { 42 | "username": "", 43 | "realname": "", 44 | "phone": "", 45 | "email": "", 46 | "room": "", 47 | "position": "", 48 | "departmentId": "-1", 49 | "buildingId": "-1", 50 | "id": "-1", 51 | "versionLock": 0 52 | }, 53 | "purchasingInformation": { 54 | "id": "-1", 55 | "leased": false, 56 | "purchased": true, 57 | "appleCareId": "", 58 | "poNumber": "", 59 | "vendor": "", 60 | "purchasePrice": "", 61 | "lifeExpectancy": 0, 62 | "purchasingAccount": "", 63 | "purchasingContact": "", 64 | "leaseDate": "1970-01-01", 65 | "poDate": "1970-01-01", 66 | "warrantyDate": "1970-01-01", 67 | "versionLock": 0 68 | }, 69 | "preventActivationLock": true, 70 | "enableDeviceBasedActivationLock": false, 71 | "anchorCertificates": [], 72 | "enrollmentCustomizationId": "0", 73 | "language": "", 74 | "region": "", 75 | "autoAdvanceSetup": false, 76 | "customPackageIds": [], 77 | "customPackageDistributionPointId": "-1", 78 | "installProfilesDuringSetup": true, 79 | "prestageInstalledProfileIds": [], 80 | "enableRecoveryLock": false, 81 | "recoveryLockPasswordType": "MANUAL", 82 | "rotateRecoveryLockPassword": false, 83 | "prestageMinimumOsTargetVersionType": "MINIMUM_OS_LATEST_MINOR_VERSION", 84 | "minimumOsSpecificVersion": "", 85 | "accountSettings": { 86 | "id": "-1", 87 | "payloadConfigured": true, 88 | "localAdminAccountEnabled": true, 89 | "adminUsername": "localadmin", 90 | "adminPassword": "jamf123456", 91 | "hiddenAdminAccount": true, 92 | "localUserManaged": false, 93 | "userAccountType": "SKIP", 94 | "versionLock": 2, 95 | "prefillPrimaryAccountInfoFeatureEnabled": false, 96 | "prefillType": "CUSTOM", 97 | "prefillAccountFullName": "", 98 | "prefillAccountUserName": "", 99 | "preventPrefillInfoFromModification": false 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /_tests/templates/computer-prestage-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "keepExistingSiteMembership": false, 3 | "enrollmentSiteId": "-1", 4 | "id": "2", 5 | "displayName": "Test Prestage 2", 6 | "supportPhoneNumber": "08003689330", 7 | "supportEmailAddress": "", 8 | "department": "", 9 | "mandatory": true, 10 | "mdmRemovable": false, 11 | "defaultPrestage": false, 12 | "keepExistingLocationInformation": false, 13 | "requireAuthentication": false, 14 | "authenticationPrompt": "Enroll!", 15 | "profileUuid": "B033659294BEBCB17BF9C018554B089A", 16 | "deviceEnrollmentProgramInstanceId": "1", 17 | "versionLock": 19, 18 | "siteId": "-1", 19 | "skipSetupItems": { 20 | "Biometric": true, 21 | "TermsOfAddress": true, 22 | "FileVault": false, 23 | "iCloudDiagnostics": true, 24 | "Diagnostics": true, 25 | "Accessibility": true, 26 | "Intelligence": false, 27 | "AppleID": true, 28 | "ScreenTime": true, 29 | "Siri": true, 30 | "DisplayTone": true, 31 | "Restore": true, 32 | "Appearance": true, 33 | "Privacy": true, 34 | "Payment": true, 35 | "Registration": true, 36 | "TOS": true, 37 | "EnableLockdownMode": false, 38 | "Welcome": false, 39 | "Wallpaper": false, 40 | "iCloudStorage": true, 41 | "Location": false 42 | }, 43 | "locationInformation": { 44 | "username": "", 45 | "realname": "", 46 | "phone": "", 47 | "email": "", 48 | "room": "", 49 | "position": "", 50 | "departmentId": "-1", 51 | "buildingId": "-1", 52 | "id": "10", 53 | "versionLock": 0 54 | }, 55 | "purchasingInformation": { 56 | "id": "2", 57 | "leased": false, 58 | "purchased": true, 59 | "appleCareId": "", 60 | "poNumber": "", 61 | "vendor": "", 62 | "purchasePrice": "", 63 | "lifeExpectancy": 0, 64 | "purchasingAccount": "", 65 | "purchasingContact": "", 66 | "leaseDate": "1970-01-01", 67 | "poDate": "1970-01-01", 68 | "warrantyDate": "1970-01-01", 69 | "versionLock": 0 70 | }, 71 | "preventActivationLock": true, 72 | "enableDeviceBasedActivationLock": false, 73 | "anchorCertificates": [], 74 | "enrollmentCustomizationId": "0", 75 | "language": "", 76 | "region": "", 77 | "autoAdvanceSetup": false, 78 | "customPackageIds": [], 79 | "customPackageDistributionPointId": "-1", 80 | "installProfilesDuringSetup": true, 81 | "prestageInstalledProfileIds": [], 82 | "enableRecoveryLock": false, 83 | "recoveryLockPasswordType": "MANUAL", 84 | "rotateRecoveryLockPassword": false, 85 | "prestageMinimumOsTargetVersionType": "NO_ENFORCEMENT", 86 | "minimumOsSpecificVersion": "", 87 | "accountSettings": { 88 | "id": "2", 89 | "payloadConfigured": true, 90 | "localAdminAccountEnabled": false, 91 | "adminUsername": "", 92 | "hiddenAdminAccount": false, 93 | "localUserManaged": false, 94 | "userAccountType": "ADMINISTRATOR", 95 | "versionLock": 4, 96 | "prefillPrimaryAccountInfoFeatureEnabled": false, 97 | "prefillType": "DEVICE_OWNER", 98 | "prefillAccountFullName": "", 99 | "prefillAccountUserName": "", 100 | "preventPrefillInfoFromModification": false 101 | } 102 | } -------------------------------------------------------------------------------- /_tests/templates/Cisco AnyConnect System Extension and Content Filter Whitelist.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | AllowUserOverrides 9 | 10 | AllowedSystemExtensions 11 | 12 | DE8Y96K9QP 13 | 14 | com.cisco.anyconnect.macos.acsockext 15 | 16 | 17 | PayloadDescription 18 | 19 | PayloadDisplayName 20 | AnyConnect System Extension 21 | PayloadEnabled 22 | 23 | PayloadIdentifier 24 | A8364220-5D8D-40A9-Af66-1Fbfef94E116 25 | PayloadOrganization 26 | Cisco Systems, Inc. 27 | PayloadType 28 | com.apple.system-extension-policy 29 | PayloadUUID 30 | A8364220-5D8D-40A9-Af66-1Fbfef94E116 31 | PayloadVersion 32 | 1 33 | 34 | 35 | Enabled 36 | 37 | AutoFilterEnabled 38 | 39 | FilterBrowsers 40 | 41 | FilterSockets 42 | 43 | FilterPackets 44 | 45 | FilterType 46 | Plugin 47 | FilterGrade 48 | firewall 49 | PayloadDescription 50 | 51 | PayloadDisplayName 52 | Cisco AnyConnect Content Filter 53 | PayloadIdentifier 54 | com.apple.webcontent-filter.339Ec532-9Ada-480A-Bf3D-A535F0F0B665 55 | PayloadType 56 | com.apple.webcontent-filter 57 | PayloadUUID 58 | 339Ec532-9Ada-480A-Bf3D-A535F0F0B665 59 | PayloadVersion 60 | 1 61 | FilterDataProviderBundleIdentifier 62 | com.cisco.anyconnect.macos.acsockext 63 | FilterDataProviderDesignatedRequirement 64 | anchor apple generic and identifier "com.cisco.anyconnect.macos.acsockext" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = DE8Y96K9QP) 65 | PluginBundleID 66 | com.cisco.anyconnect.macos.acsock 67 | UserDefinedName 68 | Cisco AnyConnect Content Filter 69 | 70 | 71 | PayloadDescription 72 | 73 | PayloadDisplayName 74 | Approved Cisco AnyConnect System Extensions 75 | PayloadEnabled 76 | 77 | PayloadIdentifier 78 | A401Bdc2-4Ab1-4406-A143-11F077Baf52B 79 | PayloadOrganization 80 | Cisco Systems, Inc. 81 | PayloadRemovalDisallowed 82 | 83 | PayloadScope 84 | System 85 | PayloadType 86 | Configuration 87 | PayloadUUID 88 | A401Bdc2-4Ab1-4406-A143-11F077Baf52B 89 | PayloadVersion 90 | 1 91 | 92 | 93 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/READMEs/JamfScriptUploader.md: -------------------------------------------------------------------------------- 1 | # JamfScriptUploader 2 | 3 | ## Description 4 | 5 | A processor for AutoPkg that will upload a script to a Jamf Cloud or on-prem server. 6 | 7 | ## Input variables 8 | 9 | - **JSS_URL:** 10 | - **required:** True 11 | - **description:** URL to a Jamf Pro server that the API user has write access to, optionally set as a key in the com.github.autopkg preference file. 12 | - **API_USERNAME:** 13 | - **required:** False 14 | - **description:** Username of account with appropriate access to jss, optionally set as a key in the com.github.autopkg preference file. 15 | - **API_PASSWORD:** 16 | - **required:** False 17 | - **description:** Password of api user, optionally set as a key in the com.github.autopkg preference file. 18 | - **CLIENT_ID:** 19 | - **required:** False 20 | - **description:** Client ID with access to access to jss, optionally set as a key in the com.github.autopkg preference file. 21 | - **CLIENT_SECRET:** 22 | - **required:** False 23 | - **description:** Secret associated with the Client ID, optionally set as a key in the com.github.autopkg preference file. 24 | - **script_path**: 25 | - **required**: False 26 | - **description**: Full path to the script to be uploaded 27 | - **script_name**: 28 | - **required**: False 29 | - **description**: Name of the script in Jamf 30 | - **script_category**: 31 | - **required**: False 32 | - **description**: Script category 33 | - **script_priority**: 34 | - **required**: False 35 | - **description**: Script priority (BEFORE or AFTER) 36 | - **default**: AFTER 37 | - **osrequirements**: 38 | - **required**: False 39 | - **description**: Script OS requirements 40 | - **script_info**: 41 | - **required**: False 42 | - **description**: Script info field 43 | - **script_notes**: 44 | - **required**: False 45 | - **description**: Script notes field 46 | - **skip_script_key_substitution**: 47 | - **required**: False 48 | - **description**: Skip substitution of keys marked between `%` signs in the script. 49 | - **default**: False 50 | - **script_parameter4**: 51 | - **required**: False 52 | - **description**: Script parameter 4 title 53 | - **script_parameter5**: 54 | - **required**: False 55 | - **description**: Script parameter 5 title 56 | - **script_parameter6**: 57 | - **required**: False 58 | - **description**: Script parameter 6 title 59 | - **script_parameter7**: 60 | - **required**: False 61 | - **description**: Script parameter 7 title 62 | - **script_parameter8**: 63 | - **required**: False 64 | - **description**: Script parameter 8 title 65 | - **script_parameter9**: 66 | - **required**: False 67 | - **description**: Script parameter 9 title 68 | - **script_parameter10**: 69 | - **required**: False 70 | - **description**: Script parameter 10 title 71 | - **script_parameter11**: 72 | - **required**: False 73 | - **description**: Script parameter 11 title 74 | - **replace_script**: 75 | - **required**: False 76 | - **description**: Overwrite an existing script if True. 77 | - **default**: False 78 | - **sleep:** 79 | - **required:** False 80 | - **description:** Pause after running this processor for specified seconds. 81 | - **default:** "0" 82 | - **max_tries:** 83 | - **required:** False 84 | - **description:** Maximum number of attempts to upload the account. Must be an integer between 1 and 10. 85 | - **default:** "5" 86 | 87 | ## Output variables 88 | 89 | - **script_name**: 90 | - **description:** Name of the uploaded script 91 | - **jamfscriptuploader_summary_result:** 92 | - **description:** Description of interesting results. 93 | -------------------------------------------------------------------------------- /JamfUploaderProcessors/JamfPolicyDeleter.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/autopkg/python 2 | 3 | """ 4 | Copyright 2023 Graham Pugh 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | NOTES: 19 | All functions are in JamfUploaderLib/JamfPolicyDeleterBase.py 20 | """ 21 | 22 | import os.path 23 | import sys 24 | 25 | # to use a base module in AutoPkg we need to add this path to the sys.path. 26 | # this violates flake8 E402 (PEP8 imports) but is unavoidable, so the following 27 | # imports require noqa comments for E402 28 | sys.path.insert(0, os.path.dirname(__file__)) 29 | 30 | from JamfUploaderLib.JamfPolicyDeleterBase import ( # noqa: E402 31 | JamfPolicyDeleterBase, 32 | ) 33 | 34 | __all__ = ["JamfPolicyDeleter"] 35 | 36 | 37 | class JamfPolicyDeleter(JamfPolicyDeleterBase): 38 | description = ( 39 | "A processor for AutoPkg that will delete a policy from a Jamf Cloud " 40 | "or on-prem server." 41 | ) 42 | input_variables = { 43 | "JSS_URL": { 44 | "required": True, 45 | "description": "URL to a Jamf Pro server that the API user has write access " 46 | "to, optionally set as a key in the com.github.autopkg " 47 | "preference file.", 48 | }, 49 | "API_USERNAME": { 50 | "required": False, 51 | "description": "Username of account with appropriate access to " 52 | "jss, optionally set as a key in the com.github.autopkg " 53 | "preference file.", 54 | }, 55 | "API_PASSWORD": { 56 | "required": False, 57 | "description": "Password of api user, optionally set as a key in " 58 | "the com.github.autopkg preference file.", 59 | }, 60 | "CLIENT_ID": { 61 | "required": False, 62 | "description": "Client ID with access to " 63 | "jss, optionally set as a key in the com.github.autopkg " 64 | "preference file.", 65 | }, 66 | "CLIENT_SECRET": { 67 | "required": False, 68 | "description": "Secret associated with the Client ID, optionally set as a key in " 69 | "the com.github.autopkg preference file.", 70 | }, 71 | "policy_name": { 72 | "required": True, 73 | "description": "Policy to delete", 74 | "default": "", 75 | }, 76 | "max_tries": { 77 | "required": False, 78 | "description": ( 79 | "Maximum number of attempts to upload the account. " 80 | "Must be an integer between 1 and 10." 81 | ), 82 | "default": "5", 83 | }, 84 | } 85 | 86 | output_variables = { 87 | "jamfpolicydeleter_summary_result": { 88 | "description": "Description of interesting results.", 89 | }, 90 | } 91 | 92 | def main(self): 93 | """Run the execute function""" 94 | 95 | self.execute() 96 | 97 | 98 | if __name__ == "__main__": 99 | PROCESSOR = JamfPolicyDeleter() 100 | PROCESSOR.execute_shell() 101 | --------------------------------------------------------------------------------