Awesome work! We have not been 100% satisfied with our update policies, and had some issues recently. I will give this a shot in our environment. Thanks for sharing.
This looks great! I'll be checking it out this morning. Very well thought out!
Thanks.
I had this URL not found issue reported but installed updates as you described. Excellent script.
softwareupdate[1889]: No alternate URLs found for packageId amds
App Store[688]: No alternate URLs found for packageId amds
Have you seen this before?
I need to give credit where credit is due. After reading http://managingosx.wordpress.com/2009/10/12/apple-software-update-options/ and talking with Greg briefly, and given my really limited (i.e. none) ability in Python but trying to read Munki code (which is very readable without Python knowledge by the way) gave me the inspiration of what you see above. The article above does give a way to do it in 10.6 (and maybe in 10.7) but I wanted to use PlistBuddy (which I realize I did misspell in the script, gotta love HFS+ for ignoring case in this case I guess) instead of defaults because technically it's not a Apple preferences I was modifying (trying to be a good doobie about "proper" procedures when it comes to Plist editing)
installarray=defaults read /Library/Updates/index ProductPaths | grep -v "[{}]" | awk -F "=" '{print $1}' | grep -o "[^" ]+"
defaults write /Library/Updates/index InstallAtLogout -array "$installarray"
As this evolves, I'll think about putting something together in GitHub. I just hope this helps others who want to keep machines up to date silently, but aren't happy with the built in Apple softwareupdate command on it's own.
I also want to stress that this script should probably be used in environments where you can control what updates get installed since it's going to install all of them from whatever URL is set on that computer to look for updates. Last thing you'd want is Apple pushing an update, you pushing it out to your users, and then having that update be faulty, history tells us this happens more often than it should.
@Kumarasinghe yes I have seen that in my environment, but since I'm using this as a silent updater for my users, and the end results does the job intended, I didn't really look into why that's happening, nor at this time do I care.
this was the result when I ran the script on a test box...
Script result: Installing Updates that require Restart
Software Update Tool
Copyright 2002-2010 Apple
Done.
Packages have been saved to /Library/Updates
Copy: Entry, "CompletedProducts", Does Not Exist
File Doesn't Exist, Will Create: /var/db/.SoftwareUpdateOptions
Unmounting file server...
Running Recon...
Locating mobile device records...
softwareupdate[1889]: No alternate URLs found for packageId amds
App Store[688]: No alternate URLs found for packageId amds
Have you seen this before?
Yes. It has nothing to do with the script; you'd see it if you ran /usr/sbin/softwareupdate manually as well.
I ran it on a box last night... when I asked the user if anything unexpected happened when they powered off for the night, they said their system went to a grey screen and sat there. He let it set for about 5minutes and finally powered it off.
@jwojda - check the files that are being modified by the script, check on the box what softwareupdate -l returns, check if index.plist is being changed properly to reflect what was downloaded versus what was listed as available updates. It looks like initially it found updates that require restart under softwareupdate -l, but when you ran softwareupdate -d -a it didn't find anything to install.
Again, modify it to suit your needs, if you don't want to auto install updates that require restarts, you could comment out those lines.
I'm okay with auto-installing updates that require restarts...
Maybe it is working as expected...this is the results of things you said to check. I guess that I was expecting the progress bar to show and that's what never did... I will do s'more testing.
sudo softwareupdate -l
Password:
Software Update Tool
Copyright 2002-2010 Apple
Software Update found the following new or updated software:
* MacBookProRetinaSMCUpdate1.1-1.1
MacBook Pro Retina SMC Update (1.1), 165K [recommended] [restart]
* AirPortUtility-6.3.1
AirPort Utility (6.3.1), 21104K [recommended]
ls
041-9657 ProductMetadata.plist
091-7170 index.plist
nano index.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs$
<plist version="1.0">
<dict>
<key>CompleteProducts</key>
<array>
<string>041-9657</string>
<string>091-7170</string>
</array>
<key>InstallAtLogout</key>
<array>
<string>041-9657</string>
<string>091-7170</string>
</array>
<key>ProductPaths</key>
<dict>
<key>041-9657</key>
<string>041-9657</string>
<key>091-7170</key>
I'm okay with auto-installing updates that require restarts...
Maybe it is working as expected...this is the results of things you said to check. I guess that I was expecting the progress bar to show and that's what never did... I will do s'more testing.
sudo softwareupdate -l
Password:
Software Update Tool
Copyright 2002-2010 Apple
Software Update found the following new or updated software:
* MacBookProRetinaSMCUpdate1.1-1.1
MacBook Pro Retina SMC Update (1.1), 165K [recommended] [restart]
* AirPortUtility-6.3.1
AirPort Utility (6.3.1), 21104K [recommended]
ls
041-9657 ProductMetadata.plist
091-7170 index.plist
nano index.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs$
<plist version="1.0">
<dict>
<key>CompleteProducts</key>
<array>
<string>041-9657</string>
<string>091-7170</string>
</array>
<key>InstallAtLogout</key>
<array>
<string>041-9657</string>
<string>091-7170</string>
</array>
<key>ProductPaths</key>
<dict>
<key>041-9657</key>
<string>041-9657</string>
<key>091-7170</key>
I wonder if the SMC firmware updates install differently than other updates, and if the script just doesn't work with those. Haven't run across a computer needing firmware updates but thanks for the feedback, I appreciate it.
I have noticed that many firmware updates will not install unless a laptop is using the power adaptor, versus running on the battery. If you attempt to install the updates via the command line, it will reboot but will not actually install the update. I haven't seen any just hang indefinitely at a grey screen though.
It may have been the firmware updates. I just built a machine using an 10.8.3 image, but the machine already had all the firmware updates. it downloaded everything, installed the non-restart updates, and when I shut down it went to a grey screen for about 1-2 seconds then switched to teh apple progress bar..
Firmware updates might be handled differently that other requires restart updates, since I'm manually triggering the Software Update loginwindow using the SoftwareUpdateAtLogout and SoftwareUpdateOptions, there might be either different options, or different mechanisms that need to be called for that to work properly.
Again thanks for the feedback, it's good food for thought for me to investigate later if I can get my hands on a machine that needs said update (kinda hard to test something that only happens once after all)
Personally I don't know that I'd want to install any Firmware updates on our Macs in an automated way anyhow. We keep those blocked on our SUS for clients for the most part and feed those out in a manual way once they've been through enough testing. So it may be good that it doesn't really handle those type of updates.
@hkim
Thanks Han. Please post here if you have made any improvements/logic to the original script.
@hkim
Have you tested the script for OS X 10.9?
It doesn't seem to work with OS X 10.9.
Thanks
@hkim I really like your approach to software updates. I decided to try your script on 10.9.2 and have found that it does succeed in caching the packages and install them at logout. However, it is producing this error:
May 13 10:43:00 computer_name softwareupdate CLI[1220] : /usr/sbin/softwareupdate: XPC error in __60-[SUCommandLineTool _runSessionWithUpdates:skippingInstall:]_block_invoke (Error Domain=NSCocoaErrorDomain Code=4099 "Couldn’t communicate with a helper application." (The connection was invalidated from this process.) UserInfo=0x7ff5a1c12f90 {NSDebugDescription=The connection was invalidated from this process.})
Any thoughts on this?
Just to chime in and say @UESCDurandal that I too have this error pretty much word for word.
I wonder if the action is trying to spawn the GUI dialog to prompt for a restart, but is being interrupted through the use of the script or JAMF policy...
I am using 10.9.3 with V.8.73 of the JSS.
I'd have a look at loceee's patchoo scripts, they handle apple softwareupdates very nicely including different catalogs for different OS versions
We have our own custom patching script (reads in a list of updates we've "blessed" and downloads/installs only those with some CocoaDialog UI elements for user interaction/deferral and a restart timer), but I am definitely going to steal some bits of your script. I like the "install on logout" bit mainly, I would much rather use the native Software Update interface.
Is anyone using this method with Mavericks?
For me, it seems to work only on every 2nd boot, it's like:
- Run script, everything looks fine, reboot -> nothing happens. Install.log says
Software Update.app (0)[1595]: Software Update.app: None of the keys registered for post-logout install () are available
- Run script again, everything looks like the first time, reboot -> Updates are being installed. Install.log:
Software Update.app (0)[989]: Software Update.app: Starting post-logout install of 031-04361
...
...
Just wondering which "keys" it refers to in the error message...
This script works very well. Nice transparent install in the background, or on restart with standard Apple GUI.
Appears to work on 10.8, 10.9 and also tested on a single 10.10 machine.