Firmware Updates Redux

Mac firmware updates generally need some sort of user intervention in order to apply them.

This makes it very difficult to automate the process. I did manage at one point to automate SMC updates, but EFI updates and other hardware (keyboards, trackpads, graphics) each have their own issues.

So I finally decided to just punt on the issue. Here’s what I do now: a script runs at login and checks softwareupdate, looking for available firmware updates. If there are any, the user is notified to call the help desk.

The script follows.


#!/usr/bin/perl -w

use strict;

# change 'com.myorg' to your organization name
my $prefs = "com.myorg.firmwareupdatecheck";

# check the last time we ran on this machine; 
# exit if we already ran today so we don't annoy too much
my $now = time;
my $lastChecked = 
   `defaults -currentHost read $prefs lastChecked 2>/dev/null`;
chomp $lastChecked;
if ($lastChecked ne "") {
  my $daysSinceLastChecked = 
     int(($now-$lastChecked)/(60*60*24));
  exit if ($daysSinceLastChecked < 1);
}

# get list of available updates from softwareupdate
my $allupdates = `softwareupdate -l | grep '^   \\* '`;
chomp $allupdates;
my @updates = split /\n/, $allupdates;
my $firmwareupdates = "";
my $firmwarelist = "";
my $otherupdates = "";

# walk through the list looking for firmware updates
for my $update (@updates) {
  $update = substr($update,5);
  if ((     $update =~ /[F|f]irmware/) 
        || ($update =~ /EFI/) 
        || ($update =~ /SMC/)) {
    $firmwareupdates .= "$update ";
    $firmwarelist .= "   $update\n";
  } else {
    $otherupdates .= "$update ";
  }
}

# record when we checked and what we found
system "defaults -currentHost write $prefs lastChecked -int $now";
system "defaults -currentHost write $prefs availableUpdates '$firmwareupdates'";

if ($firmwareupdates) {
  # there are available firmware updates
  if ($otherupdates) {
    # hide the non-firmware updates since I don't want users tempted to install them
    system "softwareupdate --ignore $otherupdates >/dev/null 2>&1";
  }
  
  # are we running under an admin account?
  my $checkAdmin = `dseditgroup -o checkmember admin`;
  if ($checkAdmin =~ /^yes/) {
     # user is an admin, prompt them to install
           my $result = `osascript<<EOFA
try
  tell application "System Events"
    activate
    display alert "Firmware updates available" message "There are firmware updates available for this Mac:" & return & "$firmwarelist" as warning buttons {"Later", "Install"} default button "Install" cancel button "Later" giving up after 120
  end tell
  if button returned of the result is "Install" then
    do shell script "open '/System/Library/CoreServices/Software Update.app'"
  end if
end try
EOFA`;

  } else {
    # user is not an admin, tell them to call help desk
    my $result = `osascript<<EOFB
try
  tell application "System Events"
    activate
    display alert "Firmware updates available" message "There are firmware updates available for this Mac:" & return & "$firmwarelist" & return & "Please call Tech Support at 555-1212 for help in installing these updates." as warning buttons {"OK"} default button "OK" cancel button "OK" giving up after 120
  end tell
end try
EOFB`;
  }
}


Firmware Updates Redux

6 thoughts on “Firmware Updates Redux

  1. That’s why I wrote “WordPress may cut off the display of longer lines, but you should still be able to copy and paste into your favorite text editor.”

    -Greg

  2. Jeff says:

    Hi Greg, how do you guys deal with system updates as a whole? At our enterprise, the desktop users are not admins. This leaves them no way to run the software updates since they are not admins.

    We have a software update server, and all our OSX clients point to it for the update repository. But they have no mechanism to run this since they are not admins. I’m curious what others are doing to get around this.

  3. We use radmind; other options include pushing packages out with Apple Remote Desktop, the Casper Suite, LANRev, Kbox, etc.

    If all you care about is updates from Apple, another option would be a script that ran as root and called softwareupdate to get available updates and apply them.

Comments are closed.