In the case of software like Microsoft Office 2011 that over the years has had many subsequent update packages, these updates can be made an update_for Office 2011 in order to be installed immediately after the main installation. In other cases where drivers or other software have to be installed before a software title, like with Avid’s Pro Tools, the necessary software can be added to the requires array. In both of these cases all software involved are already in your munki repo and just require the applicable pkginfo metadata in order to have everything installed in a single go.
In two fairly niche cases – Final Cut Pro and Motion – after the software is installed additional software items become available through Apple’s software update mechanism. The question I had was how could I most efficiently install these additional software updates following the main install, without requiring user intervention or a second automated managedsoftareupdate run at some time in the future?
While nothing prevents you from importing this additional software directly into your munki repo and adding it to the update_for array for Final Cut Pro or Motion, because we use reposado to mirror Apple’s software update servers I didn’t want to have to import software that was already available. Additionally, many of Apple’s software update “products” have more than one installer. This makes the Mac’s built-in softwareupdate tool a much simpler and overall better way to install them. So the second question was whether or not I could trigger these applicable Apple software updates through reposado as part of the Final Cut Pro and Motion installs.
The last critical piece to this was whether I could also trigger these updates without installing any Apple software behind the scenes that might impact the user. For example, if I had made a macOS security update available I didn’t want users to inadvertently install the security update when only trying to install the applicable software and associated Apple updates.
Thankfully, I was able get the the main software title installed while also triggering Apple software updates, and all without triggering larger macOS updates.
This guide assumes you have the following:
A tested & working munki setup
A tested & working reposado setup (although not required)
It has been much discussed how imaging Macs is basically dead. Monolithic imaging just isn’t viable anymore (thanks, iMac Pro) and modular imaging unfortunately won’t automatically get you things like User Approved MDM (UAMDM). Check out Armin Briegel’s post on the death of imaging.
At the end of the day however, the goal of deploying a machine as quickly and efficiently as possible all while having to manually touch or configure little to nothing remains unchanged. So how might you do this with a DEP workflow?
This post is meant to be an overview to our new workflow, acknowledging the pitfalls, various hurdles, and acknowledging other methods as well in the hopes of getting your creative juices flowing if you, too, are considering a shift from more traditional imaging workflows to DEP. While we use Jamf Pro, this write up is meant to be MDM-agnostic.
I will write up a more granular series of posts with all our Jamf Pro policies and configurations at a later time once we’ve fully rolled out this larger workflow over the summer months.
How do you ensure regardless of a user being logged in a given Mac that your machines are connected to your Wi-Fi network?
If you are an environment that uses Active Directory, or another network account system, you need to make sure that your Macs are always online so users can login. Windows computers have the benefit of being able to utilize machine authentication, but this functionality unfortunately isn’t natively available on Macs.
Rather than having to implement a Microsoft CA and have each Mac request a cert in order to connect, our environment has developed a solution that achieves the end goal of machine-based authentication for a bound Mac using the following:
A .mobileconfig profile containing a Wi-Fi payload with a placeholder username and password copied to the local machine.
A script that gets the AD computer object name & password from the System.keychain, adds it to the .mobileconfig profile, and then installs the profile on the machine.
While I myself did not come up with this solution, I’ve developed a more streamlined process for deploying our template .mobileconfig profile and script as a postinstall script in an installer PKG.
There are already great guides for how to configure reposado & margarita (the reposado web front-end) on Ubuntu and on Mac. However, neither of these setups gave me everything I wanted in my environment.
Justifications for Docker on a Mac:
Too many web servers: Despite wanting this to run on a Linux server, I couldn’t justify spinning up yet another dedicated web server in our small environment.
Available Hardware & Storage: Unless you are going to manage which individual Apple Software Update catalogs is mirrored by reposado, you’re going to need at least 1TB of storage, as completing a full repo_sync of all available catalogs (as of this writing) takes up a whopping 462GB of storage. Luckily (or unluckily, depending on your POV), we had a severely underutilized Mac Mini that was being used solely as our internal Apple Service Toolkit (AST) NetBoot server and a spare 2TB external USB3 hard drive.
Operating System: Because the Mac Mini I had available was several macOS versions back and I wanted to avoid having to upgrade the OS all the way to High Sierra (this is due to the fact the currently available macOS Server app – 5.6.1 – requires 10.13.4 to run), I wasn’t able to get pip or flask installed (required for margarita) due to errors resulting from using TLSV1 when attempting to download this software.
Nginx: While I haven’t worked too much with Nginx up to this point, the performance benefits when under heavy loads are notably better than Apache.
To address the Meltdown vulnerability, Apple released a security update for macOS High Sierra (10.13) and later for Sierra (10.12) and El Capitan (10.11). While we avoid performing major OS and other software updates during the year to avoid negatively impacting our users, we were eager to patch this widely known security hole. Up until this point we haven’t had a reason to deploy a institution-wide patch to all our managed Macs, and we actively disable automatic software checks. So, it was time to figure out a workflow.
Apple normally releases software updates through the Mac App Store and later through other sources. Normally I prefer grabbing Apple-related updates through their Support Downloads page, as this allows us to upload a single PKG to our distribution point, and then cache the PKG on our machines so that our users can then install the software at their convenience through Self Service. However, at the time Apple had not yet released the update to their support page yet, and while I’ve been eager to test and deploy reposado to keep the update deployment within our LAN, rather than out to Apple’s servers, it just wasn’t feasible given the time-frame.
While Jamf Pro supports the ability to install all available software updates via policy, I only wanted to download and install the applicable security update. I opted instead to use the Mac’s built-in softwareupdate command-line tool to cache the security update for a later install triggered by our users.
The basic structure was as follows:
Determine the softwareupdate name of the patch and the update ID of the folder that gets created in /Library/Updates
A smart group containing all the eligible machines for the security update
A script to refresh the available softwareupdatelist and download the desired security update
A script to install the cached security update
An on-demand policy with a custom trigger to download the security update
An automated policy to invoke the on-demand policy via custom trigger to download the security update behind the scenes
A Self Service policy for our users to install the security update at their convenience
An email notifying users of the update and deadline to install it, after which the update would be installed automatically
This post covers the individual components of our security update deployment solution, while a second post covers the policy build and deployment.
See below the jump for our details about our workflow.
“Did you try restarting your computer? …” is undoubtedly the most common question asked by IT to users. And perhaps unsurprisingly, the majority of user issues get resolved by completing this simple task. Before most computers had SSDs, this wasn’t a task most users wanted to do for the simple reason that it took several minutes to close all running applications, reboot, get back to the login screen, and then fully load the OS. Thankfully, most laptops now have SSDs and so this task is significantly faster – 10 to 30 seconds total at most. And yet we still struggle to get our users to reboot.
Rather than wait for the Helpdesk tickets and phone calls to come in, we’ve taken a more proactive approach to encourage our users to reboot their computers themselves.
There are 4 things that make this work:
An extension attribute to collect the last time a machine has rebooted
A smart group to collect all computers that haven’t been rebooted after the desired amount of time
A script that presents the desired notification using jamfHelper
A policy that presents the notification to the user
Whether or not you’re looking to have your users reboot on their own, this same structure can be applied to other notifications you may want to present to your users. As an example, we use a similar structure to inform our teachers and administrators when their internal storage has less than 25% free space, as well as less than 10%.
Whether you have automated policies which install printers where they’re needed or have users install them themselves via Self Service, deploying printers in Jamf Pro is fairly painless.
A few times this year however, we’ve run into issues with some of our older printers that required us to replace them with newer models. If you happen to use a print server, however, it can be challenging to simultaneously remove and install new printers via Jamf while using the original printer name with the newly deployed printer.
As a result, I wanted to develop a smoother process for these printer swaps and so that all machines in our environment that had the old printer installed would get the new model without impacting those users’ machines.
Complicating matters in our environment was the fact that we configure several proactive policies for installing printers. In the event a computer in one of our departments or labs does not have all the necessary printer(s) already installed, these policies kick in the next time a computer checks in (every 15 minutes) and reinstalls all applicable printers. I wanted to be sure then to avoid having the old printer reinstalled via these policies once we deployed the new printer.
Additionally, the native “unmap” option in the Jamf Pro Printers payload within Policies requires that the printer name deployed on machines match what’s on the server. However, the new printer I needed to deploy needed to have the same name as the old printer in order to match the same printer queue name on our institution’s print server. I needed to be able to simultaneously uninstall the old printer, reinstall the new printer with the same name, and not unnecessarily impact our users.
Ultimately, I developed the following workflow to accomplish this task:
Temporarily disable the applicable proactive printer install policies we had configured.
Change the old printer information in Jamf Pro to something different in order to upload our new printer configuration.
Create a policy scoped to all computers with the old printer installed to run 1) a script uninstalling the old printer and 2) a printer payload to map (install) the new printer.
Once successfully deployed, update the applicable proactive printer policies with the new printer and re-enable the policies.
“If it ain’t broke, don’t fix it.” But not all things have to be broken to know they could be better …
In a spree of watching past Mac Admin presentations from various conferences not too long ago, I learned about BSDPY: a replacement to the one thing that many environments loath having to have run on Mac hardware in production – a NetBoot server. A Mac NetBoot server allows IT administrators to run a fully-functional Mac operating system on a Mac from over the network. This is frequently used for imaging Macs, as it does not require local storage. Mac NetBoot servers can also be used to deploy network-based macOS installers (NetInstall) as well as run Apple-provided troubleshooting tools with Apple Service Toolkit (AST).
The problem with the macOS NetBoot Server is that it is entirely dependent on Mac hardware running macOS and the macOS Server application. As a result, many environments begrudgingly deploy Mac Minis (or Mac Pros) as servers in production in order to utilize this functionality.
Having personally started down the road of Linux administration, I took it upon myself to move everything currently on our Mac mini – our JSS, file distribution point, and NetBoot server – all to an enterprise-grade server. BSDPY proved easy to get going by comparison once I found the right guide (thanks to @bruienne – who is also the creator of BSDPY – over on the #bspdy MacAdmins Slack channel!) .
In a previous post I went through my process for editing the postinstall script of a Jamf QuickAdd package for use with Rich Trouton’s CasperCheck tool so that it does not trigger any enrollmentComplete policies you may have.
Recently I completed an upgrade of our production JSS (Jamf Pro) and found that since version 9.82 Jamf has changed this postinstall script slightly. The process itself hasn’t changed, but the line in the script you comment out to prevent enrollmentComplete policies from running is different.
Notice now that the enroll -invitation command in line 40 now by default includes the -noPolicy flag. Only after confirming that this enroll command completes successfully does it run a policy -event enrollmentComplete.
The only other notable change is line 30 where it creates the jamf config file (/Library/Preferences/com.jamfsoftware.jamf.plist). You’ll notice the new -verifySSLCert flag. This is what determines whether or not the client will verify the SSL certificate on the JSS. There are 3 options here:
always (default) – this should be used unless you are using a cert using the built-in Certificate Authority.
always_except_during_enrollment – this is the option we use, and is recommended for those using the built-in Certificate Authority in your JSS.
never – does not check the certificate on the JSS.
Make sure then that you build your QuickAdd package after you configure this on your JSS to ensure the proper value is applied to your machines should CasperCheck run.