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. 👍

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