-
-
Save arekdreyer/a7af6eab0646a77b9684b2e620b59e1b to your computer and use it in GitHub Desktop.
#!/bin/zsh | |
## postinstall | |
pathToScript=$0 | |
pathToPackage=$1 | |
targetLocation=$2 | |
targetVolume=$3 | |
# This postinstall script for Composer creates the following | |
# A LaunchDaemon that starts a separate script to run a Jamf Pro policy command | |
# A script to wait for Jamf Pro enrollment to complete | |
# - then triggers a Jamf Pro policy that triggers DEPNotify | |
# A script that is designed to be called by a Jamf Pro policy | |
# - to unload the LaunchDaemon then remove the LaunchDaemon and script | |
# | |
# Q: Why not just call the `jamf policy -event` command | |
# from the PreStage Enrollment package postinstall script? | |
# A: Because the PreStage Enrollment package is installed | |
# before the jamf binary is installed. | |
# | |
# Q: Why not just have the postinstall script wait until jamf enrollment is complete? | |
# A: Because the postinstall script won't exit while it waits, which prevents enrollment | |
# | |
# Q: Why not just include the DEPNotify.sh script in the PreStage Enrollment package? | |
# A: Because every time you update it, for instance POLICY_ARRAY, | |
# you'd need to re-build and re-upload the package | |
# | |
# Q: Why not distribute the extra scripts and LaunchDaemons somewhere else, | |
# instead of embedding them in this funky postinstall script? | |
# A: This way you only have to download and maintain one extra thing. | |
# | |
# One approach is to use the following locations and files: | |
# LaunchDaemon: | |
# /Library/LaunchDaemons/com.arekdreyer.DEPNotify-prestarter.plist | |
# | |
# Temporary folder for the installer and scripts: | |
# /usr/local/depnotify-with-installers/ | |
# | |
# Scripts: | |
# /usr/local/depnotify-with-installers/com.arekdreyer.DEPNotify-prestarter-installer.zsh | |
# /usr/local/depnotify-with-installers/com.arekdreyer.DEPNotify-prestarter-uninstaller.zsh | |
# This script must be run as root or via Jamf Pro. | |
# The resulting Script and LaunchDaemon will be run as root. | |
# Update this when the DEPNotify installer package is updated; earlier name was DEPNotifyInstallerName=DEPNotify-1.1.4.pkg | |
DEPNotifyInstallerName=DEPNotify.pkg | |
# | |
# You can change this if you have a better location to use. | |
# I haven't tested this with any path that has a space in the name. | |
TempUtilitiesPath=/usr/local/depnotify-with-installers | |
# | |
# You can change any of these: | |
InstallerBaseString=com.arekdreyer.DEPNotify-prestarter | |
InstallerScriptName=${InstallerBaseString}-installer.zsh | |
InstallerScriptPath=${TempUtilitiesPath}/${InstallerScriptName} | |
UnInstallerScriptName=${InstallerBaseString}-uninstaller.zsh | |
UnInstallerScriptPath=${TempUtilitiesPath}/${UnInstallerScriptName} | |
# Best to use /Library/LaunchDaemons for the LaunchDaemon | |
LaunchDaemonName=${InstallerBaseString}.plist | |
LaunchDaemonPath="/Library/LaunchDaemons"/${LaunchDaemonName} | |
DEPNOTIFYSTARTER_TRIGGER=start-depnotify | |
# Install the package | |
/usr/sbin/installer -pkg ${TempUtilitiesPath}/${DEPNotifyInstallerName} -target $3 | |
# The following will create a script that triggers the DEPNotify script to start. Be sure the contents are between the two "ENDOFINSTALLERSCRIPT" lines. | |
# NOTE: Make sure to leave a full return at the end of the Script content before the last "ENDOFINSTALLERSCRIPT" line. | |
echo "Creating ${InstallerScriptPath}." | |
( | |
cat <<ENDOFINSTALLERSCRIPT | |
#!/bin/zsh | |
until [ -f /var/log/jamf.log ] | |
do | |
echo "Waiting for jamf log to appear" | |
sleep 1 | |
done | |
until ( /usr/bin/grep -q enrollmentComplete /var/log/jamf.log ) | |
do | |
echo "Waiting for jamf enrollment to be complete." | |
sleep 1 | |
done | |
/usr/local/jamf/bin/jamf policy -event ${DEPNOTIFYSTARTER_TRIGGER} | |
exit 0 | |
ENDOFINSTALLERSCRIPT | |
) > "${InstallerScriptPath}" | |
echo "Setting permissions for ${InstallerScriptPath}." | |
chmod 755 "${InstallerScriptPath}" | |
chown root:wheel "${InstallerScriptPath}" | |
#----------- | |
# The following will create the LaunchDaemon file that starts the script that waits for Jamf Pro enrollment | |
# then runs the jamf policy -event command to run your DEPNotify.sh script. | |
echo "Creating ${LaunchDaemonPath}." | |
( | |
cat <<ENDOFLAUNCHDAEMON | |
<?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"> | |
<dict> | |
<key>Label</key> | |
<string>${InstallerBaseString}</string> | |
<key>RunAtLoad</key> | |
<true/> | |
<key>UserName</key> | |
<string>root</string> | |
<key>ProgramArguments</key> | |
<array> | |
<string>/bin/zsh</string> | |
<string>${InstallerScriptPath}</string> | |
</array> | |
<key>StandardErrorPath</key> | |
<string>/var/tmp/${InstallerScriptName}.err</string> | |
<key>StandardOutPath</key> | |
<string>/var/tmp/${InstallerScriptName}.out</string> | |
</dict> | |
</plist> | |
ENDOFLAUNCHDAEMON | |
) > "${LaunchDaemonPath}" | |
echo "Setting permissions for ${LaunchDaemonPath}." | |
chmod 644 "${LaunchDaemonPath}" | |
chown root:wheel "${LaunchDaemonPath}" | |
echo "Loading ${LaunchDaemonName}." | |
launchctl load "${LaunchDaemonPath}" | |
#----------- | |
# The following will create the script file to uninstall the LaunchDaemon and installer script. | |
# You can create a Jamf Pro policy with the following characteristics: | |
# General settings: | |
# --Name: Cleanup DEPNotify Installers | |
# --Trigger: Custom Trigger: cleanup-depnotify-preinstaller | |
# --Scope: All Computers | |
# --Frequency: Once per Computer | |
# Files and Processes settings: | |
# --Execute Command: Whatever your $UnInstallerScriptPath is set to. | |
# | |
# In your DEPNotify.sh script, include the policy near the end of your POLICY_ARRAY. | |
# | |
# Paste your script's contents between the two "ENDOFUNINSTALLERSCRIPT" lines. | |
# NOTE: Make sure to leave a full return at the end of the Script content before the last "ENDOFUNINSTALLERSCRIPT" line. | |
echo "Creating ${UnInstallerScriptPath}." | |
( | |
cat <<ENDOFUNINSTALLERSCRIPT | |
#!/bin/zsh | |
# This is meant to be called by a Jamf Pro policy via trigger | |
# Near the end of your POLICY_ARRAY in your DEPNotify.sh script | |
rm ${TempUtilitiesPath}/${DEPNotifyInstallerName} | |
rm ${InstallerScriptPath} | |
#Note that if you unload the LaunchDaemon this will immediately kill the depNotify.sh script | |
#Just remove the underlying plist file, and the LaunchDaemon will not run after next reboot/login. | |
rm ${LaunchDaemonPath} | |
rm ${UnInstallerScriptPath} | |
rmdir ${TempUtilitiesPath} | |
exit 0 | |
exit 1 | |
ENDOFUNINSTALLERSCRIPT | |
) > "${UnInstallerScriptPath}" | |
echo "Setting permissions for ${UnInstallerScriptPath}." | |
chmod 644 "${UnInstallerScriptPath}" | |
chown root:wheel "${UnInstallerScriptPath}" | |
exit 0 ## Success | |
exit 1 ## Failure |
Line 73: Updated description in comment.
Line 11: Changed "Jame" to "Jamf"
Lines 42 and 43: Corrected shell script names
Thanks Christopher Stout.
Changed instances of -trigger (legacy) to -event.
Now that https://gitlab.com/Mactroll/DEPNotify/-/tags names the package DEPNotify.pkg by default, instead of with the version name (like DEPNotify.pkg-1.1.4.pkg), updated the value of $DEPNotifyInstallerName.
Love your script.
between line 88 & 89 worth adding this or similar. Will ensure DEPNotify does not launch until desktop is present for new user accounts.
dockStatus=$(pgrep -x Dock)
log "Waiting for Desktop"
while [ "$dockStatus" == "" ]; do
log "Desktop is not loaded. Waiting."
sleep 2
dockStatus=$(pgrep -x Dock)
done
if you're using Jamf, i would change those log commands to echo. Policy logs don't like the log command
Removed the line that used launchctl to unload the LaunchDaemon, and added comments about why you shouldn't unload the LaunchDaemon.