Upgrade from OS X 10.12 to OS X 10.14

Phantom155
New Contributor

We are having to upgrade from Sierra to Mojave. We have been tasked with trying to do this with little to no user interaction. The tests that we have run have failed. It seems that the Mojave installer stalls out. Here is the current workflow.

My current workflow is to use JAMF to cache a .dmg containing the Install macOS Mojave.app and copy the .app to /Applications/ . Then an execute command runs that launches the startosinstall service contained in the .app using the flags –agreetolicense –nointeraction to automate the install. This has worked perfectly on several High Sierra test boxes I have, but on the three Sierra boxes I’ve tried it on, the service hangs with this error repeated: com.apple.install.osinstallersetupd: Service only ran for 0 seconds. Pushing respawn out by 10 seconds. This repeats at respawn every 10 seconds until manually forced to quit.

3 REPLIES 3

larry_barrett
Valued Contributor

--eraseinstall only works with APFS volumes. Technically, you'd have to upgrade to High Sierra first.

tomhastings
Contributor II

If I remember, 10.13.4 (or.6) is the min. OS for the startosinstall flag to function.

HNTIT
Contributor II

This is the script I wrote to do this, not had it fail yet, but cant be 100% if i have tested it in the specific set of circumstances you have, but I am fairly sure i did.

I have Multiple Policies that call it that just parse different values to the 2 Variables depending on the OS I want and if we want an upgrade or a clean build.

Hope this Helps you

#!/bin/bash
#
###############################################################################################################################################
#
# DEFINE VARIABLES & READ IN PARAMETERS
#
###############################################################################################################################################
#
ScriptName="ZZ 21 - Management - Upgrade Operating System"
#
##Specify path to OS installer. Use Parameter 4 in the JSS.
##Example: /Applications/Install macOS High Sierra.app
OSInstaller="$4"
#
##Erase & Install macOS (Factory Defaults)
##Requires macOS Installer 10.13.4 or later
##Options: 0 = Disabled / 1 = Enabled
##Use Parameter 5 in the JSS.
eraseInstall="$5"
if [[ "${eraseInstall:=0}" != 1 ]]
    then 
        eraseInstall=0
fi
#
validChecksum=0
#
###############################################################################################################################################
#
# SCRIPT CONTENTS - DO NOT MODIFY BELOW THIS LINE
#
###############################################################################################################################################
#
# Defining Functions
#
###############################################################################################################################################
#
# CLEAN EXIT
#
cleanExit() {
    /bin/kill "${caffeinatePID}"
    exit "$1"
}
#
###############################################################################################################################################
#
# Script End Function
#
ScriptEnd(){
#
# Outputting a Blank Line for Reporting Purposes
/bin/echo
#
/bin/echo Ending Script '"'$ScriptName'"'
#
# Outputting a Blank Line for Reporting Purposes
/bin/echo
#
# Outputting a Dotted Line for Reporting Purposes
/bin/echo  -----------------------------------------------
#
# Outputting a Blank Line for Reporting Purposes
/bin/echo
#
}
#
###############################################################################################################################################
#
# PREFLIGHT CHECKS
#
preflightchecks() {
#
/bin/echo "Running PreFlight Checks"
/bin/echo  
#
##Caffeinate
/usr/bin/caffeinate -dis &
caffeinatePID=$!
#
osMajor=$( /usr/bin/sw_vers -productVersion | /usr/bin/awk -F. '{print $2}' )
osMinor=$( /usr/bin/sw_vers -productVersion | /usr/bin/awk -F. '{print $3}' )
#
##Check for existing OS installer
#
if [ -e "$OSInstaller" ]
    then
        /bin/echo "$OSInstaller found."
        /bin/echo
        #
        if [ -f "$OSInstaller/Contents/SharedSupport/InstallInfo.plist" ]
            then
                echo "File $OSInstaller/Contents/SharedSupport/InstallInfo.plist does exist."
                OSVersion=$(/usr/libexec/PlistBuddy -c 'Print :"System Image Info":version' "$OSInstaller/Contents/SharedSupport/InstallInfo.plist")
            else
                echo "File $OSInstaller/Contents/SharedSupport/InstallInfo.plist does NOT exist."
                echo "Trying $OSInstaller/Contents/version.plist"
                #
                if [ -f "$OSInstaller/Contents/version.plist" ]
                    then
                        echo "File $OSInstaller/version.plist does exist."
                        OSV=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$OSInstaller/Contents/version.plist")
                        OSVersion=$( /bin/echo 10.$OSV )
                        #
                    else
                        echo "File $OSInstaller/Contents/version.plist does NOT exist."
                fi
        fi
        #
        /bin/echo
        #
    else
        /bin/echo "$OSInstaller NOT found."
        ScriptEnd
        cleanExit 1
fi
#
versionMajor=$( /bin/echo "$OSVersion" | /usr/bin/awk -F. '{print $2}' )
versionMinor=$( /bin/echo "$OSVersion" | /usr/bin/awk -F. '{print $3}' )
#
if [[ ${osMajor} == ${versionMajor} ]]
    then
        if [[ $eraseInstall == 0 ]]
            then
                /bin/echo "macOS Major Version To Be Installed is 10.$versionMajor and Current Installed Version is 10.$osMajor"
                /bin/echo "Nothing To Do"
                ScriptEnd
                cleanExit 1
            else
                /bin/echo "macOS Version To Be Installed is $OSVersion"
        fi
    else
        /bin/echo "macOS Version To Be Installed is $OSVersion"
fi
#
/bin/echo
#
##Get Current User
currentUser=$( /usr/bin/stat -f %Su /dev/console )
/bin/echo "Current User is ${currentUser}"
#
##Check if FileVault Enabled
fvStatus=$( /usr/bin/fdesetup status | head -1 )
/bin/echo "FileVault Status = ${fvStatus}"
#
##Check if device is on battery or ac power
pwrAdapter=$( /usr/bin/pmset -g ps )
if [[ ${pwrAdapter} == *"AC Power"* ]]; then
    pwrStatus="OK"
    /bin/echo "Power Check: OK - AC Power Detected"
else
    pwrStatus="ERROR"
    /bin/echo "Power Check: ERROR - No AC Power Detected"
fi
#
##Check if free space > 15GB
#
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 15000000000 ]]; 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
#
/bin/echo  
#
}
#
###############################################################################################################################################
#
# CREATE FIRST BOOT SCRIPT
#
firstbootscript() {
#
/bin/mkdir -p /usr/local/jamfps
#
/bin/echo "Creating First Run Script to remove the installer"
/bin/echo    
#
#
/bin/echo "#!/bin/bash
## 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" > /usr/local/jamfps/finishOSInstall.sh
#
/usr/sbin/chown root:admin /usr/local/jamfps/finishOSInstall.sh
/bin/chmod 755 /usr/local/jamfps/finishOSInstall.sh
#
}
#
###############################################################################################################################################
#
# CREATE LAUNCH DAEMON
#
launchdaemon() {
#
/bin/echo "Creating Launch Daemon"
/bin/echo    
#
#
/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
#
}
#
###############################################################################################################################################
#
# CREATE LAUNCH AGENT
#
launchagent() {
#
/bin/echo "Creating Launch Agent"
/bin/echo    
#
##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
#
}
#
###############################################################################################################################################
#
# RUN UPGRADE
#
processupgrade() {
#
#macOS Installer 10.13.3 or ealier set 0 to it.
if [ "$versionMajor${versionMinor:=0}" -lt 134 ]
    then
        /bin/echo "Script is configured for Erase and Install of macOS."
        /bin/echo "However this is only Supported on macOS 10.13.3 and above."
        /bin/echo "Reconfiguring to Upgrade only."
        /bin/echo
        eraseInstall=0
fi
#
if [[ ${pwrStatus} == "OK" ]] && [[ ${spaceStatus} == "OK" ]]
    then
        /bin/echo "Launching jamfHelper"
        /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper &
        jamfHelperPID=$!
        #
        if [[ ${fvStatus} == "FileVault is On." ]] && [[ ${currentUser} != "root" ]]
            then
                /bin/echo
                /bin/echo "FileVault is On. Launching Agent to deal with FileVault Authenticated Reboots"
                #
                userID=$( /usr/bin/id -u "${currentUser}" )
                /bin/launchctl bootstrap gui/"${userID}" /Library/LaunchAgents/com.apple.install.osinstallersetupd.plist
        fi
        #
        /bin/echo
        #
        /bin/echo "Launching startosinstall..."
        #
        if [[ $eraseInstall == 1 ]]
            then
                eraseopt='--eraseinstall'
                /bin/echo
                /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
        /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
#
}
#
###############################################################################################################################################
#
# End Of Function Definition
#
###############################################################################################################################################
#
# Beginning Processing
#
###############################################################################################################################################
#
#
# Outputting 2 Blank Lines for Reporting Purposes
/bin/echo
/bin/echo
#
# Outputting a Dotted Line for Reporting Purposes
/bin/echo  -----------------------------------------------
#
# Outputting a Blank Line for Reporting Purposes
/bin/echo
#
preflightchecks
#
firstbootscript
#
launchdaemon
#
launchagent
#
processupgrade
#
ScriptEnd
#
cleanExit 0