Loaner and Lab “Reimage”

We have found ourselves in need of more loaner laptops than ever before with growing numbers of students and faculty attending class remotely. In an effort to come up with a simple way to prepare these laptops after they are returned and sanitized I went looking for how I can set up with the least interactivity required.

After some research, I found this JamfNation thread. I can launch Jamf’s jamfhelper application and run at the login window, but only if its opened from a launchdaemon. That led me to this script which builds a launchdaemon to run jamfhelper and run through our prep workflow.

Luckily, as I described in this post from my JNUC2020 presentation, I have most of our software set up with policies on custom triggers to run with DEPNotify for our standard and zero touch deployment strategy. I took above script and customized it, and created a new prestage enrollment to skip account creation then run this script on enrollment. Of course I had to assign each serial number to this prestage enrollment so I utilized the MUT‘s Groups and Prestages template to upload the list of serial numbers to the newly created prestage for this refresh process.

With that configuration, we can have a student or help desk associate go through the setup on a lab or prepare a recently returned loaner using an erase install progress in Self Service. This allows us to set things up quickly without needing any passwords shared or requiring someone to go through the user setup process.

While not as pretty as DEPNotify, this does show a useful progression

Add and Remove from Static Groups with the Jamf API

I have 2 scripts I’ve found useful with scoping policies and profiles to a group that isn’t easily configured by other information in a device’s record. A MacBook Pro that is shared for a lab is difficult encrypt, but the same model in the same department is assigned to a specific user and that we do want to encrypt. We can scope a policy to a static group and use a Self Service policy to add a machine to that group, then trigger the policy by a custom event to kick off.

APIaddtoStaticGroup.sh grabs the serial number of the device and adds it to a static group by that groups ID number. You can easily locate the ID number of a group by checking the URL in the JSS. In the example below, the number is in the ?id= portion, represented by XX.

https://yourjssurl.com:8443/staticComputerGroups.html?id=XX&o=r

Writing the script with these variables allows for reuse, and if an update to the parameters is made it will be easy to update one script instead of every policy that may use it.

apiData="<computer_group><computer_additions><computer><serial_number>${serialNumber}</serial_number></computer></computer_additions></computer_group>"
curl \
	-s \
	-f \
	-u ${apiUser}:${apiPass} \
	-X PUT \
	-H "Content-Type: text/xml" \
	-d "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>${apiData}" ${jssHost}/JSSResource/computergroups/id/${groupID}

A few usage examples for this would be to add a machine to an exception group to temporarily remove a profile for testing at the help desk, or adding to a group that has an encryption policy scoped to it.

APIremovefromStaticGroup.sh is similarly used to remove a machine from a static group. One of the ways I’ve used this is to remove a machine from groups when repurposing a machine with an erase install policy. It could similarly be used in conjunction with the add to static group script for help desk, with a self service policy to add and remove a profile or policy for testing purposes.

apiData="<computer_group><computer_deletions><computer><serial_number>${serialNumber}</serial_number></computer></computer_deletions></computer_group>"
curl \
	-s \
	-f \
	-u ${apiUser}:${apiPass} \
	-X PUT \
	-H "Content-Type: text/xml" \
	-d "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>${apiData}" ${jssHost}/JSSResource/computergroups/id/${groupID}

Help Desk Scripts

I have added a couple items to Jamf Self Service that can be useful for Help Desk. They are simple items but can empower users and help desk staff to help when there are security obstacles, like a firmware password or out of sync user password.

NVRAMclear.sh does some minor clearing of caches and performs an NVRAM reset. This is useful on macOS systems with firmware passwords; the method to hold down CMD+Option+P+R will not traditionally work when there is a firmware password set. Clicking a Self Service policy to run this script and rebooting can potentially alleviate some issues.

update_dyld_shared_cache -root / -force -debug
/usr/libexec/xpchelper --rebuild-cache
nvram -c

resetkeychain.sh will simply remove an old keychain for a user with a keychain they can no longer access. This occasionally happens with AD mobile accounts when the password is changed on another system and then authenticated to AD updating the password. In macOS if you bypass the password change mechanism some items cannot be updated, like the Keychain password or Filevault password. This script will get rid of the issue when attempting to remember the old password is not working.

rm -rf "$home"/Library/Keychains/*

I’ve also added an installer for Recovery Selector from Two Canoes. Again firmware passwords can be a hindrance for some items, like rebooting to run diagnostics. When we have macOS devices that need diagnostics run I’ve added a Self Service policy to install this application to the /Applications/Utilities folder. The system still requires the firmware password, but you do not need to remove it just for diagnostics. In some cases you will still need to remove it to complete a repair, but this can make things quicker.

edit 2021-03-17: updated script links