Programmatic macOS updates for Apple Silicon

dan-snelson
Valued Contributor II

(Please pardon the piecemeal post; I'm presuming partial information is better than nothing.)


scheduleOSUpdate via the Jamf Pro API

Thanks to AppleCare pointing out that:

When running the softwareupdate command in a root shell on Apple Silicon users are being prompted for a password. This is expected behavior and the recommendation is to use the Schedule an OS Update command via MDM. This is the method to use if you want to update Apple Silicon Macs without requiring user credentials.

In other words:

if [[ "$arch" == "arm64" ]]; then
    scheduleOSUpdateViaAPI
else
    /usr/sbin/softwareupdate --install --all --include-config-data --restart --force
fi

In my limited testing, users are still prompted:
1dd859ae6a0d47459212605ed9035d25
0f66bc76c8164c1f8d4e61444960f217


Pending Feature Requests


Snippets

####################################################################################################
#
# Variables
#
####################################################################################################

jamfProURL="https://company.jamfcloud.com" # No trailing forward slash
apiUsername="${5}"
apiPasswordEncrypted="${6}"
computerSerialNumber=$( /usr/sbin/system_profiler SPHardwareDataType | /usr/bin/grep Serial | /usr/bin/awk '{print $NF}' )
arch=$( /usr/bin/arch )



####################################################################################################
#
# Functions
#
####################################################################################################

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# xpath tool changes in Big Sur
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function xpath() {

    # https://scriptingosx.com/2020/10/dealing-with-xpath-changes-in-big-sur/
    # Thanks, Armin!
    if [[ $(sw_vers -buildVersion) > "20A" ]]; then
        /usr/bin/xpath -e "$@"
    else
        /usr/bin/xpath "$@"
    fi

}



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Decrypt Password
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function decryptPassword() {
    /bin/echo "${1}" | /usr/bin/openssl enc -aes256 -d -a -A -S "${2}" -k "${3}"
}



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Schedule OS Update via the API
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function scheduleOSUpdateViaAPI() {

    echo "Schedule OS Update via the API …"

    apiPassword=$( decryptPassword ${apiPasswordEncrypted} ${Salt} ${Passphrase} )
    jamfProCompID=$( /usr/bin/curl -s -u ${apiUsername}:${apiPassword} ${jamfProURL}/JSSResource/computers/serialnumber/${computerSerialNumber}/subset/general | xpath "/computer/general/id/text()" )

    # /usr/bin/curl -s -X POST -H "Content-Type: text/xml" -u ${apiUsername}:${apiPassword} ${jamfProURL}/JSSResource/computercommands/command/ScheduleOSUpdate/action/InstallForceRestart/id/${jamfProCompID}

    /usr/bin/curl -s -X POST -H "Content-Type: text/xml" -u ${apiUsername}:${apiPassword} ${jamfProURL}/JSSResource/computercommands/command/ScheduleOSUpdate/action/Default/id/${jamfProCompID}

}




####################################################################################################
#
# Program
#
####################################################################################################


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Force Software Update Snippet only
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ "$arch" == "arm64" ]]; then
    scheduleOSUpdateViaAPI
else
    /usr/sbin/softwareupdate --install --all --include-config-data --restart --force
fi

--
Dan
40 REPLIES 40

jonw
New Contributor III

I went ahead and deployed to a classroom last night and successfully updated 34 out of 36 stations from 11.5.2 to 11.6 while at the login window.  I'm still at a loss as to why it's not 100%, but hopefully this will improve with Monterey.  As best I can tell the Jamf side and API command is functioning, it just seems like something on the workstation(s) themselves related to softwareupdated, or other process is hindering the update.  I'm still digging though logs, but I'm not coming up with anything yet.

fwiw- if it helps anyone following along, here's how I'm initiating the command via check-in from a Jamf policy script (sanitized for public view & using optional script parameters for testing... I would recommend using encrypted script parameters for production).

api user permissions are only:
Jamf Pro Server Objects: Computer: Create & Read
Jamf Pro Server Actions: Send Computer Remote Command to Download and Install macOS Update

#!/bin/bash

### Pass api user creds via script parameter
username="$5"
password="$6"
jss='https://your.jss.url'

### Get computer serial
serial=`system_profiler SPHardwareDataType | awk '/Serial Number/ { print $4 }'`

### Parse Jamf system ID from computer serial
jamfID=$( /usr/bin/curl -H "Accept: text/xml" -sfku ${username}:${password} ${jss}/JSSResource/computers/match/${serial} | xmllint --format - 2>/dev/null | awk -F'>|<' '/<id>/{print $3}' )

### Send ScheduleOSUpdate action: install
/usr/bin/curl --location -X POST --header "Accept: text/xml" -sfku ${username}:${password} ${jss}/JSSResource/computercommands/command/ScheduleOSUpdate/action/install/id/${jamfID}