Skip to main content
Question

Force a Computer Restart to Install macOS Updates


Show first post

114 replies

Forum|alt.badge.img+1
  • New Contributor
  • 5 replies
  • July 25, 2022
bwoods wrote:

@MPL Below is the second part of my jamf helper process. It's basically a set of dialogs that guides the user through the updates. logs are created to track how many times the user has deferred the prompt. Simply create a custom policy with the trigger "updateOS". The launch daemon in part A will run this at the desired time interval.

 

 

 

#!/bin/bash # Server connection information URL="https://url.jamfcloud.com" username="$4" password="$5" # Operatitng system information osVersion="$6" osName="$7" osFullName="$7 "${osVersion}"" serialNumber=$(system_profiler SPHardwareDataType | awk '/Serial Number/{print $4}') # Log information currentUser=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' ) logFolder="/Users/"${currentUser}"/logs/" deferlog="${logFolder}/deferlog.txt" lastDeferralCount=$(cat "${deferlog}") # Jamf helper information jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" description1="${osFullName} is now available. Select 'Start Now' to initialize the update. Select 'Defer' to complete the update at another time. Once the update is initiated, it may take 25-60 minutes for the computer to restart. Remaining Deferral Attempts: 3" description2="${osFullName} is now available. Select 'Start Now' to initialize the update. Select 'Defer' to complete the update at another time. Once the update is initiated, it may take 25-60 minutes for the computer to restart. Remaining Deferral Attempts: 2" description3="${osFullName} is now available. Select 'Start Now' to initialize the software update. Select 'Defer' to initialize the update at another time. Once the update is initiated, it may take 25-60 minutes for the computer to restart. Remaining Deferral Attempts: 1" finalDescription="The maximum deferral limit has been reached. Select 'Start Now' to initialize the ${osFullName} update. Otherwise, use the remaining time to sync any unsaved changes to OneDrive. Remaining Deferral Attempts: 0" waitDescription="Processing software update. Please wait for the computer to restart. Ensure that the power adapter is connected. This process may take awhile." timeout="$8" ########Functions########### initializeSoftwareUpdate(){ # create base64-encoded credentials encodedCredentials=$( printf "${username}:${password}" | /usr/bin/iconv -t ISO-8859-1 | /usr/bin/base64 -i - ) # Generate new auth token authToken=$( curl -X POST "${URL}/api/v1/auth/token" -H "accept: application/json" -H "Authorization: Basic ${encodedCredentials}" ) # parse authToken for token, omit expiration token=$(/usr/bin/awk -F \\" 'NR==2{print $4}' <<< "$authToken" | /usr/bin/xargs) echo ${token} # Determine Jamf Pro device id deviceID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${token}" ${URL}/JSSResource/computers/serialnumber/"$serialNumber" | xmllint --xpath '/computer/general/id/text()' -) echo ${deviceID} # Execute software update curl -X POST "${URL}/api/v1/macos-managed-software-updates/send-updates" -H "accept: application/json" -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" -d "{\\"deviceIds\\":[\\"${deviceID}\\"],\\"maxDeferrals\\":0,\\"version\\":\\"${osVersion}\\",\\"skipVersionVerification\\":true,\\"applyMajorUpdate\\":true,\\"updateAction\\":\\"DOWNLOAD_AND_INSTALL\\",\\"forceRestart\\":true}" # Invalidate existing token and generate new token curl -X POST "${URL}/api/v1/auth/keep-alive" -H "accept: application/json" -H "Authorization: Bearer ${token}" } pleaseWait(){ buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "lr" -title "Software Update" -description "$waitDescription" -alignDescription "Left") } firstPrompt(){ # First Prompt buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "lr" -title "Software Update" -description "${description1}" -alignDescription "Left" -button1 "Start Now" -button2 "Defer") echo $buttonClicked if [[ $buttonClicked == 0 ]]; then echo "User clicked Start Now" echo "Initializing Software Update" rm -rf "${logFolder}" launchctl unload /private/tmp/osUpdate.plist rm -rf /private/tmp/osUpdate.plist initializeSoftwareUpdate pleaseWait elif [[ $buttonClicked == 2 ]]; then # Declare what the user clicked echo "User Clicked Defer" # Set deferralCount to 0 deferralCount="1" #Append current number of deferrals to deferlog.txt echo $deferralCount > $deferlog exit 0 fi } secondPrompt(){ # Second Prompt buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "lr" -title "Software Update" -description "${description2}" -alignDescription "Left" -icon -button1 "Start Now" -button2 "Defer") echo $buttonClicked if [[ $buttonClicked == 0 ]]; then echo "User clicked Start Now" echo "Initializing Software Update" rm -rf "${logFolder}" launchctl unload /private/tmp/osUpdate.plist rm -rf /private/tmp/osUpdate.plist initializeSoftwareUpdate pleaseWait elif [[ $buttonClicked == 2 ]]; then echo "User Clicked Defer" # Set deferralCount to 0 deferralCount="2" #Append current number of deferrals to deferlog.txt echo $deferralCount > $deferlog exit 0 fi } thirdPrompt(){ # Third Prompt buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "lr" -title "Software Update" -description "${description3}" -alignDescription "Left" -button1 "Start Now" -button2 "Defer") echo $buttonClicked if [[ $buttonClicked == 0 ]]; then echo "User clicked Start Now" echo "Initializing Software Update" rm -rf "${logFolder}" launchctl unload /private/tmp/osUpdate.plist rm -rf /private/tmp/osUpdate.plist initializeSoftwareUpdate pleaseWait elif [[ $buttonClicked == 2 ]]; then echo "User Clicked Defer" # Set deferralCount to 0 deferralCount="3" #Append current number of deferrals to deferlog.txt echo $deferralCount > $deferlog exit 0 fi } finalPrompt(){ buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "lr" -title "Software Update" -description "$finalDescription" -alignDescription "Left" -button1 "Start Now" -timeout $timeout -countdown -alignCountdown "Center") if [[ $buttonClicked == 0 ]]; then echo "User clicked Start Now" echo "Initializing Software Update" rm -rf "${logFolder}" launchctl unload /private/tmp/osUpdate.plist rm -rf /private/tmp/osUpdate.plist initializeSoftwareUpdate pleaseWait fi } # First Prompt if [[ ! -f $deferlog ]]; then echo "Initializing deferral process" # Create a logs folder mkdir $logFolder # Create a deferlog.txt to track deferral count touch "$deferlog" # Set deferralCount to 0 deferralCount="1" #Append current number of deferrals to deferlog.txt echo $deferralCount > $deferlog # Initialize First Prompt firstPrompt # Second Prompt elif [[ ${lastDeferralCount} = "1" ]]; then echo "Initializing Second Prompt" secondPrompt # Third Prompt elif [[ ${lastDeferralCount} = "2" ]]; then echo "Initializing Third Prompt" thirdPrompt elif [[ ${lastDeferralCount} = "3" ]]; then echo "Initializing Final Prompt" finalPrompt fi exit 0 ## Success exit 1 ## Failure

 

 

 

 


Hi @bwoods I have encountered an issue and I'm hoping you might be able to help me out. 

When I let the launchdaemon script from policy A runs after the specified time it will show the Jamf helper prompt, and when click "Start Now" nothing seems to happen except the script removing the log folder from the /Users. Also, no logs are showing up in deferral policy B logs that the user has selected "Start Now".  However, If I select "Defer" it works and I can see the logs showing up in policy B that the user has deferred.    

The interesting thing is if I manually run sudo jamf policy -event updaeOS on the test machine the "Start Now" from the jamf helper works fine! 

 

Any advice would be appreciated greatly. 


Forum|alt.badge.img+1
  • New Contributor
  • 5 replies
  • July 25, 2022
stutz wrote:

@moussabl Here are the JAMF account permissions I use for this script and it works for me.  

Account
Access Level - Full Access
Privilege Set - Custom


Privileges (everything is unchecked except for the following):
JAMF Pro Server Objects - Computers - Create+Read

JAMF Pro Server Actions - Send Computer Remote Command to Download and Install macOS Update - Checked


Awesome, Thank you @stutz 


bwoods
Forum|alt.badge.img+14
  • Author
  • Honored Contributor
  • 473 replies
  • July 26, 2022
moussabl wrote:

Hi @bwoods I have encountered an issue and I'm hoping you might be able to help me out. 

When I let the launchdaemon script from policy A runs after the specified time it will show the Jamf helper prompt, and when click "Start Now" nothing seems to happen except the script removing the log folder from the /Users. Also, no logs are showing up in deferral policy B logs that the user has selected "Start Now".  However, If I select "Defer" it works and I can see the logs showing up in policy B that the user has deferred.    

The interesting thing is if I manually run sudo jamf policy -event updaeOS on the test machine the "Start Now" from the jamf helper works fine! 

 

Any advice would be appreciated greatly. 


@moussabl , ensure that the custom triggers are exactly the same. In your post above, see "updaeOS" instead of "updateOS". The trigger in the launch daemon must mach the trigger in the policy. Also, I designed the script to self destruct after "Start Now" is selected. The logs only work if the user clicks defer.  

For testing I suggest using Code Runner to run Part A over and over again until you're satisfied with the results.

For instance, have the code for Part A in code Runner and Part B in Jamf. Manually set the timeout in Part A to something reasonable like 10 seconds to test the code. 


Forum|alt.badge.img+2
  • New Contributor
  • 1 reply
  • July 29, 2022

Was playing around with this and granting the account read access to Computers, it outputs some information that's questionable. management_password, list of users, software detected, etc

 

Not the fastest to get ID. But it won't expose more information than what's needed.

deviceID=$(jamf recon | grep "computer_id" | xmllint --xpath '/computer_id/text()' -)
 
Account just has this permission: Send Computer Remote Command to Download and Install macOS Update

SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • July 30, 2022
bwoods wrote:

One note, the section below can mostly likely be turned into a variable or parameter to edit the version number on the fly in the future. Otherwise, have at it. Help me improve this thing.

 


I ran the above script on one of our M1's and it says completed with the below details. The user's MacBook was locked.

Script result: Serial number: XYVH2K0FVH
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 391 0 391 0 0 905 0 --:--:-- --:--:-- --:--:-- 922 Auth Token: { "token" : "eyJhbGciOiJIUzI1NiJ9.eyJhdXRoZW50aWNhdGVkLWFwcCI6IkdFTkVSSUMiLCJhdXRoZW50aWNhdGlvbi10eXBlIjoiSlNTIiwiZ3JvdXBzIjpbXSwic3ViamVjdC10eXBlIjoiSlNTX1VTRVJfSUQiLCJ0b2tlbi11dWlkIjoiNmQwNDQwMmQtZjgyOC00Mzk2LWEwNjItNjRkOWQ2NjU4ZTJmIiwibGRhcC1zZXJ2ZXItaWQiOi0xLCJzdWIiOiIxIiwiZXhwIjoxNjU5MjIwMTkxfQ.IMGqlh89pAIIGNOI0Fnn4bKKLkZwZb__G6b4p1nH6Z0", "expires" : "2022-07-30T22:29:51.103Z" } Token: eyJhbGciOiJIUzI1NiJ9.eyJhdXRoZW50aWNhdGVkLWFwcCI6IkdFTkVSSUMiLCJhdXRoZW50aWNhdGlvbi10eXBlIjoiSlNTIiwiZ3JvdXBzIjpbXSwic3ViamVjdC10eXBlIjoiSlNTX1VTRVJfSUQiLCJ0b2tlbi11dWlkIjoiNmQwNDQwMmQtZjgyOC00Mzk2LWEwNjItNjRkOWQ2NjU4ZTJmIiwibGRhcC1zZXJ2ZXItaWQiOi0xLCJzdWIiOiIxIiwiZXhwIjoxNjU5MjIwMTkxfQ.IMGqlh89pAIIGNOI0Fnn4bKKLkZwZb__G6b4p1nH6Z0 Device ID: 107 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 392 0 224 100 168 539 404 --:--:-- --:--:-- --:--:-- 982 { "responses" : [ { "id" : "e84835e9-7ee3-4884-9c01-2a032512cbfb", "href" : "https://lplfinancial.jamfcloud.com/lplfinancial/api/v1/mdm/commands?uuids=e84835e9-7ee3-4884-9c01-2a032512cbfb" } ], "errors" : [ ] } % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 391 0 391 0 0 854 0 --:--:-- --:--:-- --:--:-- 884 { "token" : "eyJhbGciOiJIUzI1NiJ9.eyJhdXRoZW50aWNhdGVkLWFwcCI6IkdFTkVSSUMiLCJhdXRoZW50aWNhdGlvbi10eXBlIjoiSlNTIiwiZ3JvdXBzIjpbXSwic3ViamVjdC10eXBlIjoiSlNTX1VTRVJfSUQiLCJ0b2tlbi11dWlkIjoiNmQwNDQwMmQtZjgyOC00Mzk2LWEwNjItNjRkOWQ2NjU4ZTJmIiwibGRhcC1zZXJ2ZXItaWQiOi0xLCJzdWIiOiIxIiwiZXhwIjoxNjU5MjIwMTkzfQ.cpkwPxLRneGh3uI9THNzys7rl8cHjFnEEmu8sTevuoA", "expires" : "2022-07-30T22:29:53.276Z" }


Forum|alt.badge.img+1
  • New Contributor
  • 5 replies
  • August 1, 2022
bwoods wrote:

@moussabl , ensure that the custom triggers are exactly the same. In your post above, see "updaeOS" instead of "updateOS". The trigger in the launch daemon must mach the trigger in the policy. Also, I designed the script to self destruct after "Start Now" is selected. The logs only work if the user clicks defer.  

For testing I suggest using Code Runner to run Part A over and over again until you're satisfied with the results.

For instance, have the code for Part A in code Runner and Part B in Jamf. Manually set the timeout in Part A to something reasonable like 10 seconds to test the code. 


Thanks heaps @bwoods! It's working for us now.

Sorry, final question. would you know if there's a way to postponed the Jamf helper notification when a user is active in a meeting on MS Teams or Zoom call?

Thank you very much.


wakco11
Forum|alt.badge.img+9
  • Valued Contributor
  • 146 replies
  • August 1, 2022
moussabl wrote:

Thanks heaps @bwoods! It's working for us now.

Sorry, final question. would you know if there's a way to postponed the Jamf helper notification when a user is active in a meeting on MS Teams or Zoom call?

Thank you very much.


@moussabl If the notification is a system notification, teach the users to enable Do not disturb on the computer at the beginning of a meeting (and how to disable it afterwards). This process is slightly different depending on the macOS version:

  • In macOS 10.15 Catalina and earlier, the quickest way was to go to the Notification centre (itemised hamburger menu on the right of the menu bar) and scroll up to find the Do Not Disturb switch.
  • In macOS 11 Big Sur and newer, go to the Control Centre menu and change the Focus (usually top right of the Control Centre).

SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 1, 2022
markopolo wrote:

Thanks, I actually got it working last night (tried so many things I don't remember what fixed it). Here is the final script I'm using:

#!/bin/bash # Server connection information URL="xxxxxxxx" username="xxxxxxxx" password="xxxxxxxx" # Determine Serial Number serialNumber=$(system_profiler SPHardwareDataType | awk '/Serial Number/{print $4}') echo "Serial number: ${serialNumber}" initializeSoftwareUpdate(){ # create base64-encoded credentials encodedCredentials=$( printf "${username}:${password}" | /usr/bin/iconv -t ISO-8859-1 | /usr/bin/base64 -i - ) # Generate new auth token authToken=$( curl -X POST "${URL}/api/v1/auth/token" -H "accept: application/json" -H "Authorization: Basic ${encodedCredentials}" ) # parse authToken for token, omit expiration token=$(/usr/bin/awk -F \\" 'NR==2{print $4}' <<< "$authToken" | /usr/bin/xargs) echo "Token: ${token}" # Determine Jamf Pro device id deviceID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${token}" ${URL}/JSSResource/computers/serialnumber/"$serialNumber" | xmllint --xpath '/computer/general/id/text()' -) echo "Device ID: ${deviceID}" # Execute software update curl -X POST "${URL}/api/v1/macos-managed-software-updates/send-updates" -H "accept: application/json" -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" -d "{\\"deviceIds\\":[\\"${deviceID}\\"],\\"maxDeferrals\\":0,\\"version\\":\\"12.4\\",\\"skipVersionVerification\\":true,\\"applyMajorUpdate\\":true,\\"updateAction\\":\\"DOWNLOAD_AND_INSTALL\\",\\"forceRestart\\":true}" # Invalidate existing token and generate new token curl -X POST "${URL}/api/v1/auth/keep-alive" -H "accept: application/json" -H "Authorization: Bearer ${token}" } initializeSoftwareUpdate

 Thanks for your help, I really appreciate it!


For this to work, does the user have to be logged on. I tested it on one our users, but the device was locked and it never updated.


bwoods
Forum|alt.badge.img+14
  • Author
  • Honored Contributor
  • 473 replies
  • August 2, 2022
moussabl wrote:

Thanks heaps @bwoods! It's working for us now.

Sorry, final question. would you know if there's a way to postponed the Jamf helper notification when a user is active in a meeting on MS Teams or Zoom call?

Thank you very much.


Hmmm...my first instinct would be to create a conditional statement to check if Zoom or Teams is open, but I don't know how to tell if the user is on a call. Simply checking for open apps may result in the process never starting because messaging apps are usually always open.


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 3, 2022

From going through this thread, are 3 policies needed to deploy the update? From what I'm reading it looks like one is needed for the update script, Part A and Part B?


bwoods
Forum|alt.badge.img+14
  • Author
  • Honored Contributor
  • 473 replies
  • August 4, 2022
SMR1 wrote:

From going through this thread, are 3 policies needed to deploy the update? From what I'm reading it looks like one is needed for the update script, Part A and Part B?


Only two policies are needed. One to load the launch daemon and the other to run the script.


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 4, 2022
bwoods wrote:

Only two policies are needed. One to load the launch daemon and the other to run the script.


Sorry for the ignorance on this, very new to Jamf. I'm just creating part A(daemon) and then part B for the script?


bwoods
Forum|alt.badge.img+14
  • Author
  • Honored Contributor
  • 473 replies
  • August 4, 2022
SMR1 wrote:

Sorry for the ignorance on this, very new to Jamf. I'm just creating part A(daemon) and then part B for the script?


Correct, part A is creating and loading a launch daemon that then runs the script in part B.


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 4, 2022
bwoods wrote:

Correct, part A is creating and loading a launch daemon that then runs the script in part B.


I must be doing something wrong, because Part A shows installed, but it's not kicking off B. 


bwoods
Forum|alt.badge.img+14
  • Author
  • Honored Contributor
  • 473 replies
  • August 4, 2022
SMR1 wrote:

I must be doing something wrong, because Part A shows installed, but it's not kicking off B. 


Ensure that you've configured the parameter for part A and that the custom trigger in part B matches the trigger in part A. Are you familiar with positional parameters / custom triggers in Jamf?


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 4, 2022
bwoods wrote:

Ensure that you've configured the parameter for part A and that the custom trigger in part B matches the trigger in part A. Are you familiar with positional parameters / custom triggers in Jamf?


I'm familiar with custom triggers, but not so much regarding positional parameters. I have the trigger in part B set to updateOS.


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 4, 2022
SMR1 wrote:

I'm familiar with custom triggers, but not so much regarding positional parameters. I have the trigger in part B set to updateOS.


Also, if the user hit's start now and then locks there Mac, will the process finish or does it need to be logged on to?


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 5, 2022
SMR1 wrote:

Also, if the user hit's start now and then locks there Mac, will the process finish or does it need to be logged on to?


Sorry for all the questions. Is it possible to set part B to deploy without any user interaction? Trying to be more like our SCCM side of things. We typically send out communications informing users of updates that are coming at night. If possible, it would cool to set this to deploy at night without any user interaction.


bwoods
Forum|alt.badge.img+14
  • Author
  • Honored Contributor
  • 473 replies
  • August 5, 2022
SMR1 wrote:

Sorry for all the questions. Is it possible to set part B to deploy without any user interaction? Trying to be more like our SCCM side of things. We typically send out communications informing users of updates that are coming at night. If possible, it would cool to set this to deploy at night without any user interaction.


If you don't want to notify the user first, you can send a mass action command via Jamf. More info below: 

Updating macOS Using a Mass Action - Managing macOS Updates | Jamf


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 5, 2022
bwoods wrote:

If you don't want to notify the user first, you can send a mass action command via Jamf. More info below: 

Updating macOS Using a Mass Action - Managing macOS Updates | Jamf


That was hit miss when we tested it.  Your script worked, so I think we'll roll with that and just have to have some user interaction.


bwoods
Forum|alt.badge.img+14
  • Author
  • Honored Contributor
  • 473 replies
  • August 5, 2022
SMR1 wrote:

That was hit miss when we tested it.  Your script worked, so I think we'll roll with that and just have to have some user interaction.


That's very strange because my script is basically an MDM Command in API form. If you don't want any interaction you can copy my original function above and just trow it in a policy.


SMR1
Forum|alt.badge.img+13
  • Valued Contributor
  • 218 replies
  • August 10, 2022
bwoods wrote:

That's very strange because my script is basically an MDM Command in API form. If you don't want any interaction you can copy my original function above and just trow it in a policy.


When running either the Part B or your original function, does the user have to be logged on for the update complete?


Forum|alt.badge.img+21
  • Honored Contributor
  • 970 replies
  • September 2, 2022
McAwesome wrote:

These couple of functions may help you add some safety checks in.

batteryCheck(){ powerType=$(pmset -g batt | head -n 1 | cut -c19- | rev | cut -c 2- | rev) if [[ "$powerType" == "Battery Power" ]]; then echo "Machine is on Battery Power." bat=$(pmset -g batt | grep 'InternalBattery' | awk '{print $3}' | tr -d '%'';') if (( $bat > 60 )); then echo "Battery Level OK, Continuing Update..." else echo "Battery Level Insufficient for this update" return 1 fi else echo "Machine is on AC Power." fi } bootstrapTokenCheck(){ bootstrap=$(profiles status -type bootstraptoken) if [[ $bootstrap == *"escrowed to server: YES"* ]]; then echo "Bootstrap escrowed" else echo "Bootstrap not escrowed. Cannot update with MDM commands." return 1 fi } freeSpaceRequirement(){ freespace=$(df -h -m | grep -m 1 /System/Volumes/Data | awk '{print $4}') if [[ $freespace -lt 15000 ]]; then echo "Insufficient free space" return 1 else echo "Machine has at least 15 GBs of free space" fi } verifyUpdateNeeded(){ # Check for available updates availableUpdates=`/usr/libexec/mdmclient AvailableOSUpdates` # Updates available if [[ "$availableUpdates" == *"=== OS Update Item ==="* ]]; then echo "Updates Available" # Updates not available else echo "No Updates Available" return 1 fi } # Verifying update is needed and requirements have been met. verifyUpdateNeeded || exit 0 bootstrapTokenCheck || exit 0 freeSpaceRequirement || exit 0 batteryCheck || exit 0

 Also if I'm not mistaken you can streamline your update command so you don't have to fiddle with it as much next time around.  If you don't specify a specific version, it will download the newest one based on device eligibility.

curl -X POST "${URL}/api/v1/macos-managed-software-updates/send-updates" \\ -H "accept: application/json" \\ -H "Authorization: Bearer ${token}" \\ -H "Content-Type: application/json" \\ -d "{\\"deviceIds\\":[\\"${deviceID}\\"],\\"skipVersionVerification\\":false,\\"applyMajorUpdate\\":false,\\"updateAction\\":\\"DOWNLOAD_AND_INSTALL\\",\\"forceRestart\\":true}"

 


can the bootstrap token check be skipped if not using mobile accounts? or is it a requirement that would stop it working?


sdagley
Forum|alt.badge.img+25
  • Jamf Heroes
  • 3540 replies
  • September 2, 2022
tkimpton wrote:

can the bootstrap token check be skipped if not using mobile accounts? or is it a requirement that would stop it working?


@tkimpton The account type doesn't matter, a bootstrap token is required for any MDM triggered updates


Forum|alt.badge.img+21
  • Honored Contributor
  • 970 replies
  • September 7, 2022

just FYI you need to change ${osFullName} to $osFullName in the variables otherwise you will get 403 Access Denied when trying to edit the script


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings