Updating MS Office dock icons from 2011 to 2016 using dockutil

Managing client machines while also giving your users freedom to customize their machines as they want can be a bit tricky. On the one hand, you want to automate things as much as possible so users don't have to be bothered with too many update prompts and other maintenance nuisances. On the other hand, you don't want to automate things in a way that will confuse your users.

Jamie (our Dir. of IT) and I had a discussion about moving people from Microsoft Office 2011 to Microsoft Office 2016 and what that would look like. We didn't want to just uninstall Office 2011 right away, especially since it's the only thing MathType will reliably work with (in February, 2016, Design Science announced compatibility with Office 2016 for Windows, with a note that compatibility with Office 2016 for Mac would be coming "soon"—still hasn't come over a year later, as of this writing). And, even though installing Office 2016 side by side with Office 2011 makes 2016 the default for Office files, we wanted to update the Dock icons, so people would launch Office 2016 applications instead of Office 2011 ones.

These were the situations we thought we'd encounter:

  1. User has MathType installed. If that's the case, we don't want to touch the Dock icons. We have only a handful of MathType users, and most of them have already installed Office 2016 (previously an optional install through Munki's Managed Software Center). Only one user asked about how to change the default application to be Office 2011's instead of Office 2016's.
  2. User has only Office 2016 icons in the Dock. Nothing to do in this scenario, because everything's cool already.
  3. User has a mix of Office 2016 and Office 2011 icons in the Dock. If both Word 2011 and Word 2016 are in the Dock, we're going to assume the user wants it that way, and we aren't going to mess with it. But if Excel 2011 and Excel 2016 are in the Dock but only Word 2011 is in the Dock, we want to switch that up to be Word 2016.
  4. User has only Office 2011 icons in the Dock. If this isn't a MathType user, let's switch these all up for Office 2016.
  5. User has no Office icons in the Dock. Leave it alone. If the user doesn't want shortcuts to Office, don't put any in there.

The tricky thing about changing up Office icons in the Dock is that dockutil goes by name or bundleid to add, and both the name and the bundleid is the same for Office 2011 and Office 2016 applications.

So I wrote up a script that checks based on the dockutil --list output to see if the Dock icon is for 2011 or not. It may not work exactly for your organization, but you can see the logic in there, and it's easily tweakable.

Can’t change Safari homepage in Sierra, even with no profiles managing homepage

So I came across something weird that's affected only my 10.12.4 clients (none of my 10.11.6 clients seem to be affected by this). Even though I have only one Safari profile enabled, which is set-once and doesn't manage the homepage, my 10.12.4 clients are unable to change the homepage in Safari manually. Whatever the homepage was is stuck like that. If you enter a new homepage in the Safari preferences, it will just not take and revert back to the old homepage once you hit Enter or click out of the address entry field.

The only workaround I've found for this is to delete all profiles (again, even though I don't have any profiles managing the Safari homepage):

sudo profiles -D
Are you sure you want to delete all configuration profiles? [y/n]:y
reboot the computer, and then reinstall (via Munki) all the previously installed profiles (yes, including the set-once profile for Safari that was installed before)... and then I'm able to change the homepage on the client manually. Very bizarre.

Also, after testing on a couple of other clients, there do seem to be situations in which the Safari profile was never set at all, and you still can't modify the homepage, even after deleting any other profiles and rebooting, and it's not account-specific either (freshly created account experiences it, too). It's a real head-scratcher.

Using startosinstall to install a macOS upgrade with Munki

Update: The instructions below will be obsolete once Munki 3 is released. More details on the Munki 3 implementation can be found on the Munki wiki.

createOSXinstallPkg is a great project for making an Apple macOS installer into a .pkg you can deploy with Munki.

Apple did some things to break that process for 10.12.4. People are in the process of finding workarounds for it.

One option is to use the built-in startosinstall tool that comes with the installer bundle.

If you import the bundle into Munki, you'll want to have both a preinstall_script and a postinstall_script.

The preinstall_script checks to make sure there aren't other updates pending, since startosinstall will run its own reboot independent of Munki. The pending updates should be 1 (it's the only 1) or 0 (it was part of a set of updates that did complete and then the pending updates cleared, and you're trying again):

#!/bin/bash

# Make sure there is only one pending update (this one)
pending_count=$(defaults read /Library/Preferences/ManagedInstalls PendingUpdateCount)

# If it's 1 or 0, we're good to go
if [ "$pending_count" == 1 ] || [ "$pending_count" == 0 ]; then

exit 0

else

# Otherwise, abort the installation
exit 1

fi
The postinstall_script does the actual install:
#!/bin/bash

sudo "/Applications/Install macOS Sierra.app/Contents/Resources/startosinstall" --applicationpath "/Applications/Install macOS Sierra.app" --agreetolicense --nointeraction
Just as you would with a normal OS upgrade item, you want the installs array to reflect the OS version (not the presence of the installer bundle in the /Applications folder), and you want to mark this as an Apple item. (Check the Munki wiki for more details about those two things.)

P.S. There is now a recommendation on the createOSXinstallPkg README to upgrade using 10.12.3 or investigate using startosinstall.

P.P.S It's possible, instead of my funky workaround with the preinstall_script, that you could use the --pidtosignal option instead with Munki. Here's an example using JAMF.

P.P.P.S. Looks as if Greg Neagle has started working on integrating startosinstall into Munki "natively"—yes!

Why you should use FileVault personal recovery keys instead of institutional recovery keys

In my previous blog posts on FileVault, I talked about or showed how to use an institutional recovery key for FileVault encryption:
Enabling FileVault Encryption for Client Macs
Setting up deferred FileVault encryption
Using a FileVault institutional recovery key to unlock an encrypted disk

But in exploring FileVault further, I've found it's much better to use personal recovery keys instead of a single institutional recovery key, and it's not for the reason you might think.

IRK not necessarily less secure than PRK

Yes, from a security standpoint, you could make the case that an institutional recovery key creates a single breach point (someone obtains that one recovery key and thus can decrypt all your institution's machines), but I don't think this makes personal recovery keys more secure necessarily. First of all, the personal recovery key itself can unlock a machine, but the institutional recovery key is used in combination with a password to unlock the keychain. Secondly, most likely you're storing your personal recovery keys all in one place—it may be a secure place, but it's also a single breach point. If you somehow access that one storage location (database, spreadsheet, whatever you're using to store the personal recovery keys), you have access to all the recovery keys for all the machines.

I suppose you could scatter the personal recovery keys in multiple storage locations. There is always an artistic (not scientific) balance between security and convenience, so that's up to you how you decide to store things. The point, though, is that an IRK is not necessarily less secure than a PRK.

IRK is less useful than a PRK, though

As I was rolling out encryption to our fleet using an institutional recovery key, I started to realize through testing (fortunately not through an actual emergency) how limited in functionality the institutional recovery key is compared to the personal recovery key.

First of all, unless you are physically in front of the machine or using ARD to remote into a virtual session, you cannot enable another FileVault user without storing the password for it in plain text. If you try to do so via SSH and the command-line, you'll be prompted for the password of an FV-enabled user or for the personal recovery key, so having the IRK doesn't help there.

That's not really the worst part. The worst part is that, as far as I can tell (based on Google searches, asking other Mac admins, and just trial and error), there is no way to reset a forgotten user password with just the institutional recovery key. You can unlock the encrypted volume and save the data, but you can't just say "Reset this user's password." You can, as a horribly long workaround, decrypt the drive, log in as another admin user, reset the other user's forgotten password, wait for the decryption to finish completely, and then re-encrypt. That can take a really long time.

But if you just use personal recovery keys, you can have the user try to log in three times, and she'll be prompted to enter the recovery key to reset the forgotten password, and then be prompted to enter a new password.

Wesley Whetstone has created a neat little pkg that can generate/regenerate personal recovery keys: fde-rekey.

Once you've switched that over, you can also remove the institutional recovery key (yes, it's possible to have both an IRK and a PRK). If you're using Munki, I wrote a nopkg that will remove the IRK after fde-rekey is installed.

Apple TV “the code is incorrect” error… when the code is correct!

We ran into a weird scenario where a user could not connect to Apple TV with a passcode. We tried all the usual troubleshooting stuff:

  • Does it work with another computer? Yes, it does.
  • Does it work with another user on the same computer? No, it doesn't.
  • Toggle Bluetooth? Makes no difference.
  • Reboot the AppleTV and the computer. No difference.
  • Double-check the key mapping is fine on the Mac itself. It is.
  • Try to connect to a different Apple TV. Same problem.
  • Is the time correct? Seems to be.
Ah, but that ended up being the problem (kudos to my colleague, Jerold, for finding this)—even though the time and date were technically "correct," we had to turn on location services and then set the time zone to be detected automatically in order for the Mac to connect to the Apple TV.

That's weird. It's weird because the time and date were definitely correct, and it's weird because other Macs do not have the time zone set to be detected automatically and are still able to connect to Apple TVs on campus.

But if you run into this issue where you're prompted for a passcode to connect to an Apple TV, and it keeps giving you the code is incorrect when you're absolutely sure you've typed the correct code, consider setting the time zone for automatic detection.

Script making Chrome the default browser on macOS

You would think it would be fairly simple to script changing the default browser to Chrome in macOS. It's not, as far as I can tell! I'd love to be corrected on this.

Script that changes Launch Services

I wrote up a script that changes the default browser silently, but it works well only the first time you run it.

If you run it again to switch to another browser, you may have to reboot for the change to take effect. Sometimes changing the default browser through the GUI and then running the script again will have it work again.

That means it's a bit messy. On the other hand, in terms of practical use, you're not likely to want to script changing the default browser multiple times on one machine—the whole point of scripting it is likely to just make an initial default the user can change later on her own should she choose to, and she can use the GUI to do that.

If you want to use this in conjunction with Outset but not have the settings change for existing users (only new ones), you can use this preinstall script to fake-run the login-once script for each existing user.

I think this is a great option (and not just because I worked hard on it), but I also outline below some other options.

cdef and defaultbrowser

cdef and defaultbrowser allow you to set the default browser. Unfortunately, as far as I can tell, all that does is pop up the regular GUI "set default browser" dialogue: Again, if someone knows of a silent option I don't know about, please leave a comment below, and I'll update this entry.

duti works great... but not for Chrome

In Using duti to script default applications for Macs, I detail the steps for using duti in general, which works great... in general. It just chokes on setting the default browser. If you try to use duti to set Chrome as the default browser:

com.google.chrome public.html all
com.google.chrome public.xhtml all
com.google.chrome http all
com.google.chrome https all
you will get the error:
failed to set com.google.chrome as handler for public.html (error -54)

Installing and using Google Photos backup

Google Photos offers unlimited storage for high quality (up to 16 megapixels per photo). Here are instructions for how to get it up and running on iOS (on an iPhone, for example), macOS, or Windows.

For Android (get Google Photos on the Google Play Store if it's not already on your phone), and the setup should be similar to the iOS setup.

Set up Google Photos on your iPhone or iPad
Set up Google Photos on macOS
Set up Google Photos on Windows

Set up Google Photos on your iPhone or iPad

Open up the App Store app.

Search for google photos.

Click Get to start downloading the app.

Click Install to confirm you want to download the app.

Wait for it to download.

Once it's downloaded, click Open to open the app.

You may see a couple of splash screens. Just keep clicking through to actually get started. If you don't see the splash screens, don't worry about it.

Likewise, if you see a prompt to allow Google Photos to access your photos, click OK.

Sign in with your Gmail address.

Click Continue

Make sure High quality is selected, and then click Continue again.

That's it. Now your iPhone photos should automatically back up to Google Photos.

Set up Google Photos on macOS

You all should have Managed Software Center installed already on your Mac. If you don't, let Alan know. Go to Applications and launch up Managed Software Center.

Search for and install Google Photos Backup.

Wait for it to download and install.

Go to Applications and launch up Google Photos Backup.

Click Agree

Click Continue

Log in with your Gmail account.

Make sure High quality is selected and then click Start backup.

Click OK.

Your macOS Photos photos should now back up to Google Photos.

Set up Google Photos on Windows

Go to photos.google.com/apps and then click Download.

Once the installer is downloaded, launch it up, and then click Agree

On the next screen, click Continue.

Sign in with your Gmail account.

Make sure High quality is selected, and then click Start backup.

Click OK and then your photos should start backing up to Google Photos.

Enable SSL on your web server using Let’s Encrypt and Certbot

If you have a public-facing web server you manage and want to enable SSL on it (you should want to), you can generate a self-signed certificate... or you can use Let's Encrypt as a certificate authority and generate a proper certificate.

There are Certbot downloads for various Linux and Unix platforms (including macOS).

If you're using Apache on macOS, you may have to install Homebrew first.

Then you pretty much run

sudo certbot --apache
and answer the questions that come up.

The first time I ran it, I got this weird error:

Error while running apachectl configtest.

AH00526: Syntax error on line 9 of /etc/letsencrypt/options-ssl-apache.conf: Setting Compression mode unsupported; not implemented by the SSL library
Just editing the /etc/letsencrypt/options-ssl-apache.conf file and commenting out (putting a # in front of) line 9 fixed that.

The certificate lasts only 90 days, but you're expected to automate the renewal process every 60 days anyway.

After you've Certbot-created your certificate and verified it works, do a dry run to make sure you're able to automate a renewal:

sudo certbot renew --dry-run

If that's good, you can run a cron job or launch daemon for

sudo certbot renew --quiet

Anatomy of a no-image workflow

For some background on what a no-image approach to deployment is and its benefits, read Thick imaging, thin imaging, and no imaging macOS and "BUILDING" 2015 MACS.

I tried a few approaches to no-imaging never-booted Macs, and I'm presenting here a way that worked for me, but you may very well have success with the other methods I tried that I had issues with.

Failed Attempt #1

I tried to make a distribution-style package that had all the minimal pkg files I needed to get the computer ready to run Munki bootstrapped, but when I tried to install it, I got this error message: noimageerror NoImage can't be installed on this disk. You can only install this software on the disk that is running OS X.

@elios on the Mac Admins Slack Team rightly pointed out it's likely I had accidentally enabled the rootVolumeOnly option (more details in Apple's documentation). I didn't bother going back and testing that approach again, but you may want to—just make sure you have that flag set correctly.

Failed Attempt #2

Tried having Outset do all the work and put Munki itself in the boot-once folder, but it got the boot volume in some weird state where the Apple symbol appeared but the progress bar never moved beyond halfway.

Successful Approach!

I created a pkg with a payload of the ca.pem (certificate) to /Library/Managed Installs/certs.

I had another payload of the Munki installer and the Outset installer to the /tmp directory.

One last payload is a wireless-connect script to /usr/local/outset/boot-every. It checks to see if there's already an Internet connection. If there is, then the script deletes itself. Otherwise, it connects with the supplied credentials.

And then there's a postinstall_script for the pkg that creates the .AppleSetupDone file, installs Munki and Outset, writes the appropriate values to /Library/Preferences/ManagedInstalls.plist, and creates the Munki bootstrap file.

To deploy the pkg, I have an external drive with macOS set to autologin. Then I boot that on the never-booted Mac and launch up the NoImage pkg to install to the internal drive, and then reboot, and Munki's bootstrap does the rest of the work.

Example munkipkg of the NoImage .pkg

I've built an example, which you can tweak and then use munkipkg to create a .pkg from.

Things to definitely tweak (you can tweak more, obviously, depending on your organization's needs):