Command-Control-Power Podcast featuring Scripting OS X!

I have the honor of being a guest on the latest Command-Control-Power podcast!

The wonderfully gracious hosts Joe Saponare and Sam Valencia talk with me about life as admin/consultant, my new book “Moving to zsh,” what the new shell means for Mac users and also the EraseInstall app we built at ProWarehouse and how workflows are important for admins and consultants.

I had a great time while we were recording this podcast, even though we had to schedule it “way past my usual bedtime.” I hope you enjoy listening, as well!

desktoppr v0.2 – Notarized

I have just pushed an update to my desktoppr tool which can change the desktop on macOS. No new features but the installer pkg is now notarized.

And because you need to use a newer Xcode and Swift 5 to notarize the tool, it now requires the Swift 5 Runtime support for command line tools when you install it on versions of macOS older than 10.14.4. (On those older versions, you can also continue to use desktoppr-0.1)

Check Installer Pkgs for deprecated scripts

macOS 10.15 Catalina will deprecate the built-in /bin/bash. I have talked about this at length.

The release notes for Catalina also tell us that other built-in scripting runtimes, namely Python, Perl, and Ruby. Will not be included in future macOS releases (post-Catalina) any more.

This means, that if you want to use bash, Python, Perl, or Ruby on macOS, you will have to install, and maintain your own version in the future.

However, scripts in installation packages, cannot rely on any of these interpreters being available in future, post-Catalina versions of macOS. Installer pkgs can be run in all kinds of environments and at all times, and you would not want them to fail, because a dependency is missing.

The good news is that we still have time. All the runtimes mentioned above are still present in Catalina, so the packages will continue to work for now. But if you are building installation scripts, you need to check if any of the installation scripts use one of these interpreters and fix them.

I recommend to use /bin/sh for installation scripts, since that will run in any macOS context, even the Recovery system.

If you are using third-party installer packages, you may also want to check them for these interpreters, and notify the developer that these packages will break in future versions of macOS.

To check a flat installer package, you would expand it with pkgutil --expand and then look at script files in the Scripts folder. This will work fine for a package or two, but gets tedious really quickly, especially with large distribution pkgs with many components (e.g. Office).

So… I wrote a script to do it. The script should handle normal component pkgs, distribution pkgs and the legacy bundle pkgs and mpkgs.

You can get the pkgcheck script from my Github repo.

What the script does

Once I had written the code to inspect all these types of pkgs, I realized I could grab all other kinds of information, as well. The script will check for:

  • Signature and Notarization
  • Type of Package: Component, Distribution, legacy bundle or mpkg
  • Identifier and version (when present)
  • Install-location
  • for Distribution and mpkg types, shows the information for all components as well
  • for every script in a pkg or component, checks the first line of the script for shebangs of the deprecated interpreters (/bin/bash, /usr/bin/python, /usr/bin/perl, and /usr/bin/ruby) and print a warning when found

How to run

Run the script with the target pkg file as an argument:

% ./ sample.pkg

You can give more than one file:

% ./ file1.pkg file2.pkg ...

When you pass a directory, will recursively search for all files or bundle directories with the pkg or mpkg extension in that directory:

% ./ SamplePkgs

Features and Errors

There are a few more things that I think might be useful to check in this script. Most of all, I want to add an indicator whether a component is enabled by default or not. If you can think of any other valuable data to display, let me know. (Issue or Pull Request or just ping me on MacAdmins Slack)

I have tested the script against many pkgs that I came across. However, there are likely edge cases that I haven’t anticipated, which might break the script. If you run into any of those, let me know. (File an Issue or Pull Request.) Having the troublesome pkg would of course be a great help.

Note: the script will create a scratch directory for temporary file extractions. The script doesn’t actually expand the entire pkg file, only the Scripts sub-archive. The scratch folder will be cleaned out at the beginning of the next run, but not when the script ends, as you might want to do some further inspections.

Sample outputs

This is a sample pkg I build in my book, it has pre- and postinstall scripts using a /bin/bash shebang:

% ./ SourceCodePro-2.030d.pkg
Signature:      None
Notarized:      No
Type:           Flat Component PKG
Identifier:     com.example.SourceCodePro
Version:        2.030d
Location:       /
Contains 2 resource files
postinstall has shebang #!/bin/bash
preinstall has shebang #!/bin/bash

This is the experimental notarized pkg installer for desktoppr:

% ./ desktoppr-0.2.pkg
Signature:      Developer ID Installer: Armin Briegel (JME5BW3F3R)
Notarized:      Yes
Type:           Flat Component PKG
Identifier:     com.scriptingosx.desktoppr
Version:        0.2
Contains 0 resource files

And finally, this is a big one, the Microsoft Office installer: (they have some work to do to clean up those scripts)

% ./ Microsoft\ Office\ 16.27.19071500_Installer.pkg
Microsoft Office 16.27.19071500_Installer
SamplePkgs/Microsoft Office 16.27.19071500_Installer.pkg
Signature:      Developer ID Installer: Microsoft Corporation (UBF8T346G9)
Notarized:      No
Type:           Flat Distribution PKG
Contains 11 component pkgs

    Type:           Flat Component PKG
    Version:        16.27.19071500
    Location:       /Applications
    Contains 3 resource files

    Type:           Flat Component PKG
    Version:        16.27.19071500
    Location:       /Applications
    Contains 2 resource files

    Type:           Flat Component PKG
    Version:        16.27.19071500
    Location:       /Applications
    Contains 2 resource files

    Type:           Flat Component PKG
    Version:        16.27.19071500
    Location:       /Applications
    Contains 2 resource files

    Type:           Flat Component PKG
    Version:        16.27.19071500
    Location:       /Applications
    Contains 2 resource files

    Type:           Flat Component PKG
    Version:        19.70.410
    Location:       /Applications
    Contains 30 resource files
    postinstall has shebang #!/bin/bash
    od_logging has shebang #!/bin/bash
    od_service has shebang #!/bin/bash
    od_migration has shebang #!/bin/bash
    preinstall has shebang #!/bin/bash

    Type:           Flat Component PKG
    Version:        4.13.19071500
    Location:       /Library/Application Support/Microsoft/MAU2.0
    Contains 2 resource files
    postinstall has shebang #!/bin/bash
    preinstall has shebang #!/bin/bash

    Type:           Flat Component PKG
    Version:        16.27.19071500
    Location:       /
    Contains 2 resource files
    dockutil has shebang #!/usr/bin/python

    Type:           Flat Component PKG
    Version:        0
    Location:       /private/tmp/
    Contains 1 resource files
    postinstall has shebang #!/bin/bash

    Type:           Flat Component PKG
    Version:        0
    Location:       /private/tmp/
    Contains 1 resource files
    postinstall has shebang #!/bin/bash

    Type:           Flat Component PKG
    Version:        0
    Location:       /private/tmp/
    Contains 1 resource files
    postinstall has shebang #!/bin/bash

Weekly News Summary for Admins — 2019-07-19

Still a lot of fallout from the Zoom invulnerability. It took Apple three updates to MRT (so far) to eradicate all the differently branded varieties of the Zoom client web server. Makes me wonder how many Macs there were or are with multiple of these clients installed.

We also got new betas for 10.14.5 and 10.15 and the respective iOS versions. Some of the worst data-destroying bugs seem to be fixed or at least mitigated but I am still not comfortable moving my production devices to the betas. That’s what test devices are there for. I am getting quite excited about some of the features I have seen, both for end-users and administrators.

One of those features is that zsh will become the default shell for macOS. If you want to know what that means, how to transfer your shell configuration, workflows, and scripts from bash to zsh, and increase your Terminal productivity, we are doing a half-day training in Amsterdam on September 6. You can get more details and sign up on our webpage!

If you would rather get the weekly newsletter by email, you can subscribe to the Scripting OS X Weekly Newsletter here!! (Same content, delivered to your Inbox once a week.)

On Scripting OS X

News and Opinion

Many,many thanks to Erik for his contributions to the Mac Admin community and I wish him all the best for the future!

MacAdmins on Twitter

  • Timo Perfitt: “So it begins. We just signed up to be an MDM vendor. MDS DEP deployment coming soon.”

Bugs and Security

macOS 10.15 Catalina and iOS 13

Support and HowTos

Scripting and Automation

Updates and Releases

To Watch


There are no ads on my webpage or this newsletter. If you are enjoying what you are reading here, please spread the word and recommend it to another Mac Admin!

If you want to support me and this website even further, then consider buying one (or all) of my books. It’s like a subscription fee, but you also get a useful book or two extra!

On Smart Quotes and Terminal

Typography is a wonderful art and has a long history. When humans turned from manual typesetting to machines, type writers and then computers, some compromises had to be made. One of these compromises was to use simple straight quote symbols for opening and closing the quote, rather than different quote symbols for opening and closing.

Note: which kind of quotes are used for opening and closing dependent on the language or and some convention. English uses upper quotes “…”, German opens with a lower quote: „…“, French uses ‘guillemets:’ «…», and Japanese uses hooks: 「…」

Quotation Marks have funny names in many languages. Germans call them “Gänsefüßchen,” or “little goose feet.”

See this Wikipedia article for more details.

macOS, iOS and other modern operating systems have a feature which replaces the simple or straight quote symbols with the typographic quotes. So, you type "Hello!" and the quotes are automatically replaced with the proper (depending on localization) typographic quotes. This is called “smart quotes.”

This is pretty nice, but can be troublesome when dealing with Terminal and text editors. Scripting languages and shells always use straight quotes, and cannot deal with typographic quotes.

Now, if someone sends you a command or a script that uses quotes, and it goes through an app that replaces them with smart quotes, then bash and Terminal will fail miserably.

There is not much you can do, other than be aware of this and check pasted code carefully. There is something you can do to make this easier, though.

The default monospace font used in Terminal on macOS are ‘Menlo’ or ‘SF Mono,’ depending on the macOS version. Now these are fine typefaces, but their typographic quotes are not very curly at all, making them very hard to distinguish from the ‘dumb’ straight quotes that Terminal expects. The classic ‘Monaco’ typeface on the other hand has beautiful curly typographic quotes, making them very distinct from the the straight quote.

My favorite mono space typeface ‘Source Code Pro’ also has nice curly typographic quotes. I have built this table with many common monospace typefaces and their quotes.

Quotation Mark Comparison
Quotation Mark Comparison

Now this shouldn’t be your only criteria in choosing your Terminal font, but it may be something that helps avoid quote errors.

MacADUK 2019 Presentation Video online

The recording of my MacADUK 2019 presentation: “Modern Deployment Workflows for Business” is online and available:

You can find this video and the other recorded presentations in the MacADUK 2019 playlist on YouTube.

I am really happy with how this presentation turned out and I could be more happy with the keyframe that was chosen for the video.

You can find the notes and slides at the session’s permanent page.

Many thanks again to all those who put a lot of effort into making MacADUK 2019 the great conference it was. Also thanks to the attendees with all their great feedback and applause. See you all again next year!

EraseInstall Update: Version 1.2

We (the team I work with at Pro Warehouse) have released a new version of the EraseInstall application.

Version 1.2 is now notarized, so it should continue to work with macOS 10.14.5 and newer. It also checks the battery level before starting the process and will refuse continue if the battery is low. We also fixed a few layout and other bugs.

Important Update: Because this new version is built with Swift 5, it will require the Swift 5 Runtime Support to be installed as well, when on macOS 10.14.3 and older.

But the big new feature is that you can customize the installation process of the new macOS with custom packages.

The package installers will be installed after the macOS installation is complete but before DEP runs or the first user is created. This allows for some useful customizations and shortcuts in the deployment process.

The EraseInstall application will look for package installers (pkg) files in the /Library/Application Support/EraseInstall/Packages/ folder. When the package installers are in the correct format (see below) they will be added to the startosinstall command with the --installpackage option.

For this to work, the packages have to be ‘distribution packages with an’product archives,’ i.e. distribution packages with the identifier attribute set in the product key.

Most package installers created with tools commonly used by Mac Administrators build component packages (also called ‘flat packages’). These contain the payload files that will be installed on the target system and optional installation scripts to modify the behavior.

If you usually build your packages as component packages with pkgbuild or a similar tool, you can convert them to product archives with the productbuild command:

$ productbuild --package path/to/component.pkg
--version 1.0 --identifier com.example.package productarchive.pkg

If you use a different tool to create your packages, please consult the tool’s manual or support reference whether they create component packages, distribution packages or product archives.
munkipkg: will automatically create product archives when the distribution_style key is set to true
Whitebox Packages: identifier (id) and version can be set for a distribution package project when ‘Show Advanced User Options’ is enabled in Packages -> Preferences
Jamf Composer: cannot create distribution packages or product archives. You can convert the component packages from Composer with the above productbuild command.
pkgbuild and most other tools: creates component packages which you can convert using the above productbuild command

You can use the ‘ShowLanguageChooser’ and ‘SuppressSetupAssistant’ package installers built with these scripts as some examples to start with.

You can download the installer for EraseInstall 1.2 here.

macOS Mojave Spring Update

The macOS Mojave 10.14.4 update dropped on Monday night, along with iOS 12.2. Like last year’s 10.13.4 update, these updates didn’t only bring the usual “bug fixes and improvements” but new features, both user facing and “under the hood.”

Apple even put a section on the ‘Enterprise Content’ of the updates in the macOS release notes!

What’s new in the updates for macOS Mojave:

Enterprise content:

  • Fixes an issue that could prevent mobile accounts from logging in from an off-network Mac after changing their network account password.
  • Fixes an issue that intermittently prevented apps from downloading from the App Store or installing via MDM.
  • Mobile Active Directory accounts that have used their personal recovery key (PRK) to unlock a FileVault volume are no longer required to continue using the PRK to unlock, but can use their login password instead.

The macOS Server/Profile Manager release notes, provide more information on some management related features:


  • Export a predefined set of device information values for specified devices using a new command-line tool, exportDeviceInfo
  • Skip True Tone pane in Setup Assistant
  • Configure new restrictions: screenshot and remote screen observation
  • Configure Exchange Web Services authentication certificate
  • Configure Apple Remote Desktop access
  • Configure managed classes on student Mac computers
  • Configure Certificate Transparency payload


  • Enable or disable Voice and Data Roaming and Personal Hotspot
  • Configure new restrictions: Personal Hotspot modification (supervised only), disable server-side Siri logging
  • Display phone number, ICCID, and IMEI details of enrolled Dual SIM devices
  • Configure Certificate Transparency payload

– Configure Managed Software Updates

While I do not recommend to macOS Server/Profile Manager as a production MDM, it is useful for testing new features and as a reference implementation.

We didn’t get new, disrupting features on the scale of user-approved MDM this year, but the spring update still warrants extra attention and preparation from system admins.