COVID Journal: Week 2 1/2

The newness of being confined to quarters is wearing off. I’m noticing the innate human tendency to normalize: I now have to remind myself out loud to keep up the twenty-second hand washing, scrubbing down doorknobs and surfaces, and other daily sanitation routines.

What’s more insidious is a feeling that managing the time during the day is difficult. What seemed like an endless stretch of minutes in each day, commencing with the dawn dread of a daily Twitter update, and ending with a late night of binge TV watching or reading a novel, seems to have shrunk quickly. Now it’s easy to feel the day has departed with nothing accomplished. In the past seven days, these have been done:

an oil painting started, but not yet picked up again (next week I will try again)

a one-hour online Feldenkrais session

online shopping for handmade face masks for ourselves and our kids on Etsy, and finding that it’s hard to get one in a reasonable amount of time

a tech webinar on how to make graphs with a programming language

income tax forms returned electronically to our accountant and a check mailed to the tax board

three Netflix parties

two grocery delivery requests initiated (this is stressful when you come to realize that they won’t have what you need and that the hardworking grocery and delivery workers are beginning to burn out and probably won’t be able to get you things on time)

a drop-in radio party with our son, the Austin bubblegum-rock DJ

two social Zooms with friends

testing the waters with airline and hotel refunds from trips canceled and finding out how unfriendly this process can be

In between these necessities and distractions, we’re trying to have a semblance of order every day. I’m finding that the schedule for most days will probably be four things to cover the fourteen hours between wake up and sleep:

cooking for an hour, either for a lunch or a dinner, but not both

going for a half-hour walk around the neighborhood in the afternoon, trying to find a new route every once in a while

coding for my software startup for a maximum of three hours, or painting for two hours, but not both

reading, napping, or watching a movie for a couple of hours

There are a few unexpectedly nice things that happen here and there, usually when we meet someone new or discover someone we know who lives in the neighborhood on our distancing walks. And the trees are all in flower along the streets, so we’re coming to appreciate the grand valley oaks all around us in their bright green spring leaves. We have ignored them for the 25 years we’ve lived here.

I’m hoping in the coming weeks to feel more stable and less anxious and drained about life in general, and will try to be able to give a little more to others. That would be an opportunity to grow.

COVID Journal: First weekend of lockdown

We went out for a walk yesterday, Saturday March 21, the first sunny Saturday since citizens of the Bay Area and then California were ordered to stay at home. My wife and I started to take seclusion seriously around 10 days ago, and decided to self-isolate as best we could a week ago. As March weather here in Northern California has been good and getting ever so slightly warmer each day, the two of us have been in the habit of doing a daily 30 minute mid-afternoon stroll together on the quiet hilly suburban streets around our house, where we usually encounter one or two others. We nod or say hi to these neighborhood strangers and keep apart.

But yesterday we had envelopes to mail and food to pick up, so we decided to walk in the dedicated multi-use paths along the creek. It was a terrifying experience for me (not so much for my wife) to be honest. It appears as though everyone in the county from elementary school kids to retirees like us were out in force. The 10-foot wide pavement was hardly wide enough, with bicyclists, runners, family groups and other walkers in constant motion, or hanging out at bridge crossings having group conversations. We just tried to hold our breaths and keep to the extreme right margin, or wait for people to come and go if the pavement narrowed. On the return to our house, we illegally hopped a barricade to gain access to a dead-end footpath that was less populated, and I only felt safe once back inside with hands washed and door handles wiped down.

According to our local newspaper, it was the same scene happening in our beautiful local state and county wild parks, on Mount Tamalpais and in Point Reyes. Mobs of people, trying to escape their confinement and get needed fresh air and sunlight and space.

So now I think we will go back to the little street outings from here on out. The sky is the same, the trees are in flower and it’s sad to say, fewer possible virus-spreading humans to encounter.

COVID Journal: Online things you can do at home

While we’re all shuttered in place, it turns out that life can be busier than ever before. In this time of crisis many arts organizations, creators, and internet-savvy individuals who are sharing skills are providing us with free and fundraising opportunities to enrich our lives. I’m having to remind myself to not to try to do too many things in a single day, but the temptation is strongly there, while my wife and I sit at home, cook meals, read together, wait for packages, and try to go for walks that will keep us away from others.

With the idea of balance and calm in mind, here are some of the things I am participating in on a regular or occasional basis, or may take advantage of when things get bleak:

Live oil painting lessons with Cotswold realist painter Paul Foxton, most days of the week at 8 am Pacific time. Paul is a calming voice and a very good teacher of value, color and technique. Each day’s session is usually 60-90 minutes. Join Paul’s Facebook Art of Calm Artists group at

Live book readings, discussions and author events from the Virtual Book Channel and the Quarantine Book Club. Visit and for more information.

Live yoga sessions with New York techie Erik Hinton. Schedule varies. Subscribe at

Art and commentary from museums around the world are being shared daily under the Twitter hashtag #MuseumMomentOfZen. I have only begun to explore this resource, but one of the deepest and most thoughtful I have found so far is from the US National Gallery of Art. Their account is

More and more film makers and distributors are sharing free access to works that were only visible through DVD purchases or at limited runs in museums and art-house cinemas. Others are offering downloads or time-limited screenings for a donation to help out closed cinemas and their laid-off workers. Here is a sampling of films I have found and watched or hope to see.

The Green Fog, directed by Guy Maddin.

Helvetica, directed by Gary Hustwit. The first of Hustwit’s documentary films on design and designers that he is releasing here:

La Vendedora de Fósforos (The Little Match Girl), directed by Alejo Moguillansky, courtesy of El Pampero Cine. Streaming at

Turns out that The Little Match Girl is one of a bunch of recent Latin American films that are now streaming. Argentine critic and curator Diego Lerer has the list on his Micropsia blog.

“Circle of Quarantine”: 10 Downloads of your choice for $49.95 from the catalog of Oscilloscope Labs. Many of Oscope’s films are on Kanopy, but there are gems here such as Madeline’s Madeline, River of Grass, L’Attesa, etc.

Kino Marquee, from Kino Lorber. Their initial screenings are of the fantastic Brazilian film Bacurau, directed by Juliano Dornelles and Kleber Mendonça Filho. I guess you visit one of their sponsored donees to actually purchase virtual tickets. These are Film at Lincoln Center (New York, NY), BAM (Brooklyn, NY), Jacob Burns Film Center (Pleasantville, NY), The Little Theatre (Rochester, NY), Santa Barbara International Film Festival, Riviera Theatre (Santa Barbara, CA), The Frida Cinema (Santa Ana, CA), Denver Film / Sie FilmCenter (Denver, CO), Belcourt Theater (Nashville, TN), Loft Cinema (Tucson, AZ), Austin Film Society (Austin, TX), Wexner Center for the Arts (Columbus, OH) and Aperture Cinema (Winston Salem, NC). If you like the Austin Film Society, here’s where to purchase a $12, five-day pass for Bacurau:

Virtual Cinema, from Film Movement. Currently offering screenings of six films that would have been in theatrical release. New films Corpus Christi, directed by Jan Komasa, The Wild Goose Lake by Diao Yinan, Zombi Child by Bertrand Bonello, and Advocate by Rachel Leah Jones. And restorations of some that I really want to see: Bruno Barreto’s Dona Flor and Her Two Husbands (1976);The Killing Floor (1984), directed by Bill Duke; and especially Luchino Visconti’s L’Innocente (1976).

ElmConf US 2.0

St. Louis Courthouse
St. Louis Civil Courts Building. Architect: Klipstein & Rathmann (1930)

This year I was invited to speak to this wonderful little (300+ attendees!) pre-conference before the annual Strange Loop conference in St. Louis. I found lots of interesting food for thought in the other speakers’ talks, and I blissfully am still unaware of the predominant reception of my 20 minutes of fame, where I tried to show how “easy” it is to do nice animations in Elm using the CSS transitions engine available in modern browsers. Links to my talk are at the bottom of this post, but first off, here’s what I heard, learned and started to think about in the immediate aftermath of ElmConf:

The Future of Elm

Expanding Elm’s Acceptance in a React World

The panel Q&A at the end of the day was very interesting, judging by the significant number of votes for questions about how Elm can expand it’s reach “in companies”. I think there are several issues here that could be addressed, but I don’t work for a company that has a large programming staff, senior architect, etc. (at our company we just made the leap as a group–none of us had much Elm experience–to use Elm, and we are so happy with the results!) so I am pretty naive on the politics of platform selection in tech companies.

Evan Czaplicki (the creator of Elm) probably is not so naive, because it’s obvious he spends a lot of time understanding the questions that these employers or their employees bring to him about Elm. One significant bit that should go ka-ching in tech companies that I did hear over and over again at the conference (and it’s also my personal experience programming in Elm) is that Elm coders are extremely happy using the restrictions and conventions presented by Elm, getting help and satisfaction from the compiler, tracking down issues in the time-traveling debugger, acquiring new skills in functional, immutable programming and seeing quick reliable results and eagerly look forward to bug fixes and tricking the compiler into giving them the blessed “all clear” signal; as compared with the JavaScript world where “all clear” means now you know there are lots of other bugs lurking in your code ready to break things. When I did chime in about comparing Elm’s present-day uptake to that of Ruby on Rails from several years ago, I of course forgot to bring up the fact that there was this same feeling back then, of wow, I just have to follow the rules and this new expressive language (Ruby) and this framework (Rails) that seems to understand what I need, actually makes me happy to use it.

I know it’s not very Elm-y to go negative, but some of the anecdotes that were mentioned, about infighting in JavaScript shops over coding style, choice of frameworks, complex tooling and setup, etc sounded pretty dreadful. (“And then the whole team of 6 developers ended up quitting.”) I’m wondering if, as the number of companies that are making the switch to Elm increases, whether the main Elm website might use a few testimonials from respected names that could describe some of the contrasting pros and cons between Elm and JS, especially when it comes down to individual and team morale and productivity.

Elm Best Practices and Emerging Domain Solutions

I really liked the fact that Evan mentioned that a lot can be done to improve Elm without changing Elm itself; instead by listening carefully to long-time and newer users’ frets and misunderstandings, and responding with some important documentation and sample code. I think if there were an “Elm Foundation” (maybe there is) with a small, active board focused on PR, the biggest thing that could add more legitimacy to Elm might be an e-book series (or collection of Elm packages and sample applications) highlighting best practices in various problem domains that confront current JavaScript/React/Angular/etc. shops.

I did my own careful listening to the speakers who came before and after me, and it occurs to me that it would be wonderful to see articles, Elm Town interviews, videos, published modules, and example apps for some common problem domains that more than one speaker mentioned. These were the things I heard, and about which I don’t see a lot of published Elm work out there (yet):

Web Workers. One magic moment at the conference was when Luke Westby clicked the “make this repository public” button for his Ellie codebase. I look forward to poring over it to understand the architecture he developed for setting up Web Workers and managing compiler jobs on them. Seems like this is a very powerful paradigm that a lot of responsive Elm apps could take advantage of.

Avoiding duplication of state in the Elm model and another source of truth (either a JavaScript system connected via ports that must maintain state; or local key-value or IndexedDB storage, as in Murphy Randle’s journaling system; or a remote backend server somewhere, as Ossi Hahnihen described in a recent Elm Town interview). Both Jonas and Murphy mentioned the nightmare of keeping two sources of truth in sync. It seems like there is some consensus that Elm front-end applications are better off always pulling a complete clone of whatever state they need to present a user interface, and immediately saving any changes made to the model out to that other system. Some good rules of thumb for singe-page applications (or as Evan said, applications that load multiple pages) would help here. Richard Feldman’s elm-spa-example sample application gets to this also, as each page fetches its page-specific model when it loads.

Deciding on strategies for using ports. Murphy’s talk was great. Since ports seem to be in many Elm projects, it would be nice to have a summary article posted somewhere that describe the range of successful approaches used to communicate with the DOM and with JavaScript libraries. I think the bigger picture on ports might be a little more complicated than the one example Murphy had; there are probably a variety of use cases out there that might provide hints to developers when they have to work with the JavaScript world.

Handling touch events. After Jonas mentioned that he had to write some custom code to allow his maps to correctly interact with touch gestures on mobile devices, I poked around on Google and could not find a widely accepted touch event library in Elm. I don’t if there is consensus on one, or whether nice examples of mobile apps that correctly handle touches are out there. Or if not perhaps they should be created.

Accessibility built-in. I kept getting the feeling throughout the day that there was huge excitement in the room about Tessa Kelly’s Accessible HTML package. I would guess that just about every developer out there wants to, or has to, follow WCAG guidelines and make his or her product more accessible, and  I think the additive incremental nature of Tessa’s approach is the right one. (Don’t know how easy it is to make React-component-based sites accessible by comparison). I think it’s very tricky in Elm right now to advocate for a package that dictates all of your view code for you, but if we had an autocomplete or keyboard shortcut to paste in, say, a fully accessible tab panel layout (with comments), and then let the developer make modifications, that might help us get to a more accessible web, in Elm. Then repeat for other widgets! Maybe the future of Elm is when there is a slick IDE that can add chunks of your view with one or two keystrokes, and that you can customize for your company’s particular coding and UI standards. In the meantime, Tessa could probably write the book (maybe she is) covering best practices for the many, many common cases of making sections of your views WCAG- and ARIA-compliant and accessible.

A Self-Review

I think it’s important to reflect publicly on my first presentation at a technical conference. Perhaps because I ended up showing almost an entire Elm app, at least one attendee reported on Twitter of being scared about CSS transitions after hearing my talk. I suppose if I ever get a second chance at this kind of thing, I’ll learn to be politically and educationally more effective (as Richard Feldman eloquently described in “Teaching Elm to Beginners”). You have to lay the groundwork and motivate folks to get them to come along with something useful but perhaps a little strange, like CSS animations. But I do think I was able to implant one or two bits of Elm knowledge (and even, hopefully, some understanding) to some in attendance. I guess I can hope I was able to stir up a little curiosity in some of the conferees to learn more about how these animations work. And it was a terrific learning experience for me personally (talk about motivation…), so I thank Brian Hicks and Luke Westby, the organizers, again and again for giving me the opportunity.

Here’s the recording of the talk:

The source code for both the demo animations used in the talk and the slide deck is available from my GitHub account if you want to play around with those animations, and get links to other animation resources.

And here are the other, highly recommended talks from ElmConf. If you’re interested in the future of Elm, how to teach (and learn) Elm, how to add accessibility to your Elm site, how to add mapping capabilities to Elm, what the fashion industry may have to help us understand different styles of programming, and many other topics and philosophies, check out the complete ElmConf US 2017 playlist:

2015 in Review

I guess it’s worth trying to summarize what, if anything, I accomplished or at least experienced in the past year. Working in education, there’s a constant reminder to self that reflection is as important to growth and learning as absorbing new ideas and doing things.  So here goes:


As a nerd this is the most easily quantified as I look at the digital trail I’m leaving behind. In 2015 I tried out quite a few new programming platforms, languages and frameworks. I built things in the cloud with Javascript, Ruby, Python, Go, Swift, PHP, Reactive.JS and the Flux paradigm, Flask, Bootstrap, Material Design, d3 (a Javascript data visualization library), Grape (a Ruby API builder), Android and iOS SDKs, Xcode, Eclipse, Google App Engine and Google APIs, Amazon Web Services, Docker, HTTP Live Streaming (both on the client and on the server side), and static website generators (Pelican and Jekyll).

I created 5 new and updated 20 public source code repositories on

To get acquainted with the Internet of Things, I tinkered with Arduino, the Particle Spark, RFM69 wireless chips, and the BeagleBone Black single-board computer. My electronics (and construction) tools and skills are still very rudimentary, so here’s a place for growth in the coming year.

I also got hands-on about (especially the MakerBot Replicator) 3D printers (how they work, how to calibrate them, how to repair them).

I upgraded my school district’s network to a new firewall and helped move students and staff toward a cloud-based future and away from reliance on individual workstations and physical servers (bidding farewell to 9-year-old Apple Xserves when they fail ungracefully).


Because of my school district’s master plan to modernize our school campuses, I learned a lot about (and generated even more questions about) what the physical and technological demands of a 21st century classroom should be. EdCamps, Google Hangouts, and face-to-face meetings (especially with talented groups of people like those on the CETPA Edtech mailing list, BAISNet, the Stanford FabLearn attendees, and the Bay Area Maker Educators Google Plus community) helped immensely, and I hope that I might have provided a few useful comments in return.

Personal Growth

I don’t think I changed substantially for the better in 2015, but some milestones made an impact. There was an afternoon in April at a magnificent villa in Rio de Janeiro that my family and I spent reviewing touching correspondence that my late father received 40 years ago and that was essentially sealed away until recently. And my mother’s passing after a slow 10 year decline into forgetfulness and silence as sad as it was, did create opportunities to reach out to my siblings and their families and to eventually have a short but meaningful reunion on a beautiful New England October weekend.

In the dubious distinction category I logged 269 films on Letterboxd during 2015. Films continue to impart meaning to me, and my watchlist (films I need to see) grows longer every year, and I hope you had or have a chance to see some of the films on my 19-best list of 2015.

More fun and games (not) with iPad management

So because of Apple’s restrictions on their Device Enrollment Program (devices must have been purchased by your organization directly from AI), I have a handful of donated iPads and iPads purchased through generous and thoughtful third-party support organizations (for instance the Dedication to Special Education group) that can’t be managed via the DEP.

To keep these under my JAMF MDM management umbrella alongside the DEP devices, I must do it the old fashioned way, using Apple Configurator to “supervise” them with an enrollment profile exported from JAMF.

Problem was that after they were “prepared” and “supervised” in Configurator and magically showed up in my JAMF database, certain pieces, like the restriction profiles and the JAMF Self Service application were not showing up on the devices the way the do with the DEP devices.

After struggling awhile, the bug apparently comes down to (can you guess?): Apple IDs!

Under the JAMF Management History there were two types of failures:

  • “The app “com.jamfsoftware.selfservice” is already scheduled for management.”
  • “The iTunes Store ID of the application could not be validated.”

Turns out that to get the Self Service app on the device, the command to install the app comes from Apple (as requested by the JAMF MDM server) on a push notification, and if you’ve never set up the Apple ID fully in the iTunes App Store on the device, the command fails.

By setting up fully I mean:

  • Signing in with the Apple ID and password.
  • Changing the “Password Settings” from empty to either “Require Always” or “Require after 15 minutes.” (BTW “Require Always: seems to be Apple’s motto; I get a prompt to log in about every 30 seconds or so on these newly enrolled devices). Also it’s interesting to me that to change the password settings, you have to log in again with your Apple ID and password. Then if you’re lucky and change the password settings, you get access to the “Require Password for Free Downloads” magic slider that lets you opt out of having to sign in to “purchase” free apps (such as the JAMF Self Service).
  • Going to the App Store app and accepting the 47 pages of changed Terms and Conditions.
  • Saying “Not Now” to Apple’s pestering about setting up Family Sharing. (These are institutional iPads, not family iPads).
  • Downloading All of the “Apple Apps” (or saying “Not Now” and hoping that you remember to download them individually later). As of iOS 8.4 these are:
    • Pages
    • Numbers
    • Keynote
    • iMovie
    • GarageBand (shows up only on some iPad models)
    • iTunes U (shows up only on some iPad models)
    • Apple Store (shows up only on some iPad models)
    • Find My Friends (shows up only on some iPad models)
    • Find My iPhone (shows up only on some iPad models)
  • Keeping your fingers crossed that the “Install Self Service app” push notification will arrive in time that you don’t have to do this all over again.

Finally I learned how to jump start the process. In JAMF you have to select the device, go to Management, issue an “Update Inventory” command, and then wait.  JAMF will check the device, see that it still needs the Self Service app and issue a Self Service app install command.  Right then you have to all the “setting up fully” steps listed above.  If all is OK you will get a notice that the Self Service app will be installed.

So you wanna manage some shared iPads

Or, “Flirting With Disaster”

I have 250 shared iPads to manage for my school district, and have struggled with various simple management schemes.  When Apple announced the Device Enrollment Program last year and some of my IT friends recommended it, I decided to take the plunge.  For those who have never had the pleasure of managing iPads for a shared environment I thought it would be important to document some of the quirks as well as the official requirements for managing iPads the Apple way, which is not simple.  iPads were designed by Apple to be personal, not institutional devices, and if you need to use them in a shared setting, like we do (with between 8 and 12 iPads shared by students in a classroom), you really have to jump through some big hoops, as you’ll see below.

Compared to the Chromebooks we use in our upper grades (where you pay Google $30 one time for access to an administration console, spend one or two hours setting up organizational units and restrictions and then maybe 15 seconds per Chromebook for enrollment in your Google domain), iPad management with the DEP looks like it’s going to take about 10-15 minutes per iPad, or between 45 and 65 hours to set up 250 iPads.  It’s a factor of 40 or 60 in terms of time compared to the Chromebooks.  This will change somewhat when iOS 9 comes out, because Apple has already released some information about a per-device app licensing model that may obviate the need for setting up institution-owned Apple IDs on each iPad.

In the meantime, this summer I am lucky to have a high school intern working with me to share this load (thanks, Carter, for putting up with my rants today).  I’m hoping we can blast through those 45 hours of work in two weeks and have the iPads ready to go by mid-July. I’ll let you know, dear reader, when it’s all done.

So in the style of a cookbook recipe, here are the steps taken to “bake” some iPads.  If you’ve been through this before and found some shortcuts that I missed, let me know in a comment or private email (to pzingg at kentfieldschools dot org) and I’ll try it out and update this post if it worked for me.  Thanks in advance for those who help.


Here’s the list of accounts, servers, applications and other tools I used.

Email Accounts

We are a Google school, so all of these are set up in our Google Apps for Education domain. I use Google Account Manager (“GAM”) to create and manipulate bulk email accounts. The accounts we’ll need are:

  • An email account for your organization’s DEP access.
  • A generic Apple ID administrative email account that can accept “+” addresses, so that you can create multiple Apple IDs that communicate with a single email inbox.
  • A rescue email account for the Apple IDs you will be generating.
  • A device-specific email address for each shared iPad (we have 250 of these).


  • A Mac laptop with a USB cable to run Apple applications, a web browser.
  • A mobile phone that Apple will send you 2-factor authentication codes when you use their DEP portal.
  • One or more 1o-port USB hubs or (preferably) Bretford (or other manufacturer’s) sync-and-charging stations, to be able to prepare 10-30 iPads at a time.

Cloud Servers and Services

  • A SolarWinds Web Help Desk trouble ticket and inventory server to hold iPad asset and purchase information. This can be set up on any CentOS-compatible Linux server.
  • A CentOS 389 Directory Server LDAP server installed to hold authentication, user and location information. I set this up on an Amazon Linux EC2 instance.
  • A JAMF JSS server as the Mobile Device Management server (an MDM server is required by Apple DEP). JAMF now offers hosted subscriptions of JSS.
  • Apple’s Device Enrollment Program (“DEP”) service. You need to contact Apple to get this set up for your organization.

Mac Laptop Applications

  • Google Account Manager, a python script that lets us create the device-specific email accounts we will install on the shared iPads.
  • Apple Configurator to update the iOS version on the iPads and to return each iPad to a clean, pre-activated state.
  • Apple Script Editor with an automation script to automate the creation of Apple IDs.
  • Other Tools
    Google Sheets to keep track of deployment information and status

Recipe, Part I. One Time Data and Server Setup

Now that we have all the servers hardware and other tools in the kitchen, we can do some prep work. Give yourself a week to get this all done.

Step 1. Create an inventory and deployment spreadsheet. [Prep time: 1-2 hours.]

The initial data for the deployment comes from purchase order records. As we purchase devices, I put the data into our existing help desk ticket and asset inventory manager, Web Help Desk. I use Web Help Desk to keep track of which devices are for which schools and classrooms, etc.

We’re a Google Apps school, so I export the iPad records into a Google Sheet, with these columns:

  • Asset Tag
  • Serial No.
  • Model (“Apple iPad mini 2”)
  • Apple Order No. (if known)
  • Purchase Order No.
  • Purchase Date
  • Building (school site, like “Bacich”)
  • Department (to make the deployment group, like “Bacich 2nd Grade”)
  • Room (like “Room 22”)
  • Teacher (if assigned to a teacher; otherwise I use “Shared Use” as the teacher name)
  • iPad No. (a sequential number or number based on the asset tag)
  • Device Name (calculated from iPad No., like “ipad-33”)
  • Username (same as the Device Name for shared devices)
  • Full Name (calculated from iPad No., like “iPad 33”)
  • Email address (calculated from iPad No., like “”)
  • Apple ID (calculated from iPad No., like “”)
  • Deployment Group (like “Bacich 2nd Grade iPads”)

And I add a bunch of status columns to keep track of things:

  • DEP Eligible?
  • AppleID Created?
  • DEP Enrolled?
  • PreStage Assigned?
  • MDM Enrolled?
  • Post-Enrollment Done?
  • Profiles Installed?
  • Apps Installed?

Step 2. Apply for and receive access to the Apple Device Enrollment Program. [Prep time: 1 hour. Cooking time: 1-2 days.]

You have to fill out an online form to get into the DEP. Apple will contact you to confirm your organization. This might take a few days. Once you are in, all of your iOS devices that were purchased with your organization’s Apple Customer ID since March 2011 should be able to be added to DEP.

When you are finally enrolled, you’ll need to give DEP a mobile phone number. Every time you need to log into DEP, it will send an authentication code via SMS and won’t let you log in until you enter this code.

Step 3. Recover unredeemed or supervised VPP app redemption codes. [Prep time: 1 email. Cooking time: 2-3 hours.]

At this time you should contact Apple to get any unredeemed VPP spreadsheet codes for apps that your organization purchased converted to “managed distribution” licenses. If you had previously redeemed VPP codes for apps on iPads that were set up as “Supervised” with Apple Configurator, you should unsupervise these iPads first, so that they will be reclaimed and so that Apple can convert them to managed distribution. I didn’t have any iPads under Configurator supervision so this saved me some time (at the cost of maybe a hundred bucks in lost VPP codes).

Step 4. Create user records on the LDAP server. [Prep time: 1-2 hours.]

I wrote a small script to parse the data in the Google Sheet and create an LDIF import file that I send to the LDAP server. For each shared iPad, I create an entry (LDAP object class “inetOrgPerson”) in the “People” tree on the LDAP server:

  • Username (“uid” LDAP attribute), like “ipad-33”
  • Email address (“mail” attribute), like “”
  • Password (“userPassword” attribute)
  • Full Name (“cn”), like “iPad 33”
  • First name (“givenName”), like “iPad”
  • Last name (“sn”), like “33”
  • Building (“physicalDeliveryOfficeName”), like “Bacich”
  • Department( “departmentNumber”), like “Bacich 2nd Grade”

Once these are set up, you can connect to your LDAP server in JSS, and map the attributes in the user record to JSS attributes that will populate device records when the devices get enrolled. JSS can also install an email configuration profile on each device that will setup the email account in iOS, based on these attributes. Nice.

Step 5. Set up your MDM server. [Prep time: 1-2 hours.]

The details here are pretty vendor-specific, but I’ll explain what I had to do to get a brand new JAMF JSS server to be ready. You can connect the MDM server to the LDAP server you set up previously. You will also need to create an Apple Push Certificate, which means generating a CSR, importing it into the Apple Push Notification portal and then downloading the certificate and bringing it back into your MDM. Finally you need to add the MDM server to your DEP, which means exporting a public key from your MDM, importing it into the DEP portal (in DEP go to “Manage Servers” and click “Add MDM Server”), downloading the token for your MDM from the DEP portal and importing it into your MDM.

Once your MDM server is good with Apple (for Push Notifications and DEP), you can set up things like Buildings, Departments, configuration profiles, and (I believe this is mandatory) at least one Enrollment Profile. Note that we don’t really need to install the configuration profiles on the devices at enrollment time–they can be pushed out later once the devices are all enrolled. This will keep the wireless network traffic low while you are enrolling new devices. Which restrictions to put on iPads is another subject (maybe for another post in this series this summer).

For now I create two configuration profiles:

  • A Wi-Fi profile that will tell the iPads which wireless network to connect to, what the WPA2 password is and what proxy information to use for our school network.
  • A restrictions profile that disables FaceTime, iMessage and a lot of iCloud stuff that we don’t want to use.

In the MDM, I “scope” these two profiles to “All Mobile Devices”, so they will take effect right after the devices are enrolled.

Then before you are ready to enroll individual iPads, you will need to create a PreStage Enrollment profile. This is where you set up which “Setup Assistant” screens will be presented to the user when he/she/you activates the iPad. You probably also want to use these “General” settings:

  • Require Authentication.
  • Supervise Devices.
  • Enable Pairing.
  • Disallow MDM Profile Removal.
  • Make MDM Profile Mandatory.
  • Skip all activation Steps except “Apple ID”, because I want to have the Apple ID ready to go and don’t want my teachers to have to do this step later.
  • Use “Serial Numbers” and “Enforce Mobile Device Names” under “Mobile Device Names”. Note to self: There is a feature request for JAMF to set the device name to something it can fetch from the LDAP server, but for now I think Serial Numbers is the way to go. Once we have supervision over these devices, we can use JAMF to change the device name later; at least the serial number will help me figure out which iPad is which.

Step 6. Configure an open wireless network. [Prep time: 15 minutes.]

If you can install a Wi-Fi access point temporarily with an open network, you can save yourself having to type in a password or SSID name as each iPad is enrolled.

Recipe, Part II – Batch Processing

Now we’ve gotten our kitchen equipped with one-time setups, like making a party’s worth of cookies, we will prepare and enroll our iPads in batches. I think 20 or 30 at a time is a good number to shoot for. The limiting factors for the batch size are:

  • Your Wi-Fi network capacity and Internet bandwidth
  • How many devices can be connected to Apple Configurator at a time through USB
  • Apple ID script timeout limits (see below)

I run through each of the following steps for each batch. The times are what it seemed to take for 20 iPads.

Step 6.5 (Update!). Manually erase all content and settings to remove possible Activation Lock problems — see information below (if you know the Apple ID password on the iPad). [Cooking time: 5 minutes].

Launch the Settings app on each iPad, and try to erase all content and settings by choosing Settings > General > Reset > Erase All Content and Settings. If the device had Activation Lock enabled, you will need to provide the Apple ID and password.

Step 7. Update the iOS version for each iPad with Configurator, and get it ready for enrollment. [Prep time: 10 minutes. Cooking time: 30 minutes.]

I plan to use 3 Bretford charging stations daisy chained together via USB to do up to 30 iPads at a time. For the older style of iPad connectors, I temporarily removed the plastic holding “trays” from the Bretfords so that I have a free length of USB cable to the iPads (because of how you have to put them into recovery mode). The newer-style “lightning” USB cables are skinny and long enough to work well with the plastic trays left in the station.

Plug the USB cable from the last Bretford cart into your Mac laptop and launch Apple Configurator.

On the “Prepare” pane in Configurator, set the “Supervision” slider to “On”. click the “Set Organization Info…” button and save the name of your organization. Supervising the iPads wipes them clean and installs the latest iOS version (make sure your laptop has an internet connection, so it can fetch this from Apple). We’re going to Supervise the iPads and then Unsupervise them. This will make sure that they all start out fresh and de-activated. If there’s a simpler way to get the latest iOS on them and have them ready for DEP enrollment, please let me know! To get each iPad ready for supervision, I had to:

  • Power the iPad off. Hold the top button for 5 seconds, then “Slide to power off” and wait until it’s really off (about 15 seconds).
  • Put the iPad into recovery mode. This requires some dexterity. Plug in the Bretford USB connector for the iPad while the iPad is still powered off, at the same time that you hold the iPad’s Home button down. Keep holding that button down until you see the “iTunes” recovery mode screen appear.

Back in Configurator’s “Prepare” screen, click the “Prepare” button (if it’s the first time, get rid of confirmation–”all USB devices?”). You can go ahead and add more iPads while the Prepare steps are processed. In general here’s I found that this takes about 20 minutes (maybe longer if you have more than 10 iPads):

  • You’ll wait 8 minutes for iOS version to be downloaded.
  • Then 5 minutes for iOS version to be unpacked.
  • Then 5 minutes for iOS version to be installed.
  • Then a final 1-2 minutes for all the supervision checks to be completed.

Once all the checks are done, as shown in Configurator, click the Stop button. Go to Supervise pane, choose “All iPads”, right click and choose “Unsupervise”. This will reboot them all and remove all data as a last step.

Now the 10-30 iPads can be unplugged and are ready for DEP enrollment. EXCEPT you may find later that some of them won’t take (see below). I’m still trying to figure out why some don’t work after they all have been through the same process.

Step 8. Generate device-specific email addresses. [Prep time: 2 minutes. Cooking time: 2 minutes.]

I just make a text file that has a line like “gam create user ipad-33 firstname iPad lastname 33 password emailpass” for each shared iPad in it. Then it’s trivial to run the script (which calls the “GAM” application on each line) and create 20 email addresses in our Google domain in a matter of 1 or 2 minutes. Later when I install the email configuration profile in JSS, each iPad will get it’s own email address we can use to share projects created on the iPad.

Step 9. Generate device-specific Apple IDs. [Prep time: 5 minutes to customize script. Cooking time: 30 minutes for 20 Apple IDs].

This is a big hassle that will go away once iOS 9 comes out this fall. For now, each device needs an Apple ID so that we can deploy VPP apps to it. While you can in theory share an Apple ID across multiple devices, this leads to craziness (been there, done that). So to avoid going to the Apple Store or Apple ID website 250 times and filling out a lot of repetitive information, there’s an Apple Script to automate that. There are several versions floating around on the ‘net. Be aware that each version is slightly different and will only work with specific versions of ITunes. The script pumps keyboard and mouse clicks into the iTunes application. The script I use (which I have modified slightly), creates Apple IDs in the form “”, all with a common, but cryptic password. By using a “+” email address, confirmation email messages will arrive at the base email address, “” (see next step for what you have to do there).

Before you create the Apple IDs you will have to contact your Apple engineer to arrange to have your IP address whitelisted for 30 days. If you don’t Apple will refuse more than a handful of new Apple IDs per IP address per day.

Once you have the script tweaked so that it works with iTunes and has the right domain, secret question answers, and password information, you can run it in Script Editor, specify the starting and ending “ipad numbers”, and the script will generate batches of Apple IDs with sequential email addresses. Because of timing that the script allows for selecting menu items, it takes about a minute to generate each Apple ID. And there is a maximum clock time that Applescripts are allowed to run, so (at least in my environment, I can only generate about 25 new Apple IDs at a time).

Step 10. Confirm Apple ID Email Addresses. [Prep time: 10 minutes for 20 Apple IDs].

Log into the catch-all email account. Since all my Apple IDs were given addresses of the form “”, all of the confirmation email messages will be sent to the base address, “”. Log in there and look at the Inbox. You will see a message for each Apple ID you created with a subject line like “Verify your Apple ID”. Open each message and click the link that says “Verify now >”. You will be taken to the Apple ID website, where you will have to dutifully copy the email address into the Apple ID text field (why can’t they do that for us), and type or paste in the difficult-to-crack password that you specified in your Apple ID generation script. Then click the “Verify Address” button. Hopefully this becomes easier after time.

You had better not skip this step, or your newly enrolled iPads will harangue you to the ends of the earth to confirm your email address and any iCloud features will be disabled until that address is confirmed.

Step 11. Enroll the iPads in the DEP. [Prep time: 1-2 minutes for the batch if you have the serial numbers or Apple order number].

Log into DEP. Remember, you’ll have to have your mobile phone handy to be able to log in. Go to the “Manage Devices” page. Grab the serial numbers for the batch of iPads you are going to enroll from your Google Sheet and paste them into the box under “Choose Devices by Serial Number”. You can also try and enter a serial number into the Search box and press Return. If you’re lucky DEP will show you the Apple order number and you can use that to enroll a whole batch of iPads. Sometimes you’ll be unlucky and the search results dialog won’t pop up but you can still enroll by pasting the serial number into the box.

If you’re feelin’ lucky, go ahead and paste those serial numbers into the box, set the action “Assign to Server” and select your MDM server. Then click “OK”. If you typed things in correctly, you’ll get confirmation of the assignment. After devices are assigned you can go over and click “View Assignment History” and see the Apple Order Numbers there, as well (only if all the devices were on a single Order, alas).

But if you’re really unlucky, when you enter the serial numbers for enrollment, you might a dialog that says, “Couldn’t Assign Your Devices.” You can download a CSV “assignment error file” if this is the case and you’ll probably get this wonderful description for the unsuccessful devices:


My guess is that (assuming you typed in the serial numbers right), this means that your organization didn’t purchase the iPad(s) from Apple. They might have been bought on Amazon, through DonorsChoose, or even if they were bought from Apple, it wasn’t your organization that was the customer from Apple’s point of view. You can call your Apple rep, but these iPads will have to be managed the old-fashioned way, using Configurator. I’ll write up my experiences using Configurator and JAMF on another day after I finish with my 240+ DEP iPads.

Step 12. Assign iPads (now assigned to MDM) to your MDM server’s PreStage Enrollment. [Prep time: 1 minute for the batch].

Log into your MDM. In JAMF, I go to Mobile Devices, PreStage Enrollments. I select the PreStage Enrollment I set up in Part I, click the “Refresh” button, then look at the “Scope”. I click “Edit” then sort by the “Device Assigned” (time of DEP assignment) column to show the devices I just assigned in Step 11 at the top of the list. I check off the new iPads and assign them to the PreStage and then click Save.

Step 13. Enroll the iPads and do initial post-enrollment setup (only 12 steps to get here!) [Prep time: 2 minutes PER iPad plus more time to re-do the ones that burned in the oven.]

Now we’re finally ready to get the iPads enrolled (wirelessly!). From each iPad’s Hello screen, you should proceed to choose the language and the Wi-Fi network. After connecting to Wi-Fi, if all goes well, you should see a message indicating that the iPad will be managed by your organization.

This worked for me only about 85% of the time. The other 15% of the iPads showed the “Location” setup screen (which I had disabled in my PreStage), meaning that they were headed toward a non-managed activation. I don’t have a solution for why these few but significant numbers of iPads didn’t “take” the PreStage after Step 12, nor an easy way to “reset” them so they can try again.

Anyway if it works, and you opted for Authentication in your MDM PreStage setup, you will be prompted for a username and password. If you authenticate successfully to your MDM (through its LDAP connection), the MDM will assign the LDAP attributes, like username, email address, building, department, etc., to the device as it is being enrolled.

Update: Here are four more things that can go wrong (and did):

iPad is “activation locked”.  “This iPad is currently linked to an Apple ID (i*****@k*****.org). Sign in with the Apple ID that was used to set up this iPad.” If you guess and type in the incorrect Apple ID you get: “Incorrect Apple ID. cannot be used to unlock this iPad.” If the iPad was hooked up to “Find My iPad” before, or was supervised, and then erased, you can’t re-activate it without remembering the previous Apple ID.  Nice if the iPad happened to be set up by an employee who has now left your school district. (This really did happen to me). In a last resort, Apple has a process that you can certify legally that the iPad is owned by the school district and you wait 7 to 10 days for them to release the lock.  Sheesh. Moral of this story: ALWAYS know what Apple ID has been assigned to an iPad before you erase it!  So one more step that should be inserted into the process.  See the new Step 6.5 in the process above for what you can do to prevent this from happening.  My next update will explain the painful Apple appeal process.

Invalid profile. After the authentication step, you might get this: “The configuration for this iPad could not be downloaded from Kentfield Elem School District. Invalid Profile.” The ones that give me this problem were probably low on battery and if you look at the clock in the status bar it’s not correct, so the TLS handshake and signing stuff is probably failing.

Activation server inaccessible. “Your iPad could not be activated because the activation server cannot
be reached.”  I think that this is a system clock or other network issue that prevents the SSL handshake between the iPad and Apple’s activation server.  Rebooting, charging to full battery, waiting overnight and/or wiping the iPad again eventually solved this issue.

Invalid SCEP server response.  “Profile Installation Failed. The SCEP server returned an invalid response.”  This was fixed by wiping (several times actually) and trying again.

On the Apple ID activation step, assuming you generated and confirmed the device-specific Apple ID, you can type in the Apple ID and password (or just skip that step).

After I’m done with the enrollment, there are a number of ways I can verify that the device was enrolled correctly:

  • In JSS it now should show up in the Mobile Devices search results
  • On the iPad if I go to the Settings app and click General, there is a message the the device is managed by my organization
  • Also in the Settings app, you can also inspect the MDM profile and any other profiles that the MDM has installed. In our case, you should see the Wi-Fi configuration profile and you should be able to connect to the private, WPA2-protected Wi-Fi network without having to type in a password.
  • On the iPad’s Home Screen, JSS installs an app named “Self Service”.

After enrollment, I do a few things on each iPad to help out teachers managed the device as a shared resource. I go to Settings, iCloud and turn off photo sharing, contacts, etc. I turn everything associated with iCloud off. But I leave the iCloud account there, so I can use “Find my iPad”.

In the meantime iOS and iTunes are bugging me to confirm the Apple ID password even though I typed it in 30 seconds ago. And they want me to tell them it’s OK to only require typing in the dang password after 15 minutes have gone by. This is a real annoyance and one I will be so glad to have disappear in the iOS 9 era.

So now after 5 days for Part 1 of the recipe (Steps 1-6), and then about 2 hours for a batch of 20 iPads in Part II (Steps 7-13), all but 3 of the batch are ready to receive apps and additional configuration profiles. In fact it took about 5 hours of solid work today to get about 30 iPads through this process (and I still haven’t set up the Apple IDs for some of them).  We’ll see over the next two weeks if it gets any easier.