Skip to main content

(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:






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 f "$arch" == "arm64" ]]; then
scheduleOSUpdateViaAPI
else
/usr/sbin/softwareupdate --install --all --include-config-data --restart --force
fi

The only action i could get to work was just plain old "install".  The other resulted in the "Unsupported InstallAction for this ProductKey"


The only action i could get to work was just plain old "install".  The other resulted in the "Unsupported InstallAction for this ProductKey"


i wanna say thats what the verbiage says in postman, so i would go with that.

collection was from Jamf


do you have the config profile set to no auto update/check/download etc, and also with a X days deferral?

 

We have just recently set the deferral so indeed that might be the issue.

redacting specific info, what is the exact url you are using? is it the same as the one i posted with your instanced replaced?

you ensuring is https?

 

what, if any, is the error you get?

 

When i run it in postman, for example, i get an xml output of computer info as a form of confirmation.

If it fails, i get a failure message.

 

Any other info from url to output that you can share would help.


@beeboo @jwaltonen Thanks for the ideas, I'm sure its some bugginess in our configuration, but it gives me hope that it's working for you.

I'm fairly confident the api call is getting through... I've tried a few iterations via command line, Postman and by script.  Jamf history indicates a 'ScheduleOSUpdate' command was received & it eventually clears itself from the pending list, the update itself just dies on the vine.  

Again, test stations (both Silicon & Intel @ 11.5.2) are at the login window when running the mdm command, bootstrap token verified escrowed on the server, Jamf 10.32.2.  Software update config profile is set to not autoupdate or download anything, and no deferrals are set in our Restrictions profile.


I feel like you are issuing the command correctly based on what you say you are observing in the JAMF console.

When I issue the command to an endpoint I see this in the console.

Then after a minute it goes away

 then i see this in management history

then sometime over the course of the next hour, the update occurs.

On machines that dont have the bootstrap token escrowed, all of the above still occurs but the update never happens.

Otherwise all my machines that I have successfully tested on are, intel, supervised, bootstrap token escrowed.

I am unsure at this point if any of my successful tests have occurred on machines that did not come through DEP/Automated Device Enrollment/ASM whatever you call it, prestage.  I am thinking maybe all of my successes were enrolled through a prestage enrollment.  

 


Strike that about the bootstrap token.  Just had success on a machine where it was NOT escrowed to the server.


Strike that about the bootstrap token.  Just had success on a machine where it was NOT escrowed to the server.


Yep!  That's exactly what I'm seeing in the Jamf console after issuing the mdm command and why I don't think the issue is with the api call.

However, I did finally get one to update- but in exactly the manner I DON'T want to happen.  I sent the command while at the login window.  Waited many hours... nothing... then logged in as a standard user.  After about 30 minutes the computer restarted without warning and performed the update to 11.6.  While it didn't need a local user to interact, this obviously won't fly in a lab/classroom setting.


These are brand new M1 iMacs all ADE (DEP) enrolled via Pre-Stage enrollment, and I can verify by Jamf console or command line that a bootstrap token is escrowed on the server.  

Interesting you got one to work without a token... maybe was an update that didn't require it?


It was the 11.6 update.  The behavior you describe is what I was seeing pre 10.32 upgrade, with the user needing to be logged in.  

Ill try to test an M1 and report back.

Thanks!  I appreciate your input!  Would you mind sharing your software update & deferment settings?  And, do you use NoMAD Login AD or Jamf Connect by any chance?  We use NoMAD Login and I'm starting to wonder if it might be getting in the way of updates at the login window?  


We use plain nomad not the login variety.

Currently this is  how our classrooms are set.

And I have another custom deferment profile deployed to try to stave off Monterey from being automatically delivered.

 <key>enforcedSoftwareUpdateMajorOSDeferredInstallDelay</key>
<integer>90</integer>
</dict> 


Thanks, update settings on my current test stations are set the same, so that's probably a dead end.


@jwaltonen @beeboo Back to testing and interestingly I've been able to get positive results by sending the mdm command via Postman whereas the same command via Jamf policy script goes nowhere (again, the console reports the command as pending & eventually clears itself, but the update never actually takes place at the login window).

I just wanted to say thanks again, at least now I know my command is functional and the problem is with macOS and/or Jamf.  If anyone following along experiences the same issues, I'd love to hear about it.


Yeah, just wanted to reiterate that doing it via the GUI is a lot more finicky and at least in the testing from my end so far, usually "goes through" but actually does nothing.

 

Ive relegated myself to the task of running a script to get all the JSS IDs of the machines in my smart group that determines out of data Big Sur machines, append a comma, then copy paste to postman.

 

I could just script the whole thing, but with with tech lockdown right now, ill just wait.


Well, fwiw I did finally get a scripted version to work... the downside is the same thing failed on another identical test station.  So yay I guess?  At least now it's down to determining "why is this so unreliable?"


Before I went on vacation last week, I felt like i was having very solid successes issuing the command.  Like I did 2 entire classrooms, and all the machines in each had updated to 11.6 in less than 2 hours.  I started working on this again yesterday and am unsure that I am having any success getting the updates to actually occur.  The OSupdate entries show up in the management history/logs but no updates.  Weird and sad. 


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

 

- see newer script in thread below using updated API

 

 


Has anyone found a Jamf API to include the new deferral option when running the update MDM command?


Has anyone found a Jamf API to include the new deferral option when running the update MDM command?


judging by the API commands I'm seeing, it doesn't seem like we can do this yet. =(


judging by the API commands I'm seeing, it doesn't seem like we can do this yet. =(


Correction, just been noodling, and found it in the API docs. 

https://jamfserver.example.com/api/doc/#/macos-managed-software-updates/post_v1_macos_managed_software_updates_send_updates

Wrote up an advancedsearch to find machines needing 12.2.1, and then some quick powershell to grab the computers, and build the query. It SEEMS to work, but will need to test more.


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

 

- see newer script in thread below using updated API

 

 


Love this script, thx for sharing. Working well for my tests so far with Monterey, but I have to manually click "Restart Now" in Software Update to get this to complete. Is that as intended or should this download, install and then restart automatically?


Love this script, thx for sharing. Working well for my tests so far with Monterey, but I have to manually click "Restart Now" in Software Update to get this to complete. Is that as intended or should this download, install and then restart automatically?


Thanks Tom!  My only thought is are you following up with a policy 'Restart Options' payload specifically set to 'MDM Restart with Kernel Cache Rebuild'?

I recently updated a few hundred lab stations to 12.3.1 at the login window so I know it's still working.  However as I mentioned previously, I almost always have a few stations that despite receiving the mdm command never complete the update!?  I suspect an Apple bug with softwareupdated, and lately I've been adding this earlier in the script. I feel like it's helping but I can't honestly say for sure.  The word is that Apple patched some issues with softwareupdated in 12.3 but I've not hat time to follow up & test.

 

/bin/launchctl kickstart -k system/com.apple.softwareupdated
### give it 5 minutes to check for updates & sort itself out
sleep 300

 




Thanks Tom!  My only thought is are you following up with a policy 'Restart Options' payload specifically set to 'MDM Restart with Kernel Cache Rebuild'?

I recently updated a few hundred lab stations to 12.3.1 at the login window so I know it's still working.  However as I mentioned previously, I almost always have a few stations that despite receiving the mdm command never complete the update!?  I suspect an Apple bug with softwareupdated, and lately I've been adding this earlier in the script. I feel like it's helping but I can't honestly say for sure.  The word is that Apple patched some issues with softwareupdated in 12.3 but I've not hat time to follow up & test.

 

/bin/launchctl kickstart -k system/com.apple.softwareupdated
### give it 5 minutes to check for updates & sort itself out
sleep 300

 




Ah I did not have the restart payload set in my policy! Testing now, first computer did not work, will keep working on it. Using this policy with the "Enrollment complete" trigger so when when start getting new laptops ready, one of the first things that happens is updating to latest macOS.

 

Where did you apply:

/bin/launchctl kickstart -k system/com.apple.softwareupdated
### give it 5 minutes to check for updates & sort itself out
sleep 300

 

 


Ah I did not have the restart payload set in my policy! Testing now, first computer did not work, will keep working on it. Using this policy with the "Enrollment complete" trigger so when when start getting new laptops ready, one of the first things that happens is updating to latest macOS.

 

Where did you apply:

/bin/launchctl kickstart -k system/com.apple.softwareupdated
### give it 5 minutes to check for updates & sort itself out
sleep 300

 

 


@jonw actually it did work just now! Heading out for the wkd and letting another run now, will report back Monday.


@jonw actually it did work just now! Heading out for the wkd and letting another run now, will report back Monday.


@TomDay Awesome!  Glad to hear it.  

I run the softwareupdated kickstart before everything else.  I also should have mentioned the whole update process governed by api/mdm is annoyingly 'mysterious' at times, whether triggered via script or by the native Jamf action.  I've seen it take up to an hour past the command being sent to see any obvious activity other than the Jamf log saying the command was successfully sent.


/bin/launchctl kickstart -k system/com.apple.softwareupdated
### give it 5 minutes to check for updates & sort itself out
sleep 300

 

This seems to have made a big difference in the effectiveness of the ScheduleOSUpdate command for me.

 


@jwaltonen Glad to hear it!

By the way, a new feature in the recently released Jamf 10.38.0 that looks really promising!  "You can now force computers to immediately restart and install an available macOS update using the /v1/macos-managed-software-updates/send-updates endpoint via the Jamf Pro API."

I'm going to start testing asap.


Reply