Archive
Using Script2Pkg to create payload-free installer packages
Payload-free packages are something I’ve discussed from time to time, as I’ve found them to be very useful additions to my Mac admin toolkit. For those not familiar with the concept, payload-free installer packages are installer packages that exist only to run scripts. They don’t install any files, which would be referred to as the installer package’s payload. With no payload included with these installer packages, the installer packages built by this tool are referred to as payload-free.
A while back, I wrote a tool that would let me easily create them from existing scripts named Payload-Free Package Creator.app. The general idea was that you could use this tool to select a script, and then Payload-Free Package Creator.app would create an unsigned payload-free installer package which would run the selected script.
I’m happy to say that my team at work has expanded on that idea and has both built and open-sourced a tool for building payload-free packages named Script2Pkg. Script2Pkg includes the following functions:
- Building an unsigned payload-free installer package
- Building a signed payload-free installer package
- Building a signed and notarized payload-free installer package
- Verifying signing and notarization status of any installer package
For more details, please see below the jump.
Using AutoPkg to build installers for Palo Alto’s GlobalProtect VPN software
As part of some recent testing, I needed to do some work with Palo Alto’s GlobalProtect VPN software. Palo Alto provides an installer package for GlobalProtect, but it has some interesting characteristics as the installer includes three installation options. One is enabled by default and the other two are disabled by default.
The first configuration is the option to install GlobalProtect, the default enabled configuration:
The second configuration is the option to uninstall GlobalProtect, which is disabled by default:
The third configuration is the option to enable the System Extension for GlobalProtect, which is disabled by default:
Note: In the image above, I’ve done some photoshopping because checking the third option to enable the System Extension for GlobalProtect also enables the option to install GlobalProtect. I made the change to the image to hopefully make more clear which option I was discussing.
The options to uninstall GlobalProtect and enable the System Extension for GlobalProtect can be managed by using an installer choices XML file to selectively enable only the desired option. For example, here’s the installer choices XML file for enabling only the option to uninstall GlobalProtect:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<array> | |
<dict> | |
<key>attributeSetting</key> | |
<integer>1</integer> | |
<key>choiceAttribute</key> | |
<string>selected</string> | |
<key>choiceIdentifier</key> | |
<string>second</string> | |
</dict> | |
<dict> | |
<key>attributeSetting</key> | |
<integer>1</integer> | |
<key>choiceAttribute</key> | |
<string>selected</string> | |
<key>choiceIdentifier</key> | |
<string>com.paloaltonetworks.globalprotect.uninstall.pkg</string> | |
</dict> | |
</array> | |
</plist> |
Here’s the installer choices XML file for enabling only the option to enable the System Extension for GlobalProtect:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<array> | |
<dict> | |
<key>attributeSetting</key> | |
<integer>1</integer> | |
<key>choiceAttribute</key> | |
<string>selected</string> | |
<key>choiceIdentifier</key> | |
<string>third</string> | |
</dict> | |
<dict> | |
<key>attributeSetting</key> | |
<integer>1</integer> | |
<key>choiceAttribute</key> | |
<string>selected</string> | |
<key>choiceIdentifier</key> | |
<string>com.paloaltonetworks.globalprotect.systemext.pkg</string> | |
</dict> | |
</array> | |
</plist> |
Using these options, I was able to build recipes for AutoPkg which would automatically build three installer packages:
- An installer which installs GlobalProtect.
- An installer which uninstalls GlobalProtect.
- An installer which enables the System Extension for GlobalProtect.
The reason I chose to do this is that using AutoPkg to create these additional installer packages should help ensure any changes that Palo Alto makes to GlobalProtect’s uninstall and System Extension enablement will automatically be available whenever a new version of GlobalProtect is picked up by AutoPkg. In turn, this should save work for those deploying GlobalProtect because now they don’t need to figure out what may have changed between GlobalProtect releases. For more details, please see below the jump.
Creating a NexThink uninstaller for deployment via Jamf Pro
As a follow-up to my previous post on building an installer for NexThink Collector which could be deployed via Jamf Pro, I also needed to build an uninstaller for this software. Fortunately, NexThink ships an uninstaller script on the same disk image that it uses to ship its installer.
NexThink’s install documentation for the macOS version of the Collector software assumes that a human is doing the following to run the uninstall process:
A. Mounting the disk image
B. Opening the Terminal application
C. Using the uninstaller script to run the uninstallation process.
In my case, I decided to do the following to deploy the uninstaller via Jamf Pro:
- Wrap the disk image inside a separate installer package.
- Use a postinstall script to perform the following actions:
A. Identify the location of the disk image stored inside the installer package.
B. Mount the disk image
C. Use the uninstall script to uninstall the NexThink Collector software.
D. Unmount the disk image.
For more details, please see below the jump.
Creating a NexThink installer for deployment via Jamf Pro
A while back, I had to build an installer for NexThink Collector which could be deployed via Jamf Pro. NexThink can be interesting to deploy because the installation process:
- Involves an application named csi.app, which has a command line tool.
- The referenced csi app’s command line tool configures and runs an installer package.
- The command line tool also needs to reference a license file, which NexThink refers to as a CustomerKey file.
The CustomerKey file should look similar to what’s shown below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
—–BEGIN CUSTOMER KEY—–MIIDhzCCAm+gAwIBAgIEIa+KoTANBgkqhkiG9w0BAQsFADBbMScwJQYDVQQDDB5SZWdlcnkgU2VsZi1TaWduZWQgQ2VydGlmaWNhdGUxIzAhBgNVBAoMGlJlZ2VyeSwgaHR0cHM6Ly9yZWdlcnkuY29tMQswCQYDVQQGEwJVQTAgFw0yMjEyMDIwMDAwMDBaGA8yMTIyMTIwMjIwMDIxMFowSTEVMBMGA1UEAwwMbG9jYWxob3N0LmlvMSMwIQYDVQQKDBpSZWdlcnksIGh0dHBzOi8vcmVnZXJ5LmNvbTELMAkGA1UEBhMCVUEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaKRW9KeX4wg/838FkxmzaBjqf1DeKD5GKEqhUKz0y78Wwnsv2zAXGM4UkdZJP9zHtC9/wFQT+lhclDlogxkU9lfMADV7nMdGL0GkJzwMQNS52dPNXDup7/d9yRkyjkV0Pf4t2fJF3igoNXFQuBvuArkNV6hfja2gOEczOSAaJ7L7qRnSahLjciJRaCuEPjwneh3krhOFT+djwuYJMIvBDEqs+gfp4OPDDBtVg2scUUGRmHsC+JAoK+JwqYwB9TNt+9hZtGfDqgZSHebXEfRTguhQpBj0mPTo76EahAbHbXJhV+efg3jt32pZ6qRl8ffrZAjefWEAnOMyXQ7fbL+bpAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBRNHRZG3IKNH0kTRaiVfq6N8Ovp5zAfBgNVHSMEGDAWgBRNHRZG3IKNH0kTRaiVfq6N8Ovp5zANBgkqhkiG9w0BAQsFAAOCAQEAhpbntg+nwhIKgRuUidu/wXn197Ah0Pd4CYYxG5dR9rg8nWObx4QO6ApIH91nUUQVuV6mSTFtfy4yNQzxaROgZP9hDNvhd78D/ewXxp6bN/Xkn+c7SWrs/b1vHb2Dr1sDP4F9SAOrCI6TdoYa8UNhPXXSTt8M/hGSB2oWOpT2FAb2IbdmdYhDaibcJwp+/Had1FLbeDZgdgYCFoZLjws/9E/pIXjSxBYAJLbaQZffrfO5jCe2KesE73iQatW2IPynsFifRGGoMHXVLOfsLA9c2KDGqDmnJ+PvsBSe9rIpSJYC4WjR5Mt8W88kQSj05b9NqCsXmmMDEbD8uVLyKvQihA==—–END CUSTOMER KEY—– |
All the needed components with the exception of the CustomerKey file, which is different for each customer, ship on a disk image.
NexThink’s install documentation for the macOS version of the Collector software assumes that a human is doing one of the following:
Graphical installation: Mounting the disk image, double-clicking on the installer package and following the prompts, entering the correct configuration information were needed.
Command line installation: Mounting the disk image, opening the Terminal application and using the csi app’s command line tool to configure the installer package and run the installation process.
For the Enterprise Deployment section of the application, the NexThink documentation says they support it but doesn’t provide information on how to do it.
In my case, I decided to do the following to deploy it via Jamf Pro:
- Wrap the disk image and CustomerKey file inside a separate installer package.
- Use a postinstall script to perform the following actions:
A. Identify the location of the disk image stored inside the installer package.
B. Mount the disk image
C. Identify the location of the csi.app on the mounted disk image.
D. Identify the location of the CustomerKey file stored inside the installer package.
E. Use the csi app’s command line tool to configure and run the NexThink-provided installer package on the mounted disk image, to install the NexThink Collector software.
F. Unmount the disk image.
For more details, please see below the jump.
Building a Privileges installer package using AutoPkg
In working with folks who want to build installer packages to install the Privileges app, I’ve noticed that a number of them have experienced problems with manually building an installer package for Privileges which correctly installs the Privileges app’s helper tool.
The result of an installer which does not install the helper tool correctly is that when a user requests administrator privileges using the Privileges app, the app prompts them to install the helper tool. This requires administrative rights, which sets up a chicken and egg situation where admin privileges are being required to get admin privileges.
Fortunately, there is an automated method for building the installer package which (so far) has worked correctly in each case I’m familiar with. There are AutoPkg recipes available for creating a Privileges installer package and AutoPkg is able to build a correctly working Privileges installer package.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
computername:~ username$ autopkg search com.github.rtrouton.Privileges | |
Name Repo Path | |
—- —- —- | |
Privileges.munki.recipe apfelwerk-recipes Privileges/Privileges.munki.recipe | |
Privileges.install.recipe rtrouton-recipes Privileges/Privileges.install.recipe | |
Privileges.munki.recipe rtrouton-recipes Privileges/Privileges.munki.recipe | |
Privileges.jss.recipe rtrouton-recipes JSS/Privileges.jss.recipe | |
Privileges.pkg.recipe rtrouton-recipes Privileges/Privileges.pkg.recipe | |
Privileges.download.recipe rtrouton-recipes Privileges/Privileges.download.recipe | |
To add a new recipe repo, use 'autopkg repo-add <repo name>' | |
computername:~ username$ |
For more details, please see below the jump.
Payload-Free Package Creator 2.4 now available
Payload-Free Package Creator.app, an Automator application that allows the selection of an existing script and then create a payload-free package that runs the selected script, has been updated to version 2.4.
The functionality and operations of the app have not changed from Payload-Free Package Creator 2.3. The main change is that Payload-Free Package Creator.app is now a Universal app, allowing it to run natively on both Intel and Apple Silicon Macs.
Payload-Free Package Creator 2.4, along with all components and scripts, are available on GitHub via the link below:
Simple Package Creator 1.5 now available
Simple Package Creator.app, an Automator application that will allow the selection of a self-contained application and creates an installer package that enables the installation of the application with pre-set permissions into /Applications, has been updated to version 1.5.
The functionality and operations of the app have not changed from Simple Package Creator 1.4. The main change is that Simple Package Creator.app is now a Universal app, allowing it to run natively on both Intel and Apple Silicon Macs.
Simple Package Creator 1.5, along with all components and scripts, are available on GitHub via the link below:
Installer package identifiers and the mystery of the missing Java 11 files
As part of developing new AutoPkg recipes to support SapMachine‘s new Long Term Support (LTS) distribution for Java 17, I ran into a curious problem when testing. When I ran the SapMachine Java 17 LTS installer that was being generated by AutoPkg, I was seeing the following behavior:
- SapMachine Java 17 LTS is installed by itself – no problem
- SapMachine Java 17 LTS installed, then SapMachine Java 11 LTS is installed – no problem
- SapMachine Java 11 LTS installed, then SapMachine Java 17 LTS is installed – SapMachine Java 11 LTS is removed, only SapMachine Java 17 LTS is installed now.
I double-checked the preinstall script for the SapMachine Java 17 LTS installer. It is supposed to remove an existing SapMachine Java 17 LTS installation with the same version info, but it should not have also been removing SapMachine Java 11 LTS. After a re-review of the script and additional testing, I was able to rule out the script as the problem. But what was causing this behavior? Also, why was it happening in this order?
- SapMachine Java 11 LTS installed, then SapMachine Java 17 LTS is installed
But not this order?
- SapMachine Java 17 LTS installed, then SapMachine Java 11 LTS is installed
The answer was in how the package’s package identifier was set up. For more details, please see below the jump.
Packaging a SAP GUI installer application for macOS
One of the recent changes for the macOS version of SAP GUI for Java is that both SapMachine Java 11 and OpenJFX 11 are now bundled with SAP GUI, so it is no longer required to have Java installed on your machine in order for SAP GUI to work. This change has also been extended to the SAP GUI installer, which is now available as a notarized installer application as of SAP GUI 7.70.
You can run this installer on a Mac which does not have Java already installed and it will install SAP GUI for Java with SapMachine Java 11 and OpenJFX 11 installations embedded inside the SAP GUI application.
Note: As of SAP GUI 7.70 rev 2, Rosetta 2 is required if installing on an Apple Silicon Mac so Rosetta needs to be installed and running before installing SAP GUI.
The installer application is available for download to customers via a link on the announcement blog post:
https://blogs.sap.com/2021/03/16/ann-sap-gui-for-java-7.70-available-for-download/
When you click the download link, you will see two choices:
- DMG
- JAR
The DMG download will provide the notarized installer application and the JAR download will provide the Java .jar installer that SAP GUI has traditionally used on macOS. I’ve discussed how to package the .jar installer in previous posts, so this post is going to focus on the new installer application contained inside the DMG download.
For more details, please see below the jump.
PkgSigner AutoPkg processor updated for Python 3
A while back, I discussed how to incorporate installer package signing into AutoPkg workflows. The PkgSigner processor used in this workflow was originally written by Paul Suh and it uses Apple’s productsign tool to access a Developer ID Installer certificate stored in the login keychain.
Like other processors and AutoPkg itself, PkgSigner needed updating to Python 3 when Python 2 reached end-of-life in April 2020. This updating process has been completed, thanks to Nick McDonald. To make sure PkgSigner is consistently using the same Python environment across machines, PkgSigner has also been set to use the Python 3 install bundled with AutoPkg.
For those who need it, I have a copy of the PkgSigner processor available via the link below:
https://github.com/rtrouton/AutoPkg_Processors/tree/master/PkgSigner
Recent Comments