Installing PKG using a bash script with Jamf

New Contributor III

Hello all,

I have a few pkg files I'd like to install using bash since I can suppress the various popups they produce during installation which are really just confusing to the user. I'm simply running:

sudo installer -pkg "package.pkg" -target /

and it works great. However, when I go to do this in the JSS, I understand that I would put the line above and the others that do the other packages into a script and add that to a policy, but where exactly do I put the pkg files? What path would I use to tell installer where the packages are?

I'm guessing I could still put them on the DP using Admin, find their location on the share, and use that as the package location in the script but that just doesn't seem right.

How can I properly install a handful of pkg files with bash using the JSS? We're running Jamf on-prem.


Valued Contributor

Why not simply put them on the DP, as you say, and push them via an install policy? Seems like using bash here is complicating the entire process.

Pushed via a policy, the install will be silent, and all you need to do is select the pkgs...

Contributor III

@Taylor.Armstrong Is correct. The installation will be silent. If you still want to do it through bash here is an example:


#Make Temp Directory
mkdir -p /Volumes/Macintosh HD/Users/Shared/temp

#Go to temp
cd /Volumes/Macintosh HD/Users/Shared/temp

#download iboss zip
curl -LO

#Unzip files

#Run IBOSS Installer
bash /Volumes/Macintosh HD/Users/Shared/temp/IBOSS/

sleep 10

#Remove Temp Directory
rm -rf /Volumes/Macintosh HD/Users/Shared/temp

exit 0

Valued Contributor

@trc29 your going to have to "package" the .pkg files and "install" them somewhere on the client disk (I'd use /tmp), and then use that path in your script.

I've only ever had one odd case situation that I needed to install a .pkg via cli like that. What .pkgs are you installing that display popups to the user when installed directly via policy? That might be a solvable problem eliminating the need to jump through hoops with the cli installer.

Edit: hmmm, or curl, hadn't though of that. Nice.

Contributor II

To install Cisco AnyConnect and configure it using the XLM the proper way, I have a pkg that the JSS installs that places the Cisco pkg and xml file at /temp/Cisco. I then have a script be a part of the policy that runs at the end that installs the Cisco pkg using the XML for configuration info.

Confusing but it works.

If it is one line then you can also throw the command in the File Maintenance section that will run at the end.

New Contributor III

Thank you everyone for your responses!

@dpertschi, We're installing Sophos SafeGuard. Installation is broken into two separate pkg: disk and file encryption. When upgrading from an older version, regardless of which component is installed first, the component being installed second will complain that it is outdated and needs to be updated throwing a message to contact your contact your system admin. The JSS does not appear to do a silent install, or at least a full silent install, since installing the components from Terminal does not make this message appear.

The other annoying thing it does is prompt the user to enable encryption and reboot prior to the JSS installation finishing on new installs. Doing this via Terminal does not cause this behavior.

Trust me, I'd rather just put these in a policy as I have now and let it be but it doesn't seem I'll be able to do that.

Valued Contributor III

What I do is “wrap” the vendor package inside a package I create. Basically I have my package dump to /tmp and have a postinstall script call the vendor package how I want it called (with custom switches, targets, etc). After the vendor package is installed, it’s then easy to cleanup /tmp with a final rm command at the end of the script.

Valued Contributor III

The benefit of the method I outlined is that the “wrapper package” appears as a plain-Jane package to the JSS. I could also give it to the end user for GUI installation if that’s desired, yet the package gets installed “my way”

New Contributor III

@blackholemac I really like that idea. I considered doing a mpkg before because I think that's what I should be doing since this is multiple packages but maybe that's not necessary anymore. I've only toyed with package creation a bit and I get the general idea with pre and post scripts. I guess it's time to finally sit down and try making one.

Do you use composer or something else?


Contributor II

Like @blackholemac I use wrapper packages. I use composer, drop the packages I need into /tmp and then drag into composer and add post install script to call installer command line tool. This also allows me to use an installer Choices file. This would not have to be an MPKG since the other installers are just payloads to place on the file system. This way I can also sign the installer with our dev cert to avoid Gatekeeper. As always, test, test, test.

Legendary Contributor II

I've done the same thing that @blackholemac outlined, for certain installs. If using Composer, simply place the vendor pkgs, xml files and anything else you need into a custom directory in /tmp/, then in Composer, drag that folder into the sidebar and it will copy it in and create a new source with the folder + files you just dragged in. Then add a postinstall script that does the installations using installer command line, making sure to use the full path to the pkgs, like /tmp/productinstallers/installer.pkg. This generally works very nicely and allows you to keep it all in one package. You can use this pkg in a Jamf policy or hand it to someone to install manually and it should work exactly the same way.

Valued Contributor III

I do use Composer but mainly because it's a quick drag drop make your own package tool...@mm2270 is essentially doing what I do...I put all the stuff I need...vendor packages, choice.xml files and any other tools into tmp, do my thing with the post install and clean it up. You wouldn't have to use composer...any package building tool will do, I just use it simply because it's relatively fast.