Been going round in circles with this for ages now but finally got something working.
https://github.com/PezzaD84/macOS-Patching
Made a script to prompt the user to available updates with the option to postpone the update for 4 days. Used to use this script before M1's ruined everything but added a nice function to run the MDM command via an API post if the device is M1.
For some reason I was getting "Battery level is too low" when tested in a Mac Pro and iMac. It works fine if I click continue but I modified the battery level part to show the warning if a laptop is not connected to power source instead below 60% (No battery warning in the Mac Pro and iMac after)
# Check Battery level
if [[ "$(/usr/bin/pmset -g ps | /usr/bin/grep "Battery Power")" = "Now drawing from 'Battery Power'" ]]; then
echo "Computer is not currently connected to a power source."
"$Notify" \\
-windowType hud \\
-lockHUD \\
-title "MacOS Updates" \\
-heading "Plug in Power" \\
-description "Computer is not currently connected to a power source.
Please connect to a power supply before continuing." \\
-icon /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns \\
-button1 "Continue"
fi
I did more testing after I posted and it seems to be working as I hoped. I'll post more details when I get a chance. The basic requirements:
- A script, executed by a policy, that writes the proper values to allow an account to automatically login at next restart. The policy also executes a restart at the end of the policy run.
- A script, executed by a policy to run at startup, once per day, to execute the software update command when the system is logged in. This script also removes the auto-login values so that after software updates run, the system is back to booting to a login window. The policy also has a reboot built-in, in the event no updates are found, so the softwareupdate tool doesn't force the restart first.
So far this has worked with two of my labs pretty well. These are Intel iMacs. I don't believe this scheme will not work for M1 Macs - but I don't have any of those in a managed lab setting yet.
A bit late to the game, but I have separately realized that I need to do pretty much this process in my own environment. Did you get it working?
So now that the new features in 10.35 and later have been available for a little while, what kind of results have people been seeing? From what we've seen, if we send out an MDM command telling computers to update to a specific OS version and allow 1 day deferral option, we might get about a 50% upgrade rate after a few days. For some folks the popup message in the Notification Center either doesn't appear or isn't noticed, others see it and ignore it, some say Try Tonight but never take any action themselves and the computer just decides not to apply the update after all. Sure, it's one more tool in our bag when it comes to ways to chip away at the number of unpatched devices but actual "enforcement" this is not.
Are others seeing anything similar or is my experience an outlier here?
So now that the new features in 10.35 and later have been available for a little while, what kind of results have people been seeing? From what we've seen, if we send out an MDM command telling computers to update to a specific OS version and allow 1 day deferral option, we might get about a 50% upgrade rate after a few days. For some folks the popup message in the Notification Center either doesn't appear or isn't noticed, others see it and ignore it, some say Try Tonight but never take any action themselves and the computer just decides not to apply the update after all. Sure, it's one more tool in our bag when it comes to ways to chip away at the number of unpatched devices but actual "enforcement" this is not.
Are others seeing anything similar or is my experience an outlier here?
@tzeilstra its still a mixed bag. There is a lot that can go wrong in the Software Update process, and in JAMFs infinite wisdom they still are not using the StatusUpdate key. So, JAMF has no idea what a Mac is doing with Software Updates. Seems like the problem still persists after all these years, JAMF is still half a!@ing software updates on macOS.
I had a case open with JAMF that got up to the engineers a few weeks ago. The best answer they had for me was to make a smart group for OS versions (which I do already), and contact users for devices that fail to update. You know, because we have JAMF to do things manually and not automate them.
To be fair, Apple moved to MDM command based Software Updates way too fast and did not let the kinks get worked out first. I'm still waiting for a policy to be able to actually schedule OS updates which was hinted would be coming in this post.
So now that the new features in 10.35 and later have been available for a little while, what kind of results have people been seeing? From what we've seen, if we send out an MDM command telling computers to update to a specific OS version and allow 1 day deferral option, we might get about a 50% upgrade rate after a few days. For some folks the popup message in the Notification Center either doesn't appear or isn't noticed, others see it and ignore it, some say Try Tonight but never take any action themselves and the computer just decides not to apply the update after all. Sure, it's one more tool in our bag when it comes to ways to chip away at the number of unpatched devices but actual "enforcement" this is not.
Are others seeing anything similar or is my experience an outlier here?
We manage a computer lab and a device checkout program that has no dedicated users. As a result, using the built-in functionality will never work for us--nobody is going to give up their computer time to run an update. We have tried using it but I don't think that we got a single machine to update itself.
This is totally broken for cases in which there is not a 1:1 computer to user relationship.
We manage a computer lab and a device checkout program that has no dedicated users. As a result, using the built-in functionality will never work for us--nobody is going to give up their computer time to run an update. We have tried using it but I don't think that we got a single machine to update itself.
This is totally broken for cases in which there is not a 1:1 computer to user relationship.
This is exactly what we're facing as well. Users of computer labs simply cannot be incentivised to install an update on their limited time.
The only workaround for this that I've found is to distribute the complete OS installer of the latest version of macOS to all the lab machines and then triggering startosinstall during the night. If you ask me, thats too many loops to jump through for every point and security update.
MDM-triggered updates for 1:1 machines is really hit or miss, after about a month we're looking at about a 65% update rate.
During the "old days" when the softwareupdate could be triggered (and trusted to do its job) by jamf, we were at 90%+ within a few days.
On a related note...
I'm not a fan of the Software Update deferments living in the Restrictions profile, alongside other settings (that are static and never change). I wish these settings were located in the (duh!) Jamf Software Update profile.
I'm considering breaking our Software Update settings into their own discreet profile(s) so that I can edit them without worrying about other Restriction payloads being affected. Since Software Deferments live in the com.apple.applicationaccess preference domain, I dont think this should be a problem.
Is anyone else doing this (or similar)?
On a related note...
I'm not a fan of the Software Update deferments living in the Restrictions profile, alongside other settings (that are static and never change). I wish these settings were located in the (duh!) Jamf Software Update profile.
I'm considering breaking our Software Update settings into their own discreet profile(s) so that I can edit them without worrying about other Restriction payloads being affected. Since Software Deferments live in the com.apple.applicationaccess preference domain, I dont think this should be a problem.
Is anyone else doing this (or similar)?
https://www.youtube.com/watch?v=tqF4ls823ig
This will totally change the way you look at Profiles. Short answer is yes, we deploy a profile for deferring software updates and that's ALL that profile does. No extra stuff from the restrictions payload.
This is exactly what we're facing as well. Users of computer labs simply cannot be incentivised to install an update on their limited time.
The only workaround for this that I've found is to distribute the complete OS installer of the latest version of macOS to all the lab machines and then triggering startosinstall during the night. If you ask me, thats too many loops to jump through for every point and security update.
MDM-triggered updates for 1:1 machines is really hit or miss, after about a month we're looking at about a 65% update rate.
During the "old days" when the softwareupdate could be triggered (and trusted to do its job) by jamf, we were at 90%+ within a few days.
This is precisely the issue we are facing. We've previously used an update policy that we could manually invoke, but that breaks on the latest M1 machines that use the APFS Volume Owner as the only person who can perform an update. We are having a great deal of difficulty installing any updates to these machines because for some reason, Sophos creates a user during install that becomes the machine's owner. We've been working on this problem for weeks and can't get around it, so some machines are stuck on Big Sur until further notice...
Supposedly there is an ability in Big Sur for the MDM to defer Major OS Upgrades for up to 90 days. Does anyone know what that setting is located in Jamf?
It is under Restrictions. Here is also an example of a naked profile. If signed and uploaded JAMF does not alter anything. (You have to calculate your own UUIDs in this example)
<?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">
<dict>
<key>PayloadUUID</key>
<string>E61CEEFB1921B511F6</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadOrganization</key>
<string>Company</string>
<key>PayloadIdentifier</key>
<string>E61CEEF861921B511F6</string>
<key>PayloadDisplayName</key>
<string>Apple Software Updates</string>
<key>PayloadDescription</key>
<string/>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadUUID</key>
<string>2451A00F-6F87A6219DDE</string>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadOrganization</key>
<string>Company</string>
<key>PayloadIdentifier</key>
<string>2451A00F-86E9-4621-921D-6F87A6219DDE</string>
<key>PayloadDisplayName</key>
<string>Restrictions</string>
<key>PayloadDescription</key>
<string/>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>forceDelayedSoftwareUpdates</key>
<true/>
<key>forceDelayedAppSoftwareUpdates</key>
<true/>
<key>enforcedSoftwareUpdateDelay</key>
<integer>7</integer>
<key>enforcedSoftwareUpdateMinorOSDeferredInstallDelay</key>
<integer>7</integer>
<key>enforcedSoftwareUpdateNonOSDeferredInstallDelay</key>
<integer>7</integer>
<key>forceDelayedMajorSoftwareUpdates</key>
<true/>
<key>enforcedSoftwareUpdateMajorOSDeferredInstallDelay</key>
<integer>90</integer>
</dict>
</array>
</dict>
</plist>
This looks very promising, but I was wondering what kind of rights do you need to give the API user account and is there any concern about it passing that username and password in plaintext?
https://docs.jamf.com/education-services/resources/20210729/Resources_300_Lesson11.html
Check out iMazing Profile Editor too, does a great job of building custom profiles (that you can sign using the app) without including extra garbage, or messing around with PLISTs.
This is exactly what we're facing as well. Users of computer labs simply cannot be incentivised to install an update on their limited time.
The only workaround for this that I've found is to distribute the complete OS installer of the latest version of macOS to all the lab machines and then triggering startosinstall during the night. If you ask me, thats too many loops to jump through for every point and security update.
MDM-triggered updates for 1:1 machines is really hit or miss, after about a month we're looking at about a 65% update rate.
During the "old days" when the softwareupdate could be triggered (and trusted to do its job) by jamf, we were at 90%+ within a few days.
My workaround for this until Jamf add policy-based MDM commands was to set up a limited access local account in Jamf, and script an API call stored on another server located on the same subnet. The local account only has CRU for Computers/Mobile Devices, and can only send an update MDM command (e.g. if the credentials were compromised, they can't be used to remote lock devices, for example).
The server containing the API script has a scheduled task that runs at the desired time, and targets a Jamf smart group with an MDM command to install updates and restart. I'm not thrilled at having to use the API but since the script is not being downloaded to endpoints and run from there (e.g. the server with the script calls Jamf which is on the same subnet, and the credentials are not passed in plain text) it's a happy medium for now.
This is exactly what we're facing as well. Users of computer labs simply cannot be incentivised to install an update on their limited time.
The only workaround for this that I've found is to distribute the complete OS installer of the latest version of macOS to all the lab machines and then triggering startosinstall during the night. If you ask me, thats too many loops to jump through for every point and security update.
MDM-triggered updates for 1:1 machines is really hit or miss, after about a month we're looking at about a 65% update rate.
During the "old days" when the softwareupdate could be triggered (and trusted to do its job) by jamf, we were at 90%+ within a few days.
In our case, we would do periodic imaging and used eraseinstall to accomplish it. If you kept the latest build packaged in a policy with an eraseinstall script attached, you could upgrade a computer and refresh it at the same time. It truly made the entire thing a zero-touch experience. I miss the old days (of about a year ago).
My contribution to handling software updates: https://babodee.wordpress.com/2021/03/30/handling-major-upgrades-and-minor-updates-for-macos-with-jamf/
This process has worked great for us for a few months now. We are utilizing it for minor macOS updates, in an environment with macOS 10.15, 11, and 12 devices(mix of intel and arm). Out of the blue with this latest macOS 12.3.1 update that addresses a couple of zero day vulnerabilities the script is exiting with an exit code of 0 showing no new updates available, even though system preferences > software update > shows the 12.3.1 update.
Curious if anyone else utilizing this solution is seeing the same?
This process has worked great for us for a few months now. We are utilizing it for minor macOS updates, in an environment with macOS 10.15, 11, and 12 devices(mix of intel and arm). Out of the blue with this latest macOS 12.3.1 update that addresses a couple of zero day vulnerabilities the script is exiting with an exit code of 0 showing no new updates available, even though system preferences > software update > shows the 12.3.1 update.
Curious if anyone else utilizing this solution is seeing the same?
I am seeing the exact same behavior, and thought I was nuts because it was my first time trying this script.
My higher ups are having us switch to a different MDM specifically because this issue is so bad. We are Mostly M1 hardware at this point. We need an automated/scheduled way to do this. We had many eyes on the macOS M1 update test project and higher ups testing with me, so far it has not gone well. Super sporadic results. Sometimes commands showed on devices, sometimes not. This script looked nice, but so far not good results.
As much as I love Jamf, the tests for OS Version handling in the new MDM have been absolutely flawless for M1 and intel so far, so I really can't argue with their decision, (People from multiple teams were shocked saying, isn't this what Jamf does, isn't macOS Updates basically the core of what they do? I had no useful rebuttal.) Jamf has been an amazing company and I hope a "built-in option" for scheduling and macOS version control arrives quickly for all. I love this great community and sure I will still ref this often.
Feel free to DM if you have any questions
Supposedly there is an ability in Big Sur for the MDM to defer Major OS Upgrades for up to 90 days. Does anyone know what that setting is located in Jamf?
Configuration Profiles > +New > Restrictions > Functionality > Scroll all the way down.
So this is still a massive issue I see and no one has a decent solution for managing updates still😂😂😂
So I used to use one script to manage both updates and upgrades but have split this into 2 scripts to trigger version upgrades and updates.
For version upgrades I use the softwareupdates command with the fetch full installer switch which is easy on Intel but requires a few pop ups and admin elevations on M1 macs but its working fine.
For updates I use the softwareupdate command for intel macs and then MDM commands from the API for M1 macs. The issue I have with the MDM command is that it will never reboot the device and relies on the user to reboot but it doesn't tell the user you need to reboot?!?!?! This is the line I use at the moment and the forceRestart doesn't seem to do anything. Anyone got a fix for this?
https://$YOURJSS/JSSResource/computercommands/command/ScheduleOSUpdate/action/InstallForceRestart/id/$ID
Currently I have a line at the end of my script to open the software updates system prefs panel so the user can see the progress and the reboot button. But if they close this then they never know they need to reboot!??!
Is @perryd84 's way of accessing the API deprecated? Shouldn't this be done with a Bearer Token now?
Is @perryd84 's way of accessing the API deprecated? Shouldn't this be done with a Bearer Token now?
I use the bearer token to authenticate this is just calling the MDM command. The old API calls can use the bearer token as well.
After a few weeks of the API approach I think it's working fairly well though not 100% reliably.
I think the structure I've put into JAMF is OK it's just that sometimes machines get the management command but don't seem to actually do the updates even with all the bootstrap tokens in place. install.log isn't a very friendly file to read and I'm yet to spot some obvious reason for when this happens.
Other times the delays between the commands getting to the machine and the update actually installing are very long which from a staff member's point of view is a bad experience. For example I tested one this morning and it got the commands and did the scan at about 9.05am, it installed them and rebooted at 10.45am (this is a machine just sat there with nobody logged in and a fast Internet connection).
2022-04-13 09:06:18+01 BW-UNION-04 softwareupdated[334]: Removing client SUUpdateServiceClient pid=15458, uid=0, installAuth=NO rights=(), transactions=0 (/usr/libexec/mdmclient)
2022-04-13 09:06:18+01 BW-UNION-04 softwareupdated[334]: SUOSUServiceDaemon: Connection invalidated!
2022-04-13 10:46:27+01 BW-UNION-04 softwareupdated[334]: SUOSUMobileSoftwareUpdateController: Download finished: (null)
2022-04-13 10:46:27+01 BW-UNION-04 softwareupdated[334]: SUOSUServiceDaemon: Successfully downloaded & prepared, proceeding to apply & reboot
Quite what it was doing for that 1h40m is a mystery to me.
I do think that JAMF desperately needs the ability to fire off the MDM commands from within a policy though so that it can just be triggered it would be a lot simpler than everyone needing to leverage the API especially since it's getting more complex with the tokens etc.
The API to me should be for people doing specific things that they need, if there's something everyone has to use the API for then it needs putting in as a core feature.
After a few weeks of the API approach I think it's working fairly well though not 100% reliably.
I think the structure I've put into JAMF is OK it's just that sometimes machines get the management command but don't seem to actually do the updates even with all the bootstrap tokens in place. install.log isn't a very friendly file to read and I'm yet to spot some obvious reason for when this happens.
Other times the delays between the commands getting to the machine and the update actually installing are very long which from a staff member's point of view is a bad experience. For example I tested one this morning and it got the commands and did the scan at about 9.05am, it installed them and rebooted at 10.45am (this is a machine just sat there with nobody logged in and a fast Internet connection).
2022-04-13 09:06:18+01 BW-UNION-04 softwareupdated[334]: Removing client SUUpdateServiceClient pid=15458, uid=0, installAuth=NO rights=(), transactions=0 (/usr/libexec/mdmclient)
2022-04-13 09:06:18+01 BW-UNION-04 softwareupdated[334]: SUOSUServiceDaemon: Connection invalidated!
2022-04-13 10:46:27+01 BW-UNION-04 softwareupdated[334]: SUOSUMobileSoftwareUpdateController: Download finished: (null)
2022-04-13 10:46:27+01 BW-UNION-04 softwareupdated[334]: SUOSUServiceDaemon: Successfully downloaded & prepared, proceeding to apply & reboot
Quite what it was doing for that 1h40m is a mystery to me.
I do think that JAMF desperately needs the ability to fire off the MDM commands from within a policy though so that it can just be triggered it would be a lot simpler than everyone needing to leverage the API especially since it's getting more complex with the tokens etc.
The API to me should be for people doing specific things that they need, if there's something everyone has to use the API for then it needs putting in as a core feature.
Just a thought from looking at the log lines that you provided, the 2nd line says that the connection was invalidated. I wondered is that 90 minute is some kind of retry delay?
I do agree that some policy (or similar) for updates will be critical going forward. I really need the ability to schedule machine updates at a certain time over-night to update labs and employee machines while they are not being used.
Just a thought from looking at the log lines that you provided, the 2nd line says that the connection was invalidated. I wondered is that 90 minute is some kind of retry delay?
I do agree that some policy (or similar) for updates will be critical going forward. I really need the ability to schedule machine updates at a certain time over-night to update labs and employee machines while they are not being used.
I've seen that line a lot, I think it just means that it closed the session to the app store or something like that.
You can update your machines on a schedule this way, you need a script which uses the API to call the updates, wrap it in a policy then set the time/day limits on the policy in JAMF. This is how I do our students ones it's limited to Sundays which is the only day we're shut, the machines aren't on through the night as part of the sustainability policy we have.
I've seen that line a lot, I think it just means that it closed the session to the app store or something like that.
You can update your machines on a schedule this way, you need a script which uses the API to call the updates, wrap it in a policy then set the time/day limits on the policy in JAMF. This is how I do our students ones it's limited to Sundays which is the only day we're shut, the machines aren't on through the night as part of the sustainability policy we have.
It seems to me like this should be something so easy to accomplish through the basic GUI and not have a million hoops to jump through to make it all work lol. Thanks for the info!