Skip to main content

Hi All,



Lets share idea's about how to upgrade to macOS Mojave via;




  • Self Service

  • App Store

  • Others



Also an idea to share idea's an how to upgrade from 10.14.1 to 10.14.2 due the new Software Update pane in Sysprefs.



Cheers.

@hpavlic. thank you!



I've added this, and Mojave installed successfully.. unfortunately the end user is still an admin after install, and the laptop has forgotten our staff WiFi network (we push the SSID and password via a Config Profile)



Any thoughts on how we might resolve this?



Thanks so much!


Awesome to see al that help in this community! i am still using a huge part of @bpavlov his work! currently migrated 300+- devices from 10.13.4/5/6 to 10.14.0/1 and less that 10 IT tickets!


@billystanton29



Did you also add the part I mentioned to finishOSInstall.sh ?



Also, in there there is a line



## Update Device Inventory
/usr/local/jamf/bin/jamf recon


You can add after that something like



## Running manage
/usr/local/jamf/bin/jamf manage


So that way it will run "jamf manage" after recon to pull the Configuration Profile to the machine.



Let me know if it worked.


@hpavlic.



Issue with the Admin rights is resolved now thank you 🙂



The WiFi issue still persists though.. The machine already has the WiFi policy, and strangely enough I can see the WiFi SSID in the "remembered networks".



A restart of the Mac still doesn't pick it up.



If I exclude the user from the profile, and then re-scope it to them then it works perfectly, but this relies on them having an ethernet connection which some of our users don't have. (The profile is computer level, should it be user level maybe?)



The SSID is hidden, so I'm wondering if this is stopping the Mac from finding the network and auto-joining?



Sorry, I'm a bit stuck! - Thanks once again for your help on this!


@billystanton29



I'm guessing that you have AD certificate payload since it requires them to be connected to wired network ....
We have AD cert. payload and I didn't notice that users lost their preferred network or conf. profile...



Do you have a specific scope for that Configuration Profile or specific setting in it that can maybe interfere during installation/restart?


@hpavlic.



I don't believe we have an AD Cert.



We bind to AD manually during laptop setup (Though create mobile accounts)



Our WiFi profile is set to All Users / All Computers and Auto Join and Hidden Network are both ticked.



It's almost like the Mac forgets that it knows those WiFi details until we remind it by either manually entering it, or removing and re-adding the WiFi profile for that machine.



Is there a way we can get JAMF to re-push the WiFi profile out again after the upgrade is finished, without us having to manually exclude and re-add users from the policy each time?


@hpavlic. Can you post the full version of your modified upgrade script that includes the promotion of user to admin and the finishOSinstall.sh extra bits. Just want unavoid issues trying to edit the wrong places, so i can test.



Also does your edited script reverse reverting the current user to standard? In our case we typically have a standard account, a local admin account, and the admin jamf management account in place on all machines. Just want to make sure post-upgrade, everyone's privilege level remains the same.


@billystanton29



hmmm that is weird, I tried to set-up profile re-push so many times but it is tricky, mostly because we use AD certificates for Wi-Fi authentication so it is hard (Conf. profile fails if user is not on wired and the only way to re push was to have user connected via wire and then run removeMDM profile, Jamf manage and it is a messy situation).



What I can recommend is creating a dummy file somewhere on the Mac and then compile EA that will read if the file is present.
Then create Smart Computer Group that detects if file is present (based on EA) and put that group in Exclusion for the scope of the configuration profile.
So the process would be something like a script which will do the following:
1. Create dummy file
2. run "Jamf recon" and "Jamf Manage"
3. Delete dummy file
4. run "recon" and "manage"
And it gets more complicated if you want to have a detection method to see if conf. profile is present after.



@jlang_remedy



Sure I can share, I have modified some stuff so please take this in consideration:




  1. This script will not check if AC is connected, it will check if the battery is more than 80% (reason behind that is: most of our users tend to be wireless, not plugged in etc. and we are planning to use the same script for push later on. While testing we noticed that during the upgrade battery is drained for 30-40% so we should be fine with battery level higher than 80%)


  2. On line 228, we only put 10GB as required space, Apple recommends 8,something.


  3. Yes, the adding user to admin group is part of the script and it will add user that is currently running the Policy as admin, create dummy file and remove them after reboot.




Please note that I noticed some minor flaws in this design and will try to fix them when I get the time.
Flaw is that LaunchDaemon is started when user logs in, ANY user. So if you run the policy as let's say John, John will get Admin rights, machine starts the upgrade, restarts, you are staring at the logon screen and log in as Administrator or for example Mary, LaunchDaemon will run, see that Administrator or Mary do not have the dummy file, run the rest of the script and self-destruct meaning that when John logs in he will still be administrator.
It would be better to put in the script that it searches for dummy file, find what user has it and demotes them, but need to work it out and find best approach.



Also, since we do not have FV2 enabled, didn't yet test this script against encrypted machines, so please test it out before going into production.



Here is the script:



#!/bin/bash

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Copyright (c) 2018 Jamf. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Jamf nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# This script was designed to be used in a Self Service policy to ensure specific
# requirements have been met before proceeding with an inplace upgrade of the macOS,
# as well as to address changes Apple has made to the ability to complete macOS upgrades
# silently.
#
# VERSION: v2.7.2.1
#
# REQUIREMENTS:
# - Jamf Pro
# - macOS Clients running version 10.10.5 or later
# - macOS Installer 10.12.4 or later
# - eraseInstall option is ONLY supported with macOS Installer 10.13.4+ and client-side macOS 10.13+
# - Look over the USER VARIABLES and configure as needed.
#
#
# For more information, visit https://github.com/kc9wwh/macOSUpgrade
#
#
# Written by: Joshua Roskos | Jamf
#
# Created On: January 5th, 2017
# Updated On: September 28th, 2018
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# USER VARIABLES
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

##Specify path to OS installer. Use Parameter 4 in the JSS, or specify here
##Example: /Applications/Install macOS High Sierra.app
OSInstaller="$4"

##Version of Installer OS. Use Parameter 5 in the JSS, or specify here.
##Example Command: /usr/libexec/PlistBuddy -c 'Print :"System Image Info":version' "/Applications/Install macOS High Sierra.app/Contents/SharedSupport/InstallInfo.plistr"
##Example: 10.12.5
version="$5"
versionMajor=$( /bin/echo "$version" | /usr/bin/awk -F. '{print $2}' )
versionMinor=$( /bin/echo "$version" | /usr/bin/awk -F. '{print $3}' )

##Custom Trigger used for download. Use Parameter 6 in the JSS, or specify here.
##This should match a custom trigger for a policy that contains just the
##MacOS installer. Make sure that the policy is scoped properly
##to relevant computers and/or users, or else the custom trigger will
##not be picked up. Use a separate policy for the script itself.
##Example trigger name: download-sierra-install
download_trigger="$6"

##MD5 Checksum of InstallESD.dmg
##This variable is OPTIONAL
##Leave the variable BLANK if you do NOT want to verify the checksum (DEFAULT)
##Example Command: /sbin/md5 /Applications/Install macOS High Sierra.app/Contents/SharedSupport/InstallESD.dmg
##Example MD5 Checksum: b15b9db3a90f9ae8a9df0f81741efa2b
installESDChecksum="$7"

##Valid Checksum? O (Default) for false, 1 for true.
validChecksum=0

##Unsuccessful Download? 0 (Default) for false, 1 for true.
unsuccessfulDownload=0

##Erase & Install macOS (Factory Defaults)
##Requires macOS Installer 10.13.4 or later
##Disabled by default
##Options: 0 = Disabled / 1 = Enabled
##Use Parameter 8 in the JSS.
eraseInstall="$8"
if [[ "${eraseInstall:=0}" != 1 ]]; then eraseInstall=0 ; fi
#macOS Installer 10.13.3 or ealier set 0 to it.
if [ "$versionMajor${versionMinor:=0}" -lt 134 ]; then
eraseInstall=0
fi

##Enter 0 for Full Screen, 1 for Utility window (screenshots available on GitHub)
##Full Screen by default
##Use Parameter 9 in the JSS.
userDialog="$9"
if [[ ${userDialog:=0} != 1 ]]; then userDialog=0 ; fi

##Title of OS
##Example: macOS High Sierra
macOSname=$(/bin/echo "$OSInstaller" | /usr/bin/sed 's/^/Applications/Install (.*).app$/1/')

##Title to be used for userDialog (only applies to Utility Window)
title="$macOSname Upgrade"

##Heading to be used for userDialog
heading="Please wait as we prepare your computer for $macOSname..."

##Title to be used for userDialog
description="This process will take approximately 5-10 minutes.
Once completed your computer will reboot and begin the upgrade."

##Description to be used prior to downloading the OS installer
dldescription="We need to download $macOSname to your computer, this will
take several minutes."

##Jamf Helper HUD Position if macOS Installer needs to be downloaded
##Options: ul (Upper Left); ll (Lower Left); ur (Upper Right); lr (Lower Right)
##Leave this variable empty for HUD to be centered on main screen
dlPosition="ul"

##Icon to be used for userDialog
##Default is macOS Installer logo which is included in the staged installer package
icon="$OSInstaller/Contents/Resources/InstallAssistant.icns"

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# FUNCTIONS
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

downloadInstaller() {
/bin/echo "Downloading macOS Installer..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper
-windowType hud -windowPosition $dlPosition -title "$title" -alignHeading center -alignDescription left -description "$dldescription"
-lockHUD -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/SidebarDownloadsFolder.icns" -iconSize 100 &
##Capture PID for Jamf Helper HUD
jamfHUDPID=$!
##Run policy to cache installer
/usr/local/jamf/bin/jamf policy -event "$download_trigger"
##Kill Jamf Helper HUD post download
/bin/kill "${jamfHUDPID}"
}

verifyChecksum() {
if [[ "$installESDChecksum" != "" ]]; then
osChecksum=$( /sbin/md5 -q "$OSInstaller/Contents/SharedSupport/InstallESD.dmg" )
if [[ "$osChecksum" == "$installESDChecksum" ]]; then
/bin/echo "Checksum: Valid"
validChecksum=1
return
else
/bin/echo "Checksum: Not Valid"
/bin/echo "Beginning new dowload of installer"
/bin/rm -rf "$OSInstaller"
/bin/sleep 2
downloadInstaller
fi
else
##Checksum not specified as script argument, assume true
validChecksum=1
return
fi
}

cleanExit() {
/bin/kill "${caffeinatePID}"
exit "$1"
}

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# SYSTEM CHECKS
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

##Caffeinate
/usr/bin/caffeinate -dis &
caffeinatePID=$!

##Get Current User
currentUser=$( /usr/bin/stat -f %Su /dev/console )

##Get Current Users homefolder
currentUserHomeDirectory=$( /usr/bin/dscl . -read "/users/$currentUser" NFSHomeDirectory | cut -d " " -f 2 )

##Check if current user is an admin
/usr/bin/dscl . read /Groups/admin GroupMembership | tr ' ' '
' | grep -x "$currentUser"
if [[ $? -ne 0 ]] ; then
/bin/echo "User is not an Admin. Adding $currentUser to Admin group"
/usr/sbin/dseditgroup -o edit -a "$currentUser" -t user admin
/bin/echo "Demote token file added for $currentUser at $currentUserHomeDirectory/.demoteafterupgrade"
/usr/bin/touch "$currentUserHomeDirectory"/.demoteafterupgrade
fi

##Check if FileVault Enabled
fvStatus=$( /usr/bin/fdesetup status | head -1 )

## Check if battery is below 80%
battLevel=$( pmset -g ps | sed -n 's/.*[[:blank:]]+*(.*%).*/1/p' )
if [[ ${battLevel} > *"80"* ]]; then
pwrStatus="OK"
/bin/echo "Power Check: OK - Battery above 80%"
else
pwrStatus="ERROR"
/bin/echo "Power Check: ERROR - Battery level below 80%"
fi


##Check if free space > 10GB
osMajor=$( /usr/bin/sw_vers -productVersion | /usr/bin/awk -F. '{print $2}' )
osMinor=$( /usr/bin/sw_vers -productVersion | /usr/bin/awk -F. '{print $3}' )
if [[ $osMajor -eq 12 ]] || [[ $osMajor -eq 13 && $osMinor -lt 4 ]]; then
freeSpace=$( /usr/sbin/diskutil info / | /usr/bin/grep "Available Space" | /usr/bin/awk '{print $6}' | /usr/bin/cut -c 2- )
else
freeSpace=$( /usr/sbin/diskutil info / | /usr/bin/grep "Free Space" | /usr/bin/awk '{print $6}' | /usr/bin/cut -c 2- )
fi

if [[ ${freeSpace%.*} -ge 10000000000 ]]; then
spaceStatus="OK"
/bin/echo "Disk Check: OK - ${freeSpace%.*} Bytes Free Space Detected"
else
spaceStatus="ERROR"
/bin/echo "Disk Check: ERROR - ${freeSpace%.*} Bytes Free Space Detected"
fi

##Check for existing OS installer
loopCount=0
while [[ $loopCount -lt 3 ]]; do
if [ -e "$OSInstaller" ]; then
/bin/echo "$OSInstaller found, checking version."
OSVersion=$(/usr/libexec/PlistBuddy -c 'Print :"System Image Info":version' "$OSInstaller/Contents/SharedSupport/InstallInfo.plist")
/bin/echo "OSVersion is $OSVersion"
if [ "$OSVersion" = "$version" ]; then
/bin/echo "Installer found, version matches. Verifying checksum..."
verifyChecksum
else
##Delete old version.
/bin/echo "Installer found, but old. Deleting..."
/bin/rm -rf "$OSInstaller"
/bin/sleep 2
downloadInstaller
fi
if [ "$validChecksum" == 1 ]; then
unsuccessfulDownload=0
break
fi
else
downloadInstaller
fi

unsuccessfulDownload=1
((loopCount++))
done

if (( unsuccessfulDownload == 1 )); then
/bin/echo "macOS Installer Downloaded 3 Times - Checksum is Not Valid"
/bin/echo "Prompting user for error and exiting..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "Error Downloading $macOSname" -description "We were unable to prepare your computer for $macOSname. Please contact the IT Support Center." -iconSize 100 -button1 "OK" -defaultButton 1
cleanExit 0
fi


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# CREATE FIRST BOOT SCRIPT
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

/bin/mkdir -p /usr/local/jamfps

/bin/cat > /usr/local/jamfps/finishOSInstall.sh <<'EOL'
#!/bin/bash

## Wait for Dock
while true; do
myUser=`whoami`
dockcheck=`ps -ef | grep [/]System/Library/CoreServices/Dock.app/Contents/MacOS/Dock`
if [ ! -z "${dockcheck}" ]; then
echo "Dockcheck is ${dockcheck}, breaking."
break
fi
sleep 1
done

##Demote if user was not an admin before upgrade
##Get Current User
currentUser=$( /usr/bin/stat -f %Su /dev/console )

##Get Current Users homefolder
currentUserHomeDirectory=$( /usr/bin/dscl . -read "/users/$currentUser" NFSHomeDirectory | cut -d " " -f 2 )
if [[ -e "$currentUserHomeDirectory"/.demoteafterupgrade ]] ; then
/bin/echo "User was not an Admin before upgrade, Removing $currentUser from Admin group"
dseditgroup -o edit -d "$currentUser" -t user admin
/bin/echo "Demote token file removed for $currentUser at $currentUserHomeDirectory/.demoteafterupgrade"
rm -f "$currentUserHomeDirectory"/.demoteafterupgrade
fi

## First Run Script to remove the installer.
## Clean up files
/bin/rm -fr "$OSInstaller"
/bin/sleep 2

## Update Device Inventory
/usr/local/jamf/bin/jamf recon

## Remove LaunchDaemon
/bin/rm -f /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist

## Remove Script
/bin/rm -fr /usr/local/jamfps

exit 0
EOL

/usr/sbin/chown root:admin /usr/local/jamfps/finishOSInstall.sh
/bin/chmod 755 /usr/local/jamfps/finishOSInstall.sh

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# LAUNCH DAEMON
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

/bin/cat << EOF > /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist
<?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>com.jamfps.cleanupOSInstall</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/usr/local/jamfps/finishOSInstall.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF

##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist
/bin/chmod 644 /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# LAUNCH AGENT FOR FILEVAULT AUTHENTICATED REBOOTS
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

##Determine Program Argument
if [[ $osMajor -ge 11 ]]; then
progArgument="osinstallersetupd"
elif [[ $osMajor -eq 10 ]]; then
progArgument="osinstallersetupplaind"
fi

/bin/cat << EOP > /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
<?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>com.apple.install.osinstallersetupd</string>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>MachServices</key>
<dict>
<key>com.apple.install.osinstallersetupd</key>
<true/>
</dict>
<key>TimeOut</key>
<integer>300</integer>
<key>OnDemand</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>$OSInstaller/Contents/Frameworks/OSInstallerSetup.framework/Resources/$progArgument</string>
</array>
</dict>
</plist>
EOP

##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
/bin/chmod 644 /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# APPLICATION
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ ${pwrStatus} == "OK" ]] && [[ ${spaceStatus} == "OK" ]]; then
##Launch jamfHelper
if [ ${userDialog} -eq 0 ]; then
/bin/echo "Launching jamfHelper as FullScreen..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType fs -title "" -icon "$icon" -heading "$heading" -description "$description" &
jamfHelperPID=$!
else
/bin/echo "Launching jamfHelper as Utility Window..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "$heading" -description "$description" -iconSize 100 &
jamfHelperPID=$!
fi
##Load LaunchAgent
if [[ ${fvStatus} == "FileVault is On." ]] && [[ ${currentUser} != "root" ]]; then
userID=$( /usr/bin/id -u "${currentUser}" )
/bin/launchctl bootstrap gui/"${userID}" /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
fi
##Begin Upgrade
/bin/echo "Launching startosinstall..."
##Check if eraseInstall is Enabled
if [[ $eraseInstall == 1 ]]; then
eraseopt='--eraseinstall'
/bin/echo " Script is configured for Erase and Install of macOS."
fi

osinstallLogfile="/var/log/startosinstall.log"
if [ "$versionMajor" -ge 14 ]; then
eval sudo nohup ""$OSInstaller/Contents/Resources/startosinstall"" "$eraseopt" --agreetolicense --nointeraction --pidtosignal "$jamfHelperPID" >> "$osinstallLogfile" &
else
eval /usr/bin/nohup ""$OSInstaller/Contents/Resources/startosinstall"" "$eraseopt" --applicationpath ""$OSInstaller"" --agreetolicense --nointeraction --pidtosignal "$jamfHelperPID" >> "$osinstallLogfile" &
fi
/bin/sleep 3
else
## Remove Script
/bin/rm -f /usr/local/jamfps/finishOSInstall.sh
/bin/rm -f /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist
/bin/rm -f /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist

/bin/echo "Launching jamfHelper Dialog (Requirements Not Met)..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "Requirements Not Met" -description "We were unable to prepare your computer for $macOSname. Please ensure you are connected to power and that you have at least 15GB of Free Space.

If you continue to experience this issue, please contact the IT Support Center." -iconSize 100 -button1 "OK" -defaultButton 1

fi

cleanExit 0


If you notice any errors or have recommendations how to do things differently please let me know.


Thanks. @hpavlic. I edited this to revert back to the original power check, and ran this on a test machine currently on 10.12.6 and for some reason the machine still got stuck on the pre-upgrade splash screen. I have mine running as a utility window I opened User's and groups in sys prefs and did in fact see the current user was promoted to admin, but the upgrade just won't start. I didn not get prompted for OSinstallersetupd as before though which is good. JSS logs show the below and the log file in the script for the install is showing empty when I open it.



[STEP 1 of 4]
Executing Policy Install MacOS Mojave
[STEP 2 of 4]
Running script 10.14.1...
Script exit code: 0
Script result: User is not an Admin. Adding atest to Admin group
Demote token file added for atest at /Users/atest/.demoteafterupgrade
Power Check: OK - AC Power Detected
Launching jamfHelper as Utility Window...
/Library/LaunchAgents/com.apple.install.osinstallersetupd.plist: service already loaded
Launching startosinstall...
[STEP 3 of 4]
[STEP 4 of 4]



Perhaps I need to try another machine maybe 10.13.x and see if I get any better results with this.


@jlang_remedy



Can you please check what does it say in the startosinstall log, located under /var/log/startosinstall.log?



From that we can get more information


Here's what I'm doing to avoid the "osinstallersetupd wants to make changes" issue:



Prior to invoking startosinstall:



## Elevation to avoid osinstallersetupd issue.
/usr/sbin/dseditgroup -q -o create -n /Local/Default -r "Admin access for macOS upgrade" upgradeadmin
/usr/sbin/dseditgroup -q -o edit -n /Local/Default -a upgradeadmin -t group admin
/usr/sbin/dseditgroup -o edit -a "${currentUser}" -t user upgradeadmin
/usr/bin/dsmemberutil flushcache


Added to the finishOSinstall.sh:



/usr/sbin/dseditgroup -o delete -n /Local/Default upgradeadmin
/usr/bin/dsmemberutil flushcache


If they were already a member of the admin group, that will remain unchanged. If they weren't, they got elevated through a temporary nested group, and the finish script can delete that group without worrying about who is logged in or any pre-existing membership.



In my case, users on staff machines already have admin access, so the upgrade from 10.13 and below would go smoothly. I noticed this during 10.14-to-10.14 "upgrade"/refresh installs, because as part of our Cybersecurity program, we're stripping off default admin access, to be replaced by targeted authorizationdb access to certain functionality. I still expect to need to accommodate the possibility of an admin exception (approved by our Cyber team).


We have noticed that if we push the macOS Mojave installer via VPP to the machine, they get a notification to restart and install the OS automatically. This is also true when placed in Self Service. Might be worth a try for you all as it doesn't require any work on your end. Only was able to confirm that the user receives this message if on 10.13 and 10.14 so far.





Cheers,
Chris


@deej



Great idea, this is an excellent solution! It removes the need to put a dummy file and works for all users.



Placed it into my script and it is working as expected.



Thank you :)


@hpavlic. the /var/log/starttoinstall.log file is empty so I can't seem to pin-point what's causing the hang as yet.



Also, can you or @deej post the full version of the script which includes @deej's latest edit to solve the admin issue.



Just want to be doubly sure all the bits that need to be removed/added are done in the right place in the script to avoid any inadvertent issues.


For those who have been able to upgrade from 10.12 & 10.13 to 10.14 successfully, I am hoping you can help me identify why it's still not working for me. What makes it hard is that I don't know where it is failing in the install process.




  • The installer downloads and installs fine.

  • The process gets somewhere hung up at the startosinstall.

  • The startosinstall.log is empty.



Any ideas what might be causing the upgrade issue? Some users are saying that the computer reboots and then looks to install, but when they log back in, it hasn't been upgraded.



All our computers are encrypted via FileVault if that matters.



Here is the JAMF log from a failed upgrade. This user was on 10.12.6





And here is the section of the script that I think its getting hung up on, but its just a guess:



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# APPLICATION
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ ${pwrStatus} == "OK" ]] && [[ ${spaceStatus} == "OK" ]]; then
##Launch jamfHelper
if [ ${userDialog} -eq 0 ]; then
/bin/echo "Launching jamfHelper as FullScreen..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType fs -title "" -icon "$icon" -heading "$heading" -description "$description" &
jamfHelperPID=$!
else
/bin/echo "Launching jamfHelper as Utility Window..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "$heading" -description "$description" -iconSize 100 &
jamfHelperPID=$!
fi
##Load LaunchAgent
if [[ ${fvStatus} == "FileVault is On." ]] && [[ ${currentUser} != "root" ]]; then
userID=$( /usr/bin/id -u "${currentUser}" )
/bin/launchctl bootstrap gui/"${userID}" /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
fi
##Begin Upgrade
/bin/echo "Launching startosinstall..."
consoleUser=`ls -l /dev/console | cut -d " " -f4`
effectiveUserID=$(/usr/bin/id -u "$consoleUser")
/bin/launchctl asuser "$effectiveUserID" sudo -u "$consoleUser" /usr/bin/open /Applications/Install macOS Mojave.app
sleep 5
/bin/launchctl asuser "$effectiveUserID" sudo -u "$consoleUser" osascript -e 'quit app "Install macOS Mojave"'
/Applications/Install macOS Mojave.app/Contents/Resources/startosinstall --applicationpath "/Applications/Install macOS Mojave.app" --nointeraction --pidtosignal $jamfHelperPID &
/bin/sleep 3
##Check if eraseInstall is Enabled
if [[ $eraseInstall == 1 ]]; then
eraseopt='--eraseinstall'
/bin/echo " Script is configured for Erase and Install of macOS."
fi

osinstallLogfile="/var/log/startosinstall.log"
if [ "$versionMajor" -ge 14 ]; then
eval /usr/bin/nohup ""$OSInstaller/Contents/Resources/startosinstall"" "$eraseopt" --agreetolicense --nointeraction --pidtosignal "$jamfHelperPID" >> "$osinstallLogfile" &
else
eval /usr/bin/nohup ""$OSInstaller/Contents/Resources/startosinstall"" "$eraseopt" --applicationpath ""$OSInstaller"" --agreetolicense --nointeraction --pidtosignal "$jamfHelperPID" >> "$osinstallLogfile" &
fi
/bin/sleep 3
else
## Remove Script
/bin/rm -f /usr/local/jamfps/finishOSInstall.sh
/bin/rm -f /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist
/bin/rm -f /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist

/bin/echo "Launching jamfHelper Dialog (Requirements Not Met)..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "Requirements Not Met" -description "We were unable to prepare your computer for $macOSname. Please ensure you are connected to power and that you have at least 15GB of Free Space.

If you continue to experience this issue, please contact the IT Support Center." -iconSize 100 -button1 "OK" -defaultButton 1

fi

cleanExit 0

@danshaw



Im guessing that this is the culprit, you have ##Begin Upgrade part where it tries to launch Mojave



/Applications/Install macOS Mojave.app/Contents/Resources/startosinstall --applicationpath "/Applications/Install macOS Mojave.app" --nointeraction --pidtosignal $jamfHelperPID &


And "--applicationpath" portion is not viable with Mojave.



This part after ##Begin Upgrade is not necessary in the script since the install is executed later:



    consoleUser=`ls -l /dev/console | cut -d " " -f4`
effectiveUserID=$(/usr/bin/id -u "$consoleUser")
/bin/launchctl asuser "$effectiveUserID" sudo -u "$consoleUser" /usr/bin/open /Applications/Install macOS Mojave.app
sleep 5
/bin/launchctl asuser "$effectiveUserID" sudo -u "$consoleUser" osascript -e 'quit app "Install macOS Mojave"'
/Applications/Install macOS Mojave.app/Contents/Resources/startosinstall --applicationpath "/Applications/Install macOS Mojave.app" --nointeraction --pidtosignal $jamfHelperPID &
/bin/sleep 3


@jlang_remedy



Could you check the /var/log/install.log or policy log on the Jamf Console?
Here is the script, hope it helps:



#!/bin/bash

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Copyright (c) 2018 Jamf. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Jamf nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# This script was designed to be used in a Self Service policy to ensure specific
# requirements have been met before proceeding with an inplace upgrade of the macOS,
# as well as to address changes Apple has made to the ability to complete macOS upgrades
# silently.
#
# VERSION: v2.7.2.1
#
# REQUIREMENTS:
# - Jamf Pro
# - macOS Clients running version 10.10.5 or later
# - macOS Installer 10.12.4 or later
# - eraseInstall option is ONLY supported with macOS Installer 10.13.4+ and client-side macOS 10.13+
# - Look over the USER VARIABLES and configure as needed.
#
#
# For more information, visit https://github.com/kc9wwh/macOSUpgrade
#
#
# Written by: Joshua Roskos | Jamf
#
# Created On: January 5th, 2017
# Updated On: September 28th, 2018
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# USER VARIABLES
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

##Specify path to OS installer. Use Parameter 4 in the JSS, or specify here
##Example: /Applications/Install macOS High Sierra.app
OSInstaller="$4"

##Version of Installer OS. Use Parameter 5 in the JSS, or specify here.
##Example Command: /usr/libexec/PlistBuddy -c 'Print :"System Image Info":version' "/Applications/Install macOS High Sierra.app/Contents/SharedSupport/InstallInfo.plistr"
##Example: 10.12.5
version="$5"
versionMajor=$( /bin/echo "$version" | /usr/bin/awk -F. '{print $2}' )
versionMinor=$( /bin/echo "$version" | /usr/bin/awk -F. '{print $3}' )

##Custom Trigger used for download. Use Parameter 6 in the JSS, or specify here.
##This should match a custom trigger for a policy that contains just the
##MacOS installer. Make sure that the policy is scoped properly
##to relevant computers and/or users, or else the custom trigger will
##not be picked up. Use a separate policy for the script itself.
##Example trigger name: download-sierra-install
download_trigger="$6"

##MD5 Checksum of InstallESD.dmg
##This variable is OPTIONAL
##Leave the variable BLANK if you do NOT want to verify the checksum (DEFAULT)
##Example Command: /sbin/md5 /Applications/Install macOS High Sierra.app/Contents/SharedSupport/InstallESD.dmg
##Example MD5 Checksum: b15b9db3a90f9ae8a9df0f81741efa2b
installESDChecksum="$7"

##Valid Checksum? O (Default) for false, 1 for true.
validChecksum=0

##Unsuccessful Download? 0 (Default) for false, 1 for true.
unsuccessfulDownload=0

##Erase & Install macOS (Factory Defaults)
##Requires macOS Installer 10.13.4 or later
##Disabled by default
##Options: 0 = Disabled / 1 = Enabled
##Use Parameter 8 in the JSS.
eraseInstall="$8"
if [[ "${eraseInstall:=0}" != 1 ]]; then eraseInstall=0 ; fi
#macOS Installer 10.13.3 or ealier set 0 to it.
if [ "$versionMajor${versionMinor:=0}" -lt 134 ]; then
eraseInstall=0
fi

##Enter 0 for Full Screen, 1 for Utility window (screenshots available on GitHub)
##Full Screen by default
##Use Parameter 9 in the JSS.
userDialog="$9"
if [[ ${userDialog:=0} != 1 ]]; then userDialog=0 ; fi

##Title of OS
##Example: macOS High Sierra
macOSname=$(/bin/echo "$OSInstaller" | /usr/bin/sed 's/^/Applications/Install (.*).app$/1/')

##Title to be used for userDialog (only applies to Utility Window)
title="$macOSname Upgrade"

##Heading to be used for userDialog
heading="Please wait as we prepare your computer for $macOSname..."

##Title to be used for userDialog
description="This process will take approximately 5-10 minutes.
Once completed your computer will reboot and begin the upgrade."

##Description to be used prior to downloading the OS installer
dldescription="We need to download $macOSname to your computer, this will
take several minutes."

##Jamf Helper HUD Position if macOS Installer needs to be downloaded
##Options: ul (Upper Left); ll (Lower Left); ur (Upper Right); lr (Lower Right)
##Leave this variable empty for HUD to be centered on main screen
dlPosition="ul"

##Icon to be used for userDialog
##Default is macOS Installer logo which is included in the staged installer package
icon="$OSInstaller/Contents/Resources/InstallAssistant.icns"

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# FUNCTIONS
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

downloadInstaller() {
/bin/echo "Downloading macOS Installer..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper
-windowType hud -windowPosition $dlPosition -title "$title" -alignHeading center -alignDescription left -description "$dldescription"
-lockHUD -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/SidebarDownloadsFolder.icns" -iconSize 100 &
##Capture PID for Jamf Helper HUD
jamfHUDPID=$!
##Run policy to cache installer
/usr/local/jamf/bin/jamf policy -event "$download_trigger"
##Kill Jamf Helper HUD post download
/bin/kill "${jamfHUDPID}"
}

verifyChecksum() {
if [[ "$installESDChecksum" != "" ]]; then
osChecksum=$( /sbin/md5 -q "$OSInstaller/Contents/SharedSupport/InstallESD.dmg" )
if [[ "$osChecksum" == "$installESDChecksum" ]]; then
/bin/echo "Checksum: Valid"
validChecksum=1
return
else
/bin/echo "Checksum: Not Valid"
/bin/echo "Beginning new dowload of installer"
/bin/rm -rf "$OSInstaller"
/bin/sleep 2
downloadInstaller
fi
else
##Checksum not specified as script argument, assume true
validChecksum=1
return
fi
}

cleanExit() {
/bin/kill "${caffeinatePID}"
exit "$1"
}

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# SYSTEM CHECKS
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

##Caffeinate
/usr/bin/caffeinate -dis &
caffeinatePID=$!

##Get Current User
currentUser=$( /usr/bin/stat -f %Su /dev/console )

##Get Current Users homefolder
currentUserHomeDirectory=$( /usr/bin/dscl . -read "/users/$currentUser" NFSHomeDirectory | cut -d " " -f 2 )

## Elevation to avoid osinstallersetupd issue.
/usr/sbin/dseditgroup -q -o create -n /Local/Default -r "Admin access for macOS upgrade" upgradeadmin
/usr/sbin/dseditgroup -q -o edit -n /Local/Default -a upgradeadmin -t group admin
/usr/sbin/dseditgroup -o edit -a "${currentUser}" -t user upgradeadmin
/usr/bin/dsmemberutil flushcache

##Check if FileVault Enabled
fvStatus=$( /usr/bin/fdesetup status | head -1 )

## Check if battery is below 80%
battLevel=$( pmset -g ps | sed -n 's/.*[[:blank:]]+*(.*%).*/1/p' )
if [[ ${battLevel} > *"80"* ]]; then
pwrStatus="OK"
/bin/echo "Power Check: OK - Battery above 80%"
else
#pwrStatus="ERROR"
pwrStatus="OK"
/bin/echo "Power Check: ERROR - Battery level below 80%"
fi


##Check if free space > 10GB
osMajor=$( /usr/bin/sw_vers -productVersion | /usr/bin/awk -F. '{print $2}' )
osMinor=$( /usr/bin/sw_vers -productVersion | /usr/bin/awk -F. '{print $3}' )
if [[ $osMajor -eq 12 ]] || [[ $osMajor -eq 13 && $osMinor -lt 4 ]]; then
freeSpace=$( /usr/sbin/diskutil info / | /usr/bin/grep "Available Space" | /usr/bin/awk '{print $6}' | /usr/bin/cut -c 2- )
else
freeSpace=$( /usr/sbin/diskutil info / | /usr/bin/grep "Free Space" | /usr/bin/awk '{print $6}' | /usr/bin/cut -c 2- )
fi

if [[ ${freeSpace%.*} -ge 10000000000 ]]; then
spaceStatus="OK"
/bin/echo "Disk Check: OK - ${freeSpace%.*} Bytes Free Space Detected"
else
spaceStatus="ERROR"
/bin/echo "Disk Check: ERROR - ${freeSpace%.*} Bytes Free Space Detected"
fi

##Check for existing OS installer
loopCount=0
while [[ $loopCount -lt 3 ]]; do
if [ -e "$OSInstaller" ]; then
/bin/echo "$OSInstaller found, checking version."
OSVersion=$(/usr/libexec/PlistBuddy -c 'Print :"System Image Info":version' "$OSInstaller/Contents/SharedSupport/InstallInfo.plist")
/bin/echo "OSVersion is $OSVersion"
if [ "$OSVersion" = "$version" ]; then
/bin/echo "Installer found, version matches. Verifying checksum..."
verifyChecksum
else
##Delete old version.
/bin/echo "Installer found, but old. Deleting..."
/bin/rm -rf "$OSInstaller"
/bin/sleep 2
downloadInstaller
fi
if [ "$validChecksum" == 1 ]; then
unsuccessfulDownload=0
break
fi
else
downloadInstaller
fi

unsuccessfulDownload=1
((loopCount++))
done

if (( unsuccessfulDownload == 1 )); then
/bin/echo "macOS Installer Downloaded 3 Times - Checksum is Not Valid"
/bin/echo "Prompting user for error and exiting..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "Error Downloading $macOSname" -description "We were unable to prepare your computer for $macOSname. Please contact the IT Support Center." -iconSize 100 -button1 "OK" -defaultButton 1
cleanExit 0
fi


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# CREATE FIRST BOOT SCRIPT
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

/bin/mkdir -p /usr/local/jamfps

/bin/cat > /usr/local/jamfps/finishOSInstall.sh <<'EOL'
#!/bin/bash

##Demote if user was not an admin before upgrade
/usr/sbin/dseditgroup -o delete -n /Local/Default upgradeadmin
/usr/bin/dsmemberutil flushcache

## First Run Script to remove the installer.
## Clean up files
/bin/rm -fr "$OSInstaller"
/bin/sleep 2

## Update Device Inventory
/usr/local/jamf/bin/jamf recon

## Remove LaunchDaemon
/bin/rm -f /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist

## Remove Script
/bin/rm -fr /usr/local/jamfps

exit 0
EOL

/usr/sbin/chown root:admin /usr/local/jamfps/finishOSInstall.sh
/bin/chmod 755 /usr/local/jamfps/finishOSInstall.sh

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# LAUNCH DAEMON
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

/bin/cat << EOF > /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist
<?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>com.jamfps.cleanupOSInstall</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/usr/local/jamfps/finishOSInstall.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF

##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist
/bin/chmod 644 /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# LAUNCH AGENT FOR FILEVAULT AUTHENTICATED REBOOTS
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

##Determine Program Argument
if [[ $osMajor -ge 11 ]]; then
progArgument="osinstallersetupd"
elif [[ $osMajor -eq 10 ]]; then
progArgument="osinstallersetupplaind"
fi

/bin/cat << EOP > /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
<?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>com.apple.install.osinstallersetupd</string>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>MachServices</key>
<dict>
<key>com.apple.install.osinstallersetupd</key>
<true/>
</dict>
<key>TimeOut</key>
<integer>300</integer>
<key>OnDemand</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>$OSInstaller/Contents/Frameworks/OSInstallerSetup.framework/Resources/$progArgument</string>
</array>
</dict>
</plist>
EOP

##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
/bin/chmod 644 /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# APPLICATION
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ ${pwrStatus} == "OK" ]] && [[ ${spaceStatus} == "OK" ]]; then
##Launch jamfHelper
if [ ${userDialog} -eq 0 ]; then
/bin/echo "Launching jamfHelper as FullScreen..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType fs -title "" -icon "$icon" -heading "$heading" -description "$description" &
jamfHelperPID=$!
else
/bin/echo "Launching jamfHelper as Utility Window..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "$heading" -description "$description" -iconSize 100 &
jamfHelperPID=$!
fi
##Load LaunchAgent
if [[ ${fvStatus} == "FileVault is On." ]] && [[ ${currentUser} != "root" ]]; then
userID=$( /usr/bin/id -u "${currentUser}" )
/bin/launchctl bootstrap gui/"${userID}" /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
fi
##Begin Upgrade
/bin/echo "Launching startosinstall..."
##Check if eraseInstall is Enabled
if [[ $eraseInstall == 1 ]]; then
eraseopt='--eraseinstall'
/bin/echo " Script is configured for Erase and Install of macOS."
fi

osinstallLogfile="/var/log/startosinstall.log"
if [ "$versionMajor" -ge 14 ]; then
eval /usr/bin/nohup ""$OSInstaller/Contents/Resources/startosinstall"" "$eraseopt" --agreetolicense --nointeraction --pidtosignal "$jamfHelperPID" >> "$osinstallLogfile" &
else
eval /usr/bin/nohup ""$OSInstaller/Contents/Resources/startosinstall"" "$eraseopt" --applicationpath ""$OSInstaller"" --agreetolicense --nointeraction --pidtosignal "$jamfHelperPID" >> "$osinstallLogfile" &
fi
/bin/sleep 3
else
## Remove Script
/bin/rm -f /usr/local/jamfps/finishOSInstall.sh
/bin/rm -f /Library/LaunchDaemons/com.jamfps.cleanupOSInstall.plist
/bin/rm -f /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist

/bin/echo "Launching jamfHelper Dialog (Requirements Not Met)..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$title" -icon "$icon" -heading "Requirements Not Met" -description "We were unable to prepare your computer for $macOSname. Please ensure you are connected to power and that you have at least 10GB of Free Space.

If you continue to experience this issue, please contact the IT Support Center." -iconSize 100 -button1 "OK" -defaultButton 1

fi

cleanExit 0

@hpavlic. Adding that dock piece to the script made it work for me!



The process runs through as designed. When complete my standard user is still a standard user and the device is on Mojave. Thank you for the help!


@glaske This looks cool. However the issue with this method is that installers are removed when a new OS is released, after which it won't be available for VPP.


Right now I am caching the Mojave installer on Macs. I have a policy in Self Service that appears once the installer is cached. The policy installs the cached installer and then runs a script that starts the Mojave upgrade. I have ran it on about 10 Macs with operating systems ranging from 10.9 to 10.13 and it works great.


@hpavlic., thank you for providing the script! Early tests are showing that this is working for me.



I did notice that you have the battery check part of your script commented to pass all the time. Were you finding that it wasn't accurate?



## Check if battery is below 80%
battLevel=$( pmset -g ps | sed -n 's/.*[[:blank:]]+*(.*%).*/1/p' )
if [[ ${battLevel} > *"80"* ]]; then
pwrStatus="OK"
/bin/echo "Power Check: OK - Battery above 80%"
else
#pwrStatus="ERROR"
pwrStatus="OK"
/bin/echo "Power Check: ERROR - Battery level below 80%"
fi

@danshaw



Ohhhhh, sorry about that, it is a mistake!!!
I was testing something on VM and that part fails as it cannot detect battery so I left it out and put pwrStatus=“OK”.
That should be commented out and power status OK removed!


I was testing on a VM and noticed the same thing! Good call.


.


@hpavlic. the JSS log looked normal, I think i copied it earlier in this thread. For /var/log/install.log I have to go back and check.
I did end up getting the original test machine to upgrade, FINALLY! but only after 2 or 3 reboots and retrying then it suddenly worked. I think I just need to do more testing but so far with 4 machines, all different model macbooks between 10.126 - 10.13.6 they all hung on the pre-upgrade on first try, then like my first test machine took a few reboots and retries to get it to work.



After a few more test upgrades if this still remains the case, i'll post my edited script to see if something is wrong there, although it wouldn't explain why it eventually works. Here's 2 questions I had though.




  1. I see as part of the finishOSinstall script there's a line to remove the Installer folder.



## Clean up files
/bin/rm -fr "$OSInstaller"
/bin/sleep 2


Doesn't the upgrade do that by default(unfortunately)? I took that line out, hoping to save the installer in the /Applications folder for future Erase and Install's but found it was deleted anyway even though I took that line out?




  1. I found a thread where someone ran startoinstall via command line instead of self service script and the CLI showed a percentage progress bar before the reboot kicks in.



    It would be totally awesome to have something similar on that black jamfhelper pre-upgrade waiting screen to at least indicate if progress is being made or not. For now, I simply wait 10 - 15 mins max and if the machine hasn't rebooted I assume it's stuck at that point, and I reboot for extra measure and try once more. To avoid running blind during this point, Is it possible to script a different utility window that can show the progress being made, ideally with verbose output to give indication everything is working or the process hasn't errored out and frozen. I think 1 out of 4 tests i tried did show something in /var/log/startosinstall.log which has been usually empty for me. It said Unable to create a preboot APFS volume. Not sure how to prevent such an error but at least that was helpful to know why it stopped in that 1 test scenario.



Has anyone been able to figure out a way to block users from upgrading via the app store and force them to upgrade in self service? Our users don't have admin rights so when they try they need admin creds, but using this script that @hpavlic. provided above, its using an admin account to do the upgrade and the process/app is getting blocked by the restriction I put into place.



I tried some fancy work such as laying down a dummy receipt at the beginning of the upgrade, scoping that to a smartgroup that excludes that computer from the restriction and then running sudo jamf manage, but that isn't working very well.



Wondering if anyone else has found a solution in their environments.