Escaping an apostrophe on a PowerSchool custom page variable

Acknowledgements: Thanks to Roger Sprik on the PowerSchool forums for this tip.

I have a custom page that uses the last name field:

~([05]Last_Name)
The only problem with that is if the last name has an apostrophe in it, that can lead to unexpected stuff when used in jQuery.

Apparently, you can strip out the variable to show only the letters and numbers:

~([05]Last_Name;keep_ascii=48-57,65-90,97-122)

Chrome Gmail unread messages not appearing in bold

We had a user whose unread emails were appearing as bold in Safari (with an ugly font) and not bold at all in Chrome (font looked okay), and we did some digging and found the solution was to enable the Arial Bold font in Font Book on the user's Mac, and it was all good.

Our best guess is that Safari couldn't find the font it wanted so substituted an ugly font but kept it bold, and Chrome couldn't find the font it wanted so substituted a decent-looking font but not bold.

When you can’t draw, erase, or highlight in Notability on iOS

A user wasn't able to draw (with a finger) using the pen tool in Notability. Highlighting and erasing were also not working (just seemed to move the note about in Notability).

We worked with the user on the usual troubleshooting steps (kill the app, do the home–power button reset, make sure iOS and Notability are both updated) to no avail.

The solution that ended up working—double-checking the notes were all backed up, and the uninstalling the app... and reinstalling the app.

Fix for Google Sheets error message: “Can’t save your changes. Copy any recent changes, then revert to an earlier revision”

If you come across a message that Google Sheets can't save your sheets and you need to revert to an earlier version, but even the earlier version can't save, don't bother doing any of these suggested steps. Clearing cookies won't help. Disabling extensions won't help.

Instead, try this (as counterintuitive as it seems): copy and paste your Google Sheets cells into a new Excel workbook. Save the Excel workbook and upload it to Google Drive. Open it with Google Sheets. Save that sheet. Delete your old, non-working sheet.

macOS command to add back Wi-Fi service

Acknowledgements: Hat tip to Eric Hemmeter on the MacAdmins Slack for this command.

If you want a command that will add back the Wi-Fi service if you deleted it and now want it back, here it is:

networksetup -createnetworkservice Wi-Fi en1
That's assuming the output of
networksetup -listallhardwareports
has a hardware port of Wi-Fi with its device being en1 (could be en0, for example).

Using Munki to manage Mac preferences with .mobileconfig profiles

You may sometimes script preferences using defaults write commands (don't edit the .plist files with a text editor directly). For example, you might change Munki client preferences using a command like:

sudo defaults write /Library/Preferences/ManagedInstalls SoftwareRepoURL "https://subdomain.yourserver.com/munki_repo"
That's fine to do, but if you're actually managing Munki client preferences (not just for Munki-related settings but for other third-party or macOS settings), why not use Munki's built-in support for .mobileconfig profiles?

There are several methods to get or generate .mobileconfig profiles. I'm listing them below in order of preference from top recs to not-to-top recs.

Just finding existing profiles

Chances are if you want to manage a setting, someone else has also wanted at some point to manage that setting. site:github.com mobileconfig is a great Google search for finding those.

Using mcxToProfile to generate a profile

You can create .mobileconfig profiles from existing .plist preference files you already have on a sample client machine. Just download Tim Sutton's mcxToProfile.

Then you can run something like

./mcxToProfile --plist /Library/Preferences/ManagedInstalls.plist --identifier MunkiPrefs
and then you can hand-edit the resulting .mobileconfig file to get out anything extraneous (for example, if all you want to set is the SoftwareRepoURL).

Generating Profiles with Apple Configurator

Apple Configurator is another option.

Just click File and select New Profile.

Once you've selected everything you want to configure, click Save.

The code it produces is (like mcxToProfile's) clean and easy to edit. And, yes, you usually want to edit down .mobileconfig profiles to be only the things you actually want to manage. Omit (i.e., delete) anything that you want your users to be able to manage themselves.

Generating profiles with Profile Manager

If you're using Server.app, there's a built-in way to generate profiles.


I usually create a test device group with no actual devices in it.

Then, under Settings, select Edit.

Find the type of setting you want to edit (there are some generic settings and then others specific to iOS or macOS). and click Configure and check off all the stuff you want configured.

Then once you've closed out of the editing settings space, click Save for the whole device group. This will allow you to download the settings.

Click the Download button and select macOS.

Now we're getting to why I seldom use Profile Manager. It adds in a bunch of binary gobbledygook and shoves all of the tags together so it's not easy to read. So, yeah, you can use it... but not fun.

Update: Apparently, you can tidy up the XML fairly easily if you want. Thanks to Ian Vonesh for the tip.

Whichever method you use, though, you can just import the .mobileconfig directly into Munki and push it out to your clients (be sure to test for unexpected behavior first before moving to production).

Importing library patrons into Follett

Follett/Destiny has its own documentation on the process of importing patrons into its online database, which is not very helpful.

Below are instructions on how you actually do it, based on trial and error and various calls to customer service for more details on the process that aren't actually documented anywhere.

Getting the Site Short Name

First of all, log in as the administrator for your account and click on List all sites, and then select the site you want to import into.

Click Back Office, and then on the left side bar that appears, click Site Configuration. On the row of tabs, find and click Site Info.

You should find your site's Short Name there. You will need to note that name for later.

Here's where things get confusing.

Even though you'll see an Import Patrons option on the left sidebar, apparently (according to customer service) you're not supposed to use that to import patrons.

Creating the XML to upload, method 1

You may want to do method 2 first so you can see what an example XML file looks like, but once you do that, you can also just create the XML directly out of PowerSchool to save you steps (and so you don't need a Windows machine every time you want to do an export/import). Here's an example PowerSchool custom page that creates the XML. Obviously, tweak to suit your own school's needs.

Note that you may see in your web browser what appear to be extra spaces in the XML file. Once you download it to your computer and open it with a text editor, the spaces should be gone, though.

Creating the XML to upload, method 2

This is the long method, but you may want to do this at least once so you have a template for the shorter method mentioned above.

First, you want to create a .csv file like this:

Site Short Name,Barcode,District ID,Last Name,First Name,Middle Name,Nickname,Patron Type,Access Level,Asset Group,Status,Gender,Homeroom,Grade Level,Card Expires,Acceptable Use Policy on File,Is Teacher,User Defined 1,User Defined 2,User Defined 3,User Defined 4,User Defined 5,Graduation Year,Birth Date,User Name,Password,Email 1,Email 2,Address 1 Line 1,Address 1 Line 2,Address 1 City,Address 1 State,Address 1 Postal Code,Address 1 Phone 1,Address 1 Phone 2,Address 2 Line 1,Address 2 Line 2,Address 2 City,Address 2 State,Address 2 Postal Code,Address 2 Phone 1,Address 2 Phone 2
YOURSITESHORTNAME,ABUNCHOFUNIQUEBARCODES,,ALASTNAME,AFIRSTNAME,AMIDDLENAME,,,,,,F,,9,,,,,,,,,2021,20030101,SOMEUSERNAME,,SOMEEMAIL@YOURSCHOOL.EDU,,,,,,,,,,,,,,,
Obviously, fill it with real data. The YOURSITESHORTNAME would be the Short Name you looked up earlier, and that will be the same for all patron records. The bar codes should be unique. In theory, I think you can auto-assign them, but we had some issues with that, so just pick some unique IDs that are 14 characters or fewer (numbers work). Dates need to be in the YYYYMMDD format.

For some reason, though, you can't just straight upload the .csv—you have to convert it to XML first using a special converter application that runs only on Windows. You can find the converter in this bundle. In order for it to run, you'll have to download and install the latest Java.

When you launch up the converter, click the Browse button next to Choose CSV file to transform and find your .csv file.

You will likely have a header row (and should), so be sure to change Data begins on row to 2 instead of 1.

In the Field Mapping tab, you'll unfortunately have to manually map each field, even though your column headers match exactly what the Destiny field names are. Just pick the appropriate field for each one in the drop-down menu for the CSV Input Field column.

In the Patron Matching tab, select Site short name & Barcode for Math patrons using their.

Then click the Save button so you won't have to re-match the fields every time you want to do an upload.

Finally, click Run, and it will create an uploadable .xml file.

Uploading the XML

One more counterintuitive thing: you don't upload through your administrator login. There's a separate login just for importing, which you'll have to get from Follett/Destiny. Log in with that login and click on District. Then click on Back Office. On the sidebar, find and click on Update Patrons.

Then, next to Update File, click Choose File and find your .xml file. Click Update Patrons and then wait for the upload to finish. To check on the progress, continually click Job Manager (on the sidebar).

Removing Find My Mac from re-imaged machines

Sadly, my 250th blog post isn't fully an original post but just a link to an awesome blog post someone else wrote, but it's a good read:
Find My Mac

The only two things I'll add are these:

If you want to clear everything out (say, if you're re-imaging a machine... not sure why you'd want to keep any firmware variables around), you can run

sudo nvram -c
which will delete all firmware variables.

If a user signs out of her iCloud account before you re-image a machine, it will clear out the fmm-mobileme-token-FMM firmware variable but not the fmm-computer-name. That's likely sufficient to prevent a future lockout, but you may want to run the previous command to clear out all firmware variables just in case.

Terminal command to see the Startup Disk in macOS

If you want to see what the current Startup Disk is on your macOS installation, you can certainly go to System Preferences > Startup Disk.

But if you want to use the terminal instead of the GUI, this command will return the current Startup Disk:

bless --getBoot
If a Startup Disk is set, you'll see something like this:
/dev/disk0s2
If no Startup Disk is set, you'll see this error message instead:
Can't access "efi-boot-device" NVRAM variable
or this one:
Could not interpret boot device as either network or disk
Can't interpet EFI boot device
And, yes, there's a typo in the error message (as of macOS 10.12.6, anyway). That should say Can't interpret instead of Can't interpet.

Use the command-line to set a firmware password on macOS

For extra security, you can add a firmware password to Macs, especially since Find My Mac is essentially useless (unlike for iPads, which have an activation lock preventing thieves from reactivating the iPad after a factory reset) and DEP-to-MDM enrollments for Macs can even be avoided by thieves if they're resourceful enough.

If you have a laptop with a firmware password, you need that password to boot from anything except the startup disk. Combine that with FileVault encryption, and a stolen Mac is pretty much useless. Doesn't mean that you'll necessarily get it back, but the likelihood is higher if the device is useless to thieves.

You can, of course, enable the firmware password via Recovery Mode, but it's easier to do it from the command line:

sudo firmwarepasswd -setpasswd
You'll be prompted for the new firmware password. Afterwards, you'll need to reboot the machine for the change to take effect. (Be sure to make sure you have an actual startup disk selected in System Preferences!)

There are two modes for a firmware password: command and full. By default, the firmware password mode will be command, which means you'll be prompted for the password only if you boot from something other than the startup disk. If, for some strange reason, you want the mode to be full, it would mean you'd be prompted for a firmware password at every boot, regardless of what you're booting to.

A few other commands you might find useful...

sudo firmwarepasswd -check
checks to see if the firmware password is set.
sudo firmwarepasswd -verify
allows you to verify you have the correct password (without rebooting).
sudo firmwarepasswd -delete
deletes the firmware password. You'll need the current one to delete it, of course.

If you want to script firmware password setting, someone wrote a fairly simple script that does it. There's also firmware password manager, which is a far more sophisticated way to manage firmware passwords.

Nota Bene: If you enable a firmware password, you can get into target disk mode by holding down the Alt/Option key at boot, typing in the firmware password, and then holding down the T key. However, you will be unable to boot into Safe Mode unless you delete the firmware password.