{"id":22692947,"url":"https://github.com/deviscoding/jss-easy","last_synced_at":"2026-04-29T00:04:23.861Z","repository":{"id":50529337,"uuid":"339821220","full_name":"deviscoding/jss-easy","owner":"deviscoding","description":"Helper utility for JSS scripts","archived":false,"fork":false,"pushed_at":"2023-02-03T17:35:08.000Z","size":1041,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-04T18:14:56.500Z","etag":null,"topics":["jamf","jamf-pro","jamfpro-scripts","mac-administration","macos","mdm"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deviscoding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-17T18:40:08.000Z","updated_at":"2022-07-29T20:55:32.000Z","dependencies_parsed_at":"2023-02-13T01:45:15.989Z","dependency_job_id":null,"html_url":"https://github.com/deviscoding/jss-easy","commit_stats":null,"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deviscoding%2Fjss-easy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deviscoding%2Fjss-easy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deviscoding%2Fjss-easy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deviscoding%2Fjss-easy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deviscoding","download_url":"https://codeload.github.com/deviscoding/jss-easy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246215826,"owners_count":20741894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jamf","jamf-pro","jamfpro-scripts","mac-administration","macos","mdm"],"created_at":"2024-12-10T02:08:32.233Z","updated_at":"2026-04-29T00:04:23.827Z","avatar_url":"https://github.com/deviscoding.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSS Easy\nIn developing scripts to work with Jamf Pro to manage a fleet of Mac computers, I found that similar functionality was often needed in each script.  As Jamf does not offer any sort of shared script library, this often led to repeating blocks of code and updating many scripts when changes were needed. The JSS Helper application was created to streamline scripts by providing assistance with three types of functionality:\n\n* Downloads \u0026 Installations\n* Script Output\n* Information Gathering\n\nWhile it was designed for use with Jamf Pro, it may be used with other MDM systems, or without any MDM system.\n\n## Installation, Dependencies, and Compatibility\n\nFor installation on client systems, it is recommended that you use a policy that runs a script, called via a trigger.  See the `/resources` directory for an example.  Once you have a policy created, you can use **jez** in your scripts by adding the following lines:\n\n    ([ -z \"$(which jez)\" ] \u0026\u0026 jamf policy --trigger InstallJez) \u0026\u0026 ([ -z \"$(which jez)\" ] \u0026\u0026 echo \"ERROR: JEZ Not Installed\") \u0026\u0026 exit 1\n    source \"$(jez prep)\"\n\nAt this time, JSS Easy has no dependencies when used in macOS High Sierra, Mojave, Catalina, or Big Sur.\n\nIn Monterey, you must install PHP prior to use.\n\nFor testing, simply download the `jez.phar` to your utility path, and rename it, for example `/usr/local/bin/jez`.\n\n## Script Output Helpers\n\nDuring the course of running a script it can be helpful to provide some output to improve any logs kept by your MDM, as well as to ease troubleshooting.   As a script run by most MDM systems has no terminal type, there is additional complexity in adding output if one wishes to use color or spacing.  The output helpers allow for colored output when your terminal allows for it, and plain output when run in an automated fashion.  \n\nThere are three basic commands: `write`, `writeln`, and `badge`.\n\n| Command  | Description |\n|--|--|\n| `write` | Writes a line of text.  Can provide consistent widths using the `--width` option. |\n| `writeln` | Writes a line of text followed by a new line. |\n| `badge` | Writes a small quantity of text, capitalized, between brackets. |\n\nEach of these commands can be run with various aliases for the formats, detailed in the format chart further below. You can also use the various formats with the `--format` flag.\n\n| Format | Aliases | Typical Color |\n|--|--|--|   \n| success | `success`, `successln`, `successbg` | Green |\n| error | `error`, `errorln`, `errorbg` | Red |\n| info | `info`, `infoln`, `infobg` | Blue |\n| msg | `msg`, `msgln`, `msgbg` | Light Purple |\n| comment | `comment`, `commentln`, `commentbg` | Yellow |\n\n\n## Info Commands\nThese commands provide various information about the Mac system. All of this information can be found through various system utilities, however it can be handy to have it all in one place, pre-parsed and ready for use.\n\nAll commands can take a `--json` flag which will change the results to JSON.  Additionally, an argument can be given to limit the result to that key \u0026 subkeys.  For a full list of the keys available, run the command without any argument.\n\n| Command | Description |\n|--|--|\n| info:os | Provides information about the version, name, and build of the OS.  Additionally, reports any shared and personal caches in use, as well as any custom SUS url. |\n| info:app | Provides the version, name, path, identifier, copyright, filename, and path for the given application, or all applications if no argument is given.  Additional information is provided about Adobe Applications. |\n| info:hardware | Provides info about the model, cpu, power attributes, and network of the device. |\n\n## Install Commands\nThese commands help with the download and installation of executables and applications.  Which command is the most useful may depend on the source and format of the download.\n\n### Recipe Installer\nInstalls a pre-configured application, using the latest version available.  Only a limited number of applications are\navailable using this command, as detailed below.  Application names and details remain subject to the license of the\nauthor, license issuing party, or copyright holder as is appropriate.\n\nThis command should only be used for applications where you do not need to control the version of the application that is installed.\n\nFor most applications, nothing is downloaded if the _current_ version of the application matches the _installed_ version.  Applications where the _current_ version cannot be obtained from the application's website or other public source are the exception.\n\nExample usage:\n\n    jez install:recipe \u003cslug\u003e\n\n| Application | Recipe Slug |\n|--|--|\n| Adobe Reader DC | adobe-reader-dc |\n| Basecamp3 | basecamp |\n| Docker Desktop for Mac | docker |\n| Mozilla Firefox | firefox |\n| Mozilla Firefox Developer Edition | firefox-developer |\n| Google Chrome | google-chrome |\n| GoToMeeting | go-to-meeting |\n| Hyper | hyper |\n| iTerm2 | iterm2 |\n| Jamf PPPC Utility | jamf-pppc-utility |\n| Jetbrains PhpStorm | jetbrains-php-storm |\n| Microsoft Edge | microsoft-edge |\n| Microsoft OneDrive | microsoft-one-drive |\n| Microsoft Teams | microsoft-teams |\n| OpenVPN Connect | open-vpn-connect | \n| Platypus | platypus |\n| Rectangle | rectangle |\n| Slack | slack |\n| Sourcetree | sourcetree |\n| Skype | skype |\n| Thunderbird | thunderbird |\n| Visual Studio Code | visual-studio-code |\n\n### Github Installer\nDownloads a file from a GitHub Repo's release, and installs it in a given path.  Existing files are not overwritten unless the `--overwrite` flag or the `--installed` flag are given. When provided with the version currently installed using the `--installed` flag, this command will check the latest release to determine if an update is needed.\n\nExample Usage:\n\n    jez install:github \u003cdestination\u003e --repo=\u003crepo\u003e --file=\u003cfile_in_release\u003e\n    jez install:github /usr/local/bin/jez --repo=deviscoding/jss-easy --file=jez.phar\n\nThe permissions of downloaded files are set to be executable (0755).\n\n### PKG Installer\nDownloads a PKG file, installs, and confirms the target file or macOS app bundle is present. When the `--target` flag is given, and the destination is a macOS app bundle, the version is compared _before_ the download to verify that an update is needed.  The version is also verified _after_ installation.\n\nExample usage:\n\n    jez install:pkg \u003cdestination\u003e \u003curl\u003e\n\nExisting files are not overwritten unless the one of the following is true:\n\n* The `--target` flag is given, the destination is a macOS application bundle, and the target version is newer.\n* The `--overwrite` flag is given.\n* The `--target` and `--installed` flags are given, and the target version is newer than the installed version.\n\nAfter the installation, the downloaded PKG file is removed.\n\n### DMG Installer\nDownloads a DMG file, mounts the DMG, then inspects the contents to determine what is needed, using the logic in the table below.\n\nExample usage:\n\n    jez install:dmg \u003cdestination\u003e \u003curl\u003e\n\n| DMG Contains | Action |\n|--|--|\n| macOS App Bundle (.app) | If filename matches the _destination_, the downloaded app version is compared to the _destination_ version if present. If the destination does not exist or is an older version, the new app is copied to the _destination_. |\n| Single PKG File | PKG file is installed using the same criteria as the PKG installer command above. After installation, if a `--target` version is given \u0026 _destination_ is an app, the version is verified. |\n| Other File Types | If a filename matches the _destination_, that file is copied to destination unless already present.  Files are overwritten only if the `--overwrite` flag is given. |\n| Multiple PKG Files | No Action Taken |\n\nAfter the installation, the volume is unmounted, and the DMG file is removed.\n\n## Software Update Functionality\n**THIS FUNCTIONALITY SHOULD BE CONSIDERED BETA SOFTWARE AND SHOULD NOT BE USED IN PRODUCTION**\n\nWorks with the built in `softwareupdate` command and your MDM to facilitate the installation of macOS software updates.  Adds the following functionality to the built in `softwareupdate` command:\n\n* Wait Condition Monitoring (similar to the Wait command documented below), including whether the SUS is available.\n* Can trigger a Jamf policy for the installation of updates rather than using `softwareupdate`\n* Returns a non-zero exit code when a lack of disk space prevents installations.\n* Allows for Json output.\n* Can provide a simple count of updates to install.\n* Can provide a summary of relevant information to performing updates.\n* If running `softwareupdate` without user authentication is prevented, opens the Software Update Preference pane for the console user.\n\nIMPORTANT NOTE: This command currently requires the `at` daemon for restart functionality.\n\n### Installations (--install)\n\n**Apple Silicon Macs**\n\nIf the computer is using Apple Silicon, the Software Update preference pane is opened if any updates are pending, and a console user is logged in.\n\n**Other Macs**\n\nIf the `install-policy` option is provided, the Jamf Policy is used instead of running `softwareupdate` for the installations, otherwise the `softwareupdate` binary is utilized. When using the `softwareupdate` binary, all non-restart updates are installed individually, then any updates requiring a restart are installed in a batch.  This allows us to provide the maximum amount of feedback on the success or failure of updates installed.\n\n|Flags  | Purpose |  \n|--|--|  \n| install | Installs available updates |  \n| download | Downloads available updates |  \n| list | List available updates |\n| count | Provides a count of available updates |\n| summary | Provides a summary including counts (total updates, recommended, requiring restart, requiring halt), console username, content cache IP, SUS URL, free disk space, battery percentage, AC power, encryption status, presentation status, and SUS status. |\n| no-scan | Do not scan when listing or installing updates (use available updates previously scanned) |\n| skip-cpu | Do not wait for low CPU usage |\n| skip-power | Do not wait for AC power |\n| skip-user | Do not wait for console user logout |\n| skip-screen | Do not wait for screen availability |\n| wait | The number of seconds to wait for wait conditions.  Defaults to 60 seconds. |\n| install-policy | The trigger or ID for a Jamf Pro policy that installs updates using the Software Update payload. |\n| json | Show any output in JSON format. |\n| timeout | The amount of time in seconds that is allowed for any one `softwareupdate` command to complete.  Defaults to 7200 seconds (2 hours)\n\n## Adobe Applications Functionality\n\nThe Adobe commands can back up preferences for Adobe Creative Cloud applications, or transfer preferences between different _years_ of the same Creative Cloud application.\n\nFor all of these commands, the application name should be provided in lowercase, using a dash as a separator, for example: _after-effects_.\n\n#### adobe:backup _app_ _year_\nBacks up the preferences of an Adobe Creative Cloud application.  While the application does not need to be installed, it can be helpful.  Preferences are backed up to the path below, and stored in time/date stamped zip files.\n\n`/Users/\u003cuser\u003e/Library/Preferences/MDM Easy/CC/\u003capp\u003e/\u003cyear\u003e`\n\nThe year is optional for the applications that do not use it, such as XD, Dimension, and Lightroom.\n\n#### adobe:transfer _app_\nCopies preferences from one _year_ of a Creative Cloud application to another _year_.  This is intended for situations in which more than one _year_ of an application are installed side-by-side, such as both Photoshop 2020 and 2021.\n\n_It should be noted that this is purely a  \"copy\" process; no changes are made to the files,  and no attempt is made to migrate changed or deprecated preferences.  This has worked well in testing, but may not work with all future preferences or applications.  As such, a backup of the existing preferences is always made during the copy process_.\n\n|Flags  | Purpose |  \n|--|--|  \n| from | The source year, IE - 2019 |  \n| to | The destination year, IE - 2020 |  \n| user | This defaults to the current user, which makes it important to include this flag when running this tool as root. |\n\n## Wait Command\n\nThis command will wait until a number of conditions are false, or until the number of seconds given has passed.  This is useful for scripts in which you do not want to run the action while one of the configured conditions is present, for instance any script which may require a reboot.\n\nThe command can test for High CPU load, console user, battery power, screen sleep prevention (video conferencing), and an in-progress FileVault encryption.  If no condition flags are given, all conditions are tested for.\n\nExample usage:\n\n    jez wait 30 --filevault --power --cpu\n\n|Flags  | Purpose |  \n|--|--|  \n| user | Wait for there to be no console user present |  \n| filevault | Wait until no FileVault encryption is in-progress |  \n| power | Wait until the computer is on AC power |\n| screen | Wait until screen sleep is not prevented |\n| cpu | Wait until there is no high CPU load |\n| json | Output results in JSON format |\n\n## Ownership Command\n\nThis command set the ownership of the given file to the same owner \u0026 group as a user's home directory.  Note that symlinks are ignored by this command.\n\nExample usage:\n\n    jez chown:user /Users/bobm/Library/Preferences/com.apple.caramel.plist --user bobm\n\n| Flag | Purpose |\n|--|--|  \n| --user | Specifies the user to set permissions from |\n| --console | Uses the user currently logged into the GUI console |\n| --recursive | Performs the command recursively |\n\n## Menu Command\nThis command will add a menu to a user's menubar, and works with any of the .menu bundles located in\n\n    /System/Library/CoreServices/Menu Extras\n\nExample Usage:\n\n    jez menu:add VPN --user kevins\n\n|Flag  | Purpose |  \n|--|--|  \n| --user | The user to add the menu for.  This defaults to the current console user. |\n\n\n## Can you add...\nIf there is functionality that you constantly repeat in your MDM scripting, it may be useful to add to this application.  Open an issue with your use case, and an example of the code! Requests will be evaluated on a case-by-case basis.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeviscoding%2Fjss-easy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeviscoding%2Fjss-easy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeviscoding%2Fjss-easy/lists"}