Blog

Building a Tech Support Business; My Journey and Lessons Learned

Building a Tech Support Business; My Journey and Lessons Learned

My journey of creating a personalized tech support business, from brainstorming the initial concept to building a website using AI tools like Bolt.new. I also share my experiences and lessons learned while working with technologies like React, Supabase, and edge functions.
A Custom LaunchAgent for Nudge

A Custom LaunchAgent for Nudge

Why we needed to deploy a custom LaunchAgent for our school
On Hugo, the static site generator

On Hugo, the static site generator

So, I published a little blog post about browser extensions to write down how we’re currently doing it, and I thought it went well, since I didn’t look at the site on mobile at all.
How to Enforce Browser Extensions Across your Org

How to Enforce Browser Extensions Across your Org

If you’re a sysadmin or sysengineer at an organization that supports multiple browsers and platforms, this is for you.
Dash Cameras

Dash Cameras

I’ve been using the Viofo A119 Plus Duo for about 3 years now, until…
Working with Jamf School

Working with Jamf School

I’ve been using Jamf School at work for 3 years now. This is the first year (2024) in which I believe ALL of our faculty and staff Macs are enrolled in JS. Previously to the 21-22 school year, the school paid for Jamf Pro to manage the iPads for the K-5th graders and used imaging to deploy the Macs. I arrived in 2021, and that summer we began to move our devices and configurations to Jamf School.
Pfsense Https V2

Pfsense Https V2

Yesterday, I learned how to get Let’s Encrypt working on our PfSense router.
Unifi Controller HTTPS

Unifi Controller HTTPS

Here’s another HTTPS certificate story. This time, a self-hosted Unifi Controller was the invalid certificate annoyance.
A Real pfsense HTTPS Certificate

A Real pfsense HTTPS Certificate

Yesterday, I learned how to get Let’s Encrypt working on our PfSense router.

Hello World

First post!

A Custom LaunchAgent for Nudge

Planted February 4, 2025

A Custom LaunchAgent for Nudge

What is Nudge for macOS? What does it accomplish?

Nudge is an open-source tool designed to encourage (or, let’s be honest, nudge) macOS users to update their operating systems. It displays non-blocking (the users can continue working), progressively more persistent notifications reminding users to install available updates. The goal is to improve update compliance within organizations, ensuring devices are running secure and supported versions of macOS.

How does Nudge launch to tell users to update their Macs?

Nudge uses a LaunchAgent to trigger its checks and display notifications. This LaunchAgent is configured to run periodically. When it runs, Nudge checks for pending software updates. If Nudge is configured and updates are available, Nudge displays a notification to the user.

So, let’s create a custom LaunchAgent for our Nudge deployment

First, some important background info:

Read in-depth about launchd at https://www.launchd.info/

Or, skip to checking out the plist generator: https://launched.zerowidth.com/

In our case, the important information was

  1. What we’re going to launch/execute/run /Applications/Utilities/Nudge.app/Contents/MacOS/Nudge
  2. When we’re going to launch/execute/run it
    1. Well, when we’re not going to run it, actually

By default, the LaunchAgent you can download from the Nudge GitHub releases launches Nudge every 30 minutes, if the user has not deferred longer than “later”.

Specifically, we don’t want Nudge to launch during class times, so we’re going to exclude those times by specifying them in cron format.

alt text

Pressing “Create Plist” at the bottom of the generator will show you the formatted plist xml file. This is what we need to replace on or deploy to our fleet.

Let’s use a Package to deploy the new LaunchAgent

Using Composer, it’s really easy to create a new .pkg file to deploy via Jamf or your favorite MDM.

From your system, open Finder to /Library/LaunchAgents, and place the plist we generated there. Next, drag the plist onto Composer to create a new package. I added some files in /Users/Shared like a screenshot and an icon to include in Nudge.

alt text Make sure the plist is owned by root:wheel and the mode is 644 in the bottom right corner.

Next, edit the postInstall script in Composer to do a couple of things:

  1. See if a user is logged in (useful for #2 and #4)
  2. Unload the existing LaunchAgent if it exists (stops it)
    1. Step 2a is to place the new plist in place, but we’ve already done that with this package install
  3. Load the new LaunchAgent
  4. Run the Nudge postinstall script provided by the Nudge team

Here is a link to my GitHub repo with this script: custom_LaunchAgent.sh

Side note about launchctl

I’m using the newer versions (not load/unload) of launchctl commands. I really wish it had better error messages than “I/O Error” for multiple error message situations. Anyways, if a user isn’t signed in, we don’t need to bootstrap the LaunchAgent because as soon as a user signs in, all of /Library/LaunchAgents loads anyways.

Moving on…

Deploying

Now, grab the Nudge package from GitHub - I’m using Nudge-2.0.12.81807.pkg but if you need something else to better fit your deployment, read up!

Upload both the Nudge.pkg and the nudge-resources.pkg we created to your MDM and scope them to your target devices. Don’t worry, this won’t run Nudge yet! It will only place the files on their computers.

Finally, upload your completed mobileconfig file to your MDM. I would suggest scoping that to your test devices first, to see if it runs correctly, then deploy it to a larger and larger scope to see if anyone yells as Nudge starts running.

So, Why do we need to deploy a custom LaunchAgent for our school?

Nudge was too annoying. You can configure a ton of things for the Nudge UI, but you can’t configure the time of launching. There was one instance of a “perfect storm” when MacOS 15.2 was released and I was using “latest-available” instead of specifying a version like “15.1.1” to mitigate a SOFA issue where a handful of M1 Macbooks were telling the end users that their devices were out of warranty and needed to be replaced by IT.

Turns out, when the SOFA feed was updated with 15.2 and the Required Install Date was in the past, a bunch of users had entirely blurred out screens by Nudge, even those who had correctly updated to 15.1.1! Also, I’m hosting my own SOFA feed now. Read about hosting your own to lighten the load of the default one.

So now, Nudge is only launching in off hours, we’re specifying a version (15.3) and a Required Install Date (about a month from now) so that hopefully everyone has time to install it before Nudge gets pushy.

Remember, never deploy on Fridays

alt text

Was this guide helpful?

Consider using my Amazon referral code to purchase something you were already going to purchase! Just add my tag to the Amazon product URL:

?tag=starbuckstech-20

For example, here’s an awesome USB-C retractable charging cable with my affiliate code:

https://www.amazon.com/dp/B0CZDJTRPZ?tag=starbuckstech-20

Thank you!!

Written in Markdown on Obsidian.md - February 2025