Getting up and running with InstallApplications

Erik Gomez did a presentation in 2017 on his InstallApplications project:
Macbrained SF Pinterest April 2017

Now that Apple's deprecating monolithic imaging, a lot of workflows have gone to DEP=>MDM=>something else (like Munki).

After doing some testing with InstallApplications, I think we're probably going to stick with our custom script workflow, but I didn't want our tinkering with it to be in vain, so hopefully some of these notes should help another school, org, or company that wants to get its feet wet with InstallApplications and may actually find it better suited for their situation than for ours.

This isn't a comprehensive guide on how to set up InstallApplications—just some implementation notes that may help people on a few of the things we got hung up on when trying it. For more comprehensive details on InstallApplications, check out the README for it and also this blog post: CUSTOM DEP - PART 9: A PRACTICAL EXAMPLE OF INSTALLAPPLICATIONS, CRYPT, DEPNOTIFY AND MUNKI.

You will need a signing certificate for InstallApplications.

The kind you want, though, can't be obtained by an admin. It has to be created by the Team Agent.

When you add a certificate, make sure you select macOS from the drop-down menu, and then select Developer ID.

Then select Developer ID Installer

Once you go through the steps of setting up the certificate, you should have a certificate on your Mac to import into your Keychain. Import it into your login (not system) keychain.

Then, make a note of this part: Developer ID Installer: YOURDEVELOPERDESCRIPTION (AWHOLEBUNCHOFSTUFF). You'll use that later in the build-info.json file.

When you download the project from GitHub (or git clone it), you'll see a bunch of files and folders.

For the simplest set up, the only things you'll modify are build-info.json and com.erikng.installapplications.plist.

The generatejson.py file you'll use to generate a .json to put on a server somewhere (or build into your package).

When you run munkipkg on the InstallApplications project folder, you'll get a .pkg in the build folder, which you can upload to your MDM.

Special note to other Mosyle users out there—don't be silly like me and forget to check the checkbox after you upload your InstallApplications .pkg file.

Hat tip to jacobfgrant on the Mac Admins Slack for telling me the minimal files to modify.

MathType formulas shrink after editing and saving them in Microsoft Word

One teacher had an issue in MathType that involved saved formulas in a Word doc shrinking after editing and saving them again (even if the edit involved no actual changes).

The weird thing is that we tried with another user on the same machine with the same document and couldn't replicate the behavior, so it seemed to be tied to the user profile, but then later, with a fresh user profile, the issue still seemed to persist. So maybe that was a weird anomaly (it not shrinking)?

I did a bit more digging and Googling and came across this answer from WIRIS:

This is an issue with Retina displays, so that's one possible workaround: if you have a non-Retina display, use that when inserting or editing equations. The equations will be fine if merely viewed or printed when using a Retina display, but when you insert or edit one is when the sizing issue happens.

As Charles suggested in an earlier reply, "Consider reverting to Version 16.15." This is, in fact, Microsoft's recommendation as well. The answer on an earlier question in the Microsoft Community answers forum describes how to do that.

"[F]ine if merely viewed or printed" means, as far as I can tell, if you have already existing formulas that haven't been edited.

We tried reverting to 16.15, and that seemed to fix the issue.

For Munki users trying to downgrade Word to address this particular MathType issue, this is what worked for us:

  • Import Word 2016 (version 16.15).
  • Get the installs array of the binary at /Applications/Microsoft Word/Contents/MacOS/Microsoft Word, and put that in the pkginfo.
  • Modify the pkginfo to also change the version to be higher than 16.16. For us, 16.16.18091015 was sufficient for the change to take hold.
  • Create a new catalog called mathtype, and make that the only catalog for this pkginfo.
  • Put in a preinstall_script that checks for the existence of /Applications/Microsoft Word, and deletes it if necessary. If you don't do this, Munki will install 16.15, but it won't actually replace 16.16.
  • Add the mathtype catalog to the relevant manifest(s) you want to have this downgraded version of Word. Put this catalog before production, testing, or any of the other regular catalogs you have (more details on why).

Example of the preinstall_script:

#!/bin/bash

# Doesn't work if the newer version is already there, so delete it
existing_word='/Applications/Microsoft Word.app'

if [[ -a "$existing_word" ]]; then

/bin/rm "$existing_word"

fi

This downgrade procedure is modeled after the general approach to downgrading via Munki, outlined on the wiki.

P.S. The shrinking MathType formula problem persists in Word 16.17 (Word 2019).

Activating Geometer’s Sketchpad in macOS 10.13.6 (and beyond?)

In Licensing GSP Deployments by Terminal Command , I covered the officially sanctioned way to license GSP5 for Macs.

I believe that was still working even as of 10.13.5. It certainly was working in 10.12.

Unfortunately, with 10.13.6—unless you had an already activated GSP when you upgraded to 10.13.6 from 10.13.5 or earlier—you might get error messages like

usage: Sketchpad_Executable -license (register | deregister) -name LicenseName -code AuthorizationCode
in the terminal or like in the GUI, even if you're using an admin account.

So I opened a ticket with McGraw Hill, and they said:

The license for all users is stored in the "/Library/Application Support/The Geometer's Sketchpad/" so it must be a permissions issue with that folder, either creating it for a new install, or accessing it when deregistering an old install.

If you copy the "The Geometer's Sketchpad" folder for a non-admin user install (which would be found in "~/Application Support/The Geometer's Sketchpad", to the global /Library/Application Support/ folder, that should also work, provided that the folder permissions allow read/write.

Lo and behold, that was the the old non-sanctioned, unofficial way I used to license GSP5 on Macs.

Tested it out on 10.13.6. Works!

So, yeah, use the old way until McGraw Hill figures out what's going on.

Integrating DetectX Swift with Munki

If you like DetectX Swift and want to integrate it with Munki, this is how I did it. Hat tip to Zack McCauley for doing the heavy lifting, which I'm now building on. I'd recommend you read his blog post first.

So instead of having an Outset script or separate Launch Agent, I decided to put the DetectX Swift scan as part of the Munki run (specifically a script in the preflight.d directory that MunkiReport creates):

#!/bin/bash

# Run a DetectX Swift scan
/Applications/Utilities/DetectX\ Swift.app/Contents/MacOS/DetectX\ Swift search -aj /usr/local/munki/preflight.d/cache/detectx.json

Outside of MunkiReport (but connecting to the MunkiReport MySQL database), I have a script that generates a Python list of files that DetectX Swift has flagged as "issues":

$query="SELECT issues FROM detectx WHERE numberofissues > 0";
$result=mysqli_query($YOURDATABASECONNECTION, $query);
if(mysqli_num_rows($result)>0){
   // Create an array to store the results
   $larger_issues=array();
   while($row=mysqli_fetch_assoc($result)){
      
      // Create an array based on a semi-colon delimiter
      $smaller_issues=explode(";", $row['issues']);
      foreach($smaller_issues AS $smaller_issue){
          if((trim($smaller_issue)!='') AND (!in_array($smaller_issue, $larger_issues))){
            array_push($larger_issues, $smaller_issue);
         }
      }

   // End fetching results
   }

   if(!empty($larger_issues)){
      echo '<p>okay_to_delete = [ ';
      $counter=0;
      while($counter+1<count($larger_issues)){
         echo '\'' . $larger_issues[$counter] . '\',<br />';   
         $counter+=1;
      }
      echo '\'' . $larger_issues[$counter] . '\' ]</p>';
      //print_r($larger_issues);
   
   // End checking there are elements in larger issues (there should be)
   }

// End checking there are any issues
}

And finally I have a nopkg to do the actual cleaning of the issues DetectX flagged.

So why even have an array of okay-to-delete things?

Well, DetectX Swift has command-line options to scan, but it (at least as of this writing) does not have the option to command-line remove things, presumably so someone has a chance to review the things removed before actually removing them. Also, since it's just forcefully removing things (yes, I know about using shutil to remove, but I've run into weird situations in which that doesn't work consistently, so I'm using a subprocess to invoke rm instead), it's probably a good idea for at least one human to review things before they get removed.

The nopkg also copies the .json to /var/log (with a datetime stamp in the name) before removing anything.

Considerations when upgrading CrashPlan with Munki

I had a great workflow for installing CrashPlan with Munki for older versions of CrashPlan (we were on versions 3 and 4 before).

We recently made the jump to CrashPlan 6.5, though, and that workflow no longer applies. Now you have to use a deploy.properties file instead of custom.properties and userInfo.sh files.

We had some added complications to our "upgrade" process, because our new CrashPlan server is a completely different server, and we weren't migrating everyone at once, so we couldn't just change the DNS to point to the new server. I'm not sure a jump from 4 to 6.5 would have been possible as just an installation upgrade anyhow.

So what were those complications?

  • We couldn't use an installs array any more to tell Munki whether CrashPlan was installed or not. Keeping the installs array would (without managed_updates) prompt users to upgrade to CrashPlan 6.5 or, worse, just upgrade them automatically (with managed_updates). So I changed CrashPlan 4 and 6.5 to use an installcheck_script instead.
  • Since CrashPlan 6.5 isn't just an update but an actual upgrade for us (think Microsoft Office 2016 vs. Microsoft Office 2011), it's a separate item in Munki altogether, which means we also had to remove the old version from the client's SelfServeManifest before installing the new version (otherwise, the old version would just reinstall).
  • Likewise, as part of the preinstall_script for 6.5, we had to invoke the /Library/Application Support/CrashPlan/Uninstall.app/Contents/Resources/uninstall.sh script to remove 4 first.
  • Lastly, we had to have a temporary place to hold the deploy.properties file before copying it to /Library/Application Support/CrashPlan—otherwise, the old installation of CrashPlan would somehow make it disappear or be unusable by the new installer. Not sure exactly what was happening, but it wasn't being recognized when just being delivered there directly as a payload. We also tried including the deploy.properties file in the .dmg itself, but that didn't work either (prompted for server and registration key).
  • Annoyingly, if you choose not to use SSO, you can't fully automate user account creation or sign-in, so some user interaction for the upgrade is required.

Ours may be a very niche scenario (upgrading from CrashPlan 4 to CrashPlan 6.5 and not using single sign-on), but in case anyone else is in that same situation and using Munki, maybe this blog entry can save you some time in planning your rollout.

Create a .mobileconfig profile for a certificate

If you want to create .mobileconfig profile from a certificate (for example, to import into Munki), you can use Apple Configurator 2 to do so.

If you have your certificate already in your keychain, launch up Keychain Access.app and find the certificate you want to make into a .mobileconfig profile.

Right-click the certificate and select Export NAMEOFTHECERTIFICATE (export it as a .cer).

Then launch up Apple Configuration 2.app.

Select File and then New Profile


Select Certificates and then Configure.

Find and select the certificate you exported earlier.

Select File and then Save.


Pick a filename for your .mobileconfig, which you can deploy however you want (as I previously mentioned, you can import this into a Munki repo).

If munkiimport doesn’t generate an installer_item_hash in the pkginfo file

If you notice that running munkiimport on a .dmg doesn't result in an installer_item_hash generating, you might want to also run makepkginfo on that .dmg to double-check it's read-only:

makepkginfo /PATH/TO/REPO/pkgs/PROBLEMITEM.dmg
WARNING: /PATH/TO/REPO/pkgs/PROBLEMITEM.dmg is a writable disk image. Checksum verification is not supported.
WARNING: Consider converting /PATH/TO/REPO/pkgs/PROBLEMITEM.dmg to a read-only diskimage.

Failing Adobe Acrobat DC updates

Usually when new Acrobat updates come out, I can have clients pull them off the Munki server and install those updates automatically. Randomly, some clients will error out:

installer: The upgrade failed (The Installer encountered an error that caused the installation to fail. Contact the software manufacturer for assistance.)
installer:%42.031690
installer:PHASE:Preparing for installation…
installer: Package name is Adobe Acrobat DC (18.011.20038)
installer:PHASE:Validating packages…
------------------------------------------------------------------------------
installer: Upgrading at base path /
installer:%97.750000
installer:PHASE:Configuring the installation…
installer:%72.402678
installer:PHASE:Writing files…
installer:PHASE:Running package scripts…
installer:PHASE:Preparing Adobe Acrobat DC (18.011.20038)…
installer:%4.485919
installer:PHASE:Waiting for other installations to complete…
installer:STATUS:
installer:PHASE:Preparing the disk…
At first I thought maybe having the update require a logout might fix that issue, but it doesn't. The only working solution I've found is to delete the Acrobat folder, run
sudo managedsoftwareupdate --auto
and then Munki will see that Acrobat is missing and install both Acrobat and the update just fine.

Not sure if there's a less involved way to fix that. And it seems to happen only for a few clients randomly.

Using Munki’s force_install_after_date key to force items to install

Keeping machines up to date can be a challenge. Munki tries to make this as seamless as possible, especially if you mark certain items as unattended installs (Munki will try to install those items in the background and not even bother the user).

But some updates require a logout or a reboot, and users generally don't like to log out or reboot often, particularly if they have laptops (as opposed to desktops). So pending updates can sit there for days, weeks, months, even over a year, unless you force the user to install the items.

I wouldn't recommend using the force_install_after_date option very often, but it can be very handy, particularly if there are critical updates that need to get to users.

And even though Munki itself will attempt to notify users of forced updates, you may want to accompany those built-in warnings with warnings of your own (via email, in person, etc.).

At the final countdown, the screenshots below are examples of what your users will see. Every time there's an OK button in the Managed Software Center, your user has the option to close Managed Software Center for a short time, but then MSC will just pop back up again soon. At the very last dialogue, the user will have no choice but to install the pending install item.

Once again, use sparingly, but you may need to use it, so it's good to know roughly what your users will see...

Troubleshooting Munki failing to install Apple updates

Problem

If you see Apple updates (that require a reboot) not installing properly via Munki, it may be because the downloaded update is stale somehow. Not really 100% sure on how this works, since I've seen this fail even on a "stale" update downloaded the same day (not weeks ago).

Symptoms

When you log out to update, you'll see Munki's progress bar over the login screen window, and it will look for a split second as if it's trying to install the pending Apple update but then move on almost immediately to requiring a reboot.

Then, if you check the logs at /Library/Managed Installs/Logs/Install.log, you'll see something like

Apple Software Update install of Security Update 2017-001-10.12.6: FAILED for unknown reason

Workarounds

You could create a script (run from its own Launch Daemon or as part of a Munki run) to clear old updates from the /Library/Updates folder periodically (though, again, I saw this happen even with a recently downloaded update).

I've found that if you run

softwareupdate -d -a
the newly downloaded update will install just fine via Managed Software Center.

This is tricky, because it's not technically a Munki issue (Munki just uses Apple's built-in softwareupdate to install Apple software updates), but clearly there's some flaw in invoking the software update mechanism.