Deploying Logic Pro X additional content

For one computer, you can use Apple's Logic Pro X: Download additional content knowledgebase article. If you have a lot of computers to deploy the additional content to, though, you'll want to capture those .pkg files.

One way to do that is to "install" on one machine and track down the .pkg files before doing the actual install. More details at Download all of the GarageBand / Logic Pro X Content Loops.

Another way is to use Hannes Juutilainen's script to download all the .pkg files.

One you have those hundreds of .pkg files, you can import them into whatever you're using to manage your Macs. For Munki I use this bulk-import script to get them all into the repo.

Your users may have to reindex the loops to get them all to appear.

From the loops drop-down menu, select Reindex All Loops.

Then, just wait for the indexing to complete.

Setting up GAM: “Click the 3 dots to the right of your service account” not showing

GAM is a neat little command-line utility for admins to manage the G-Suite for their organizations.

The setup process is fairly straightforward, even though there are a lot of steps.

I did notice one little bit of weirdness that actually has nothing to do with GAM, but it put a little wrench in my GAM setup process. I don't know if many people will encounter this issue, but I'm writing it up just in case someone else does and is Googling for solutions.

At a certain point, GAM will prompt you to Click the 3 dots to the right of your service account. I didn't see the 3 dots. I kept thinking "Are the instructions out of date?" That seemed odd, though, since there was just a new release of GAM recently. I also couldn't find anything on the GAM mailing list indicating that the option had disappeared.

I then realized my browser window was too small (I don't expand it all the way out horizontally.

Notice how, with a smaller window width, there are no three dots on the right?

Expand the window width a bit, and then the three dots reappear, though!

I would have thought Google would have some kind of responsive web design to the page, but I guess not. In any case, if you run into this same issue, that's the solution—expand your browser window!

USB-C Multi-port adapter constantly prompts to install drivers

If you've run into the issue of the multi-port adapter constantly prompting to install drivers even after you've already installed the drivers (particularly annoying, since it requires a reboot), apparently the solution is to plug the power cable in through the multi-port adapter (instead of through a separate port). Worked for me that way.

Hat tip to Zak Nilsson on the MacAdmins Slack for making me aware of this fix.

AutoPkg recipe writing: things to look out for

AutoPkg is a cool project for Mac admins (in theory, Windows admins could use it, too, and there are even a few Windows recipes). Although it's a flexible framework that can be applied in many different ways, what it's most useful for is automating the tedious process of going to a website, downloading a new version of the software, and then importing that download into whatever you're using to push updates out to your Mac clients.

For a while, I was using existing recipes (there are many, so this is a totally valid approach), but eventually there was software I didn't see recipes for, so I started writing my own recipes. At first, I just started by copying existing templates and just modifying certain parts (the download URL, or the regular expressions to search for within the search URL).

Here are some things I noticed, in case you ever want to write your own recipes and run into these issues.

Arguments need to be separate

I ran into this issue where I was trying to purge the destination before unarchiving a .zip file, but it didn't seem to be working. Even though the archive_path and destination_path seemed to work fine without being in the Arguments dictionary, the purge_destination key wasn't registering until I put them all into the Arguments dictionary, as I should have from the start... so, remember to always put all arguments in an actual Arguments dictionary. Example:


Code signature verification within disk images

When you're doing code signature verification on a disk image, you don't have to explicitly use the DmgMounter processor to mount the disk image. Instead, you can just treat the .dmg as a folder that includes the bundle to be verified. Here's an example (where %pathname% refers to the downloaded .dmg):

<string>identifier "net.gete.diskmakerx" and anchor apple generic and certificate 1[field.1.2.840.113635.] /* exists */ and certificate leaf[field.1.2.840.113635.] /* exists */ and certificate leaf[subject.OU] = "2U4ZFMT67D"</string>

Dealing with regular expressions

If you're not a regex expert, some of the regular expression searches for the URLTextSearcher processor may look like gibberish to you.

A few tips to help with that, apart from (or maybe in addition to?) reading up on all the details of the Python regex documentation:

  • Before you put the regex into your recipe, you can test out your regex using Regex101 (select the Python one).
  • Generally speaking, the most useful thing I've found is creating a capture group with
  • Just as you're about to put the regex into your recipe, make sure to substitute &lt; for < and &gt; for >

Code: Debugging the Gender Gap screening at SI

On Wednesday, May 17, we will be screening Code: Debugging the Gender Gap here at SI. Students, faculty, and staff are all welcome to come, and the event counts as a GOYB!


After the screening, we will have a discussion with guest panelists from the industry:

Lin Ling, Director of Growth at SourceClear

Lin loves building scalable growth stories at early stage B2B start ups. Today, she works with engineers and data scientists to grow paying customers at SourceClear - a software security firm. Originally a STEM nerd from NYC, she never thought she would be leading growth strategies in Silicon Valley. Other: ran growth at Spigit - innovation software firm, over caffeinated as a Deloitte Consultant doing tech systems for Google, etc. Loves yoga, D3.js, and converting websites.

Monica Garde, Software Engineer at Google Inc.

Monica has been at Google for the past 4 years as a Software Engineer on a number efforts, most recently on the Search team bringing features to emerging markets. Outside of the office, Monica runs a Girls Who Code club in Mountain View and works with to help local nonprofits improve their technical infrastructure. Prior to Google, Monica was a student at Cornell University where she studied Computer Science.

Katie Lane, Product Marketing at Bugsnag

Katie is a Texas native, and graduated from the University of Texas where she studied Electrical Engineering. Katie has spent time in various tech roles such as designing high availability data-centers, to working on the wifi chips in your cell phones, and now in product marketing, helping tech companies better communicate their products to the world. She loves teaching Girls Who Code and hopes to inspire lifelong learning for girls in tech.

Movie Trailer

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.

Script AutoPkg trust verification and trust update process

Starting with version 1, AutoPkg began evaluating trust info for recipes, so you could see what changes were made to a recipe (if changes were made) and then accept the changes if you wanted to. Here is what the typical trust verification workflow looks like.

Whether running a list of recipes via script or via AutoPkgr schedule, I'd occasionally get error'ed recipes when trust was broken, have to manually run

autopkg verify-trust-info -vv NAMEOFRECIPE
and then, after review, run
autopkg update-trust-info NAMEOFRECIPE
and then run the recipe after updating the trust info:
autopkg run -v NAMEOFRECIPE
So I thought I'd take a stab at scripting the whole process. Basically my script updates all the repos (to see if there are changes), verifies trust info on each of the recipes in the recipe list, and then prompts the user to review changes and approve them or not, before running all the approved or unchanged recipes.

It's still in the early testing phase, but it seems to work so far....

Guided Access mode after a reboot on iOS 9 vs. iOS 10 vs. iOS 11 vs. iOS 12

iOS 12 Update: Just tested on iOS 12, and it gets out of guided access mode after a reboot.

iOS 11 Update: Just tested on iOS 11, and it stays in guided access mode after a reboot. Same with iOS 11.1.

Update: Just saw an iPad with 10.3.3 not get out of guided access mode after a reboot.

Just a quick observation based on testing:

If you're in Guided Access mode on an iPad running iOS 9.3.5 (say, an older model that can't install iOS 10 and above), and you do a forced reboot (hold home and power buttons until the Apple symbol appears), the device stays in Guided Access mode.

If, however, you're in Guided Access mode on an iPad running iOS 10 (and perhaps in future versions?) and do a forced reboot, the device gets out of Guided Access mode.

P.S. I was able to use this to help a student out who was stuck in Guided Access mode on an older iOS version—updated it to iOS 10, rebooted, and then the iPad was out of Guided Access mode, and a new Guided Access mode passcode could be set.

Basics of Crypt 2 and Crypt Server

Graham Gilbert created a pretty cool project called Crypt 2, which forces client machines to enable FileVault2 encryption, and then sends the recovery key to a Crypt Server.

So far the documentation on Crypt 2 is rather sparse, so this is what I was able to piece together based on the README, some asking around, and a lot of trial and error.

The server

The server bit was tricky for me to figure out. I happened to have a Ubuntu 16.04 LTS server I wanted to try it out on, but the Ubuntu 14.04 and Ubuntu 12.04 instructions did not work for 16.04. I got this error when trying to run the command to get the requirements:

Collecting django-extensions==1.6.8 (from -r
crypt/setup/requirements.txt (line 4))
Could not find a version that satisfies
the requirement django-extensions==1.6.8 (from -r crypt/setup/requirements.txt (line 4)) (from versions: 0.4, 0.4.1, 0.5, 0.6, 0.7, 0.7.1, 0.8, 0.9, 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.1.0, 1.1.1, 1.2.0, 1.2.1, 1.2.2, 1.2.3, 1.2.4, 1.2.5, 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.3.5, 1.3.6, 1.3.7, 1.3.8, 1.3.9, 1.3.10, 1.3.11, 1.4.0, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.4.9, 1.5.0, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.5.6, 1.5.7, 1.5.8, 1.5.9, 1.6.1, 1.6.2, 1.6.3, 1.6.5, 1.6.6, 1.6.7, 1.7.0, 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, 1.7.6, 1.7.7)
No matching distribution found for django-extensions==1.6.8 (from -r crypt/setup/requirements.txt (line 4))

It seems a lot of people go the Docker route. I'm not really an experienced Docker user, but most of the instructions are fairly straightforward.

After you install Docker, you just pull Crypt Server:

docker pull macadmins/crypt-server

Then, to test Crypt out, try the sqlite instructions from the docs.

And then, when you're ready to go full production, scrap that container, get a proper postgresql database and then follow the Using Postgres as an external database instructions.

Special notes based on things Graham Gilbert (primary developer on Crypt) told me:

  • You should not use the sqlite3 database for production. Nor should you use grahamgilbert/postgres as a docker container for a postgres database to link up. For a production Crypt server, you should link up to an external postgres database, preferably Amazon RDS or Google Cloud SQL.
  • For an external postgres database (whether self-hosted or hosted in the cloud), all you need is a database name, a username, and a password. Crypt will do the rest (creating tables and populating them).
  • If you decide to host the postgres database on the server that's running the docker container, localhost (or is the actual Crypt docker container—it is not the host running docker. So you should specify the host as the actual fqdn or IP address.

Whether you ran the test Crypt with sqlite3 or a proper production Crypt with postgres, you should be able to see your site at

There are ton of ways, apparently, to get the site more secure. Since I'm most familiar with using Apache, I just put in a :443 VirtualHost entry with

ProxyPass /
ProxyPassReverse /
and then that worked out for getting SSL going (as long as you've got SSL going for SUBDOMAIN.MAINDOMAIN.COM... that's too much to go into for one blog entry).

Once you have that set up, go to https://SUBDOMAIN.MAINDOMAIN.COM and log in with admin and password, and then immediately change the password to a new one.

You'll then have the option to add other users with various types of permissions.

The client

The Crypt 2 client is a standard .pkg you can deploy with whatever you're using to manage your client machines. You can configure your clients' Crypt 2 preferences before deploying the .pkg.

When the user who's okay to enable encryption (one not in the SkipUsers array) logs in, a window will pop up that says This machine must be encrypted. It will reboot shortly after clicking continue.

Crypt will write a file to /var/root/crypt_output.plist with values for EnabledDate, EnabledUser, HardwareUUID, LVGUUID, LVUUID, PVUUID, RecoveryKey, and SerialNumber.

After that, probably nothing will happen for some time. Crypt 2 runs a Launch Daemon that invokes /Library/Crypt/checkin every 900 seconds (15 minutes) 120 seconds (2 minutes). After around that time, you should see the client machine show up in the web interface the admin sees.

If you're using a self-signed certificate on your Crypt server, the curl command in the checkin script will fail when escrowing the recovery key. To avoid that (thanks to Graham Gilbert for the tip), you can add the .pem somewhere on the client machine and modify the .curlrc file for root to point to it.

If you click Info... ...and then Info / Request... ...and then Retrieve Key... ... you should be able to see the recovery key.

You may have to ask permission of yourself to view the recovery key (presumably if you have users with different permission levels, a user with lesser permission would ask an admin user for temporary permissions to view the recovery key).

Other options

This isn't a comprehensive list: