HOWTO: Package files, scripts and apps together for macOS

PaulF
Meraki Employee
Meraki Employee

HOWTO: Package files, scripts and apps together for macOS

If you're looking for windows: https://community.meraki.com/t5/Mobile-Device-Management/HOWTO-Package-files-for-deployment-to-windo...

 

So, here's a quick guide on how to package files together, whether they be fonts, files, scripts, xml and / or apps.

 

Mild warning: You will need to be familiar with Terminal

 

There's three different examples:

 

  1. Script only (including an execute)
  2. plist / xml (or other file) only
  3. An installer made elsewhere that needs a pre or postflight script running (delete old version / expect input, etc, etc)

 

Building your package : Scripts

Open Terminal

 

using mkdir, create a directory. I've used ScriptPackage as an example:

 

cd ScriptPackage
mkdir Scripts
cd Scripts
touch postinstall

 

Using a text editor, edit the postinstall file and paste in your script. Save your script

 

Again, in Terminal:

 

chmod a+x postinstall
cd ..

 

Build the package: Type

 

sudo pkgbuild --identifier com.meraki.scriptonly --nopayload --script Scripts com.meraki.scriptsonly.pkg

 

Terminal should report:

pkgbuild: Adding top-level postinstall script
pkgbuild: Wrote package to com.meraki.scriptsonly.pkg

Note: we use the --nopayload flag to indicate there are no contents to the installer, just the postflight

 

 

Building your package : PLIST / XML (or other files)

Open Terminal

 

Using mkdir Create a Directory. I’ve used PlistPackage as the Example

 

mkdir PlistPackage
cd PlistPackage
mkdir Scripts
mkdir Content
cd Scripts
touch postinstall

 

Copy the file(s) you need into the Content Folder

 

Using a text editor, edit the postinstall file and paste in your script that will move files in /tmp (we set where the installer will deposit the files in a following command) to where ever you need to

 

In Terminal

 

chmod a+x postinstall
cd ..

 

Build the package

 

sudo pkgbuild --identifier com.meraki.plistonly --root Content --script Scripts --install-location /tmp com.meraki.plistonly.pkg

NoteThe above is similar to the previous example. We’ve removed the --nopayload flag and replaced it with --root Content to indicate that there’s a folder with content in 

 

Double Note: ensure that there is a space between /tmp and com.meraki.plistonly.pkg

 

Terminal reports:

 

sudo pkgbuild --identifier com.meraki.plistonly --root Content --script Scripts --install-location /tmp com.meraki.plistonly.pkg
pkgbuild: Inferring bundle components from contents of Content
pkgbuild: Adding top-level postinstall script
pkgbuild: Wrote package to com.meraki.plistonly.pkg

 

Building your package : DMG / PKG (silent installer)

Open Terminal

Using mkdir Create a Directory. I’ve used InstallerPackage as the Example

 

mkdir InstallerPackage
cd InstallerPackage
mkdir Scripts
mkdir Content
cd Scripts
touch postinstall

 

Copy the DMG  you need into the Content Folder

Using a text editor, edit the postinstall file and paste in your script that will move files in /tmp to where ever you need to

 

In Terminal

 

chmod a+x postinstall
cd ..

 

Build the package:

 

sudo pkgbuild --identifier com.meraki.dmg --root Content --script Scripts --install-location /tmp com.meraki.dmg.pkg

 

Terminal will report:

 

pkgbuild: Inferring bundle components from contents of Content
pkgbuild: Adding top-level postinstall script
pkgbuild: Wrote package to com.meraki.plistonly.pkg

 

An example postflight to move an app from a mounted DMG to /Applications:

#!/bin/bash

dmgPath="/tmp/YourDMGName.dmg"
mountPath="/Volumes/YourDMGMounted"
currentuser="$(id -un)"
usersAppDir="$(sudo -u $currentuser echo $HOME)"

/usr/bin/hdiutil attach "$dmgPath" -nobrowse -quiet
		
if [[ -e "$mountPath" ]]
	then
		cp -r "$mountPath"/"YourApp.app" /Applications/"YourAppName.app"
fi

umount "$mountPath"

rm -rf "$dmgPath"

# insert the commands that you need to
# provision your application

exit 0

 

An example postflight to move an app from a mounted DMG to /Applications where the DMG install expects user input

CaptureOne. for example, requests the user accept some EULA when opening the DMG. You can script this acceptance in your postflight:

 

#!/bin/bash

dmgPath="/tmp/CaptureOne12.Mac.12.1.4.dmg"
mountPath="/Volumes/Capture One 12"

/usr/bin/expect<<EOF
		spawn /usr/bin/hdiutil attach "$dmgPath" -nobrowse -quiet
		expect ":"
		send -- "G"
		expect ""
		send -- "\n"
		expect "Agree Y/N?"
		send -- "Y\n"
		expect EOF
EOF

if [[ -e "$mountPath" ]]
	then
		cp -r "$mountPath"/"Capture One 12.app" /Applications/"Capture One 12.app"
fi

umount "$mountPath"

exit 0

 

We use the EXPECT command to wait for the prompt, and SEND to send user input.

 

Hope that helps!

1 Reply 1
BlakeRichardson
Kind of a big deal
Kind of a big deal

Great info, easy to follow and well written. 👍

If you found this post helpful, please give it Kudos. If my answer solves your problem, please click Accept as Solution so others can benefit from it.
Get notified when there are additional replies to this discussion.
Welcome to the Meraki Community!
To start contributing, simply sign in with your Cisco account. If you don't yet have a Cisco account, you can sign up.
Labels