With the release of 10.13.2, Apple introduced a new “feature” called User Approved Mobile Device Management Enrollment (UAMDM), which withholds certain privileges from the managing MDM until manual action, by the device user, “Approves” the right to those privileges. Apple also made it quite difficult to perform this approval remotely, with the intent that the user of the machine would have to in fact agree to these extra capabilities. This poses an issue for MacAdmins who are managing fleets of Apple devices, especially those who may not have all of their devices in a centralized location, may not have an MDM setup, or may not have DEP for devices coming in, even if they do have an MDM setup.
As I’ve talked about previously, we’re in the middle of an MDM migration over to AirWatch. Because of this, we have (selfishly) been telling our customers to hold off on upgrading their machines to 10.13.x. In our defense, up until 10.13.2, it was primarily due to stability and security concerns. But at this point, we really are just trying to have them wait so that we can avoid UAMDM troubles once we are ready to enroll their machines into our new MDM.
We are also performing our migration in as much of an automated way as possible, which means installing the MDM profile directly on the machines via a package. This means that for any 10.13 machines that are already in our fleet, we will need to figure out a way to click that pesky “Approve…” button in order to reap all of the MDM goodness that we have at our finger tips.
Taking from what I learned about trying to automate the AirWatch location services in this post, I decided to see if we could do the same kind of thing here, by using AppleScript to send button clicks on our behalf in order to Approve UAMDM. From that post we can recall that fully automating this process is essentially impossible, since we can’t authorize Script Editor.app to have the “Accessibility” access it needs to send button clicks. But it might just allow us to at least approve UAMDM remotely, which is a heck of a lot easier and faster to do than sneaker-netting to all of our 10.13 machines, especially since we are a geographically distributed organization. Side note: Have an intern? This could be a great project if you have lots of non-UAMDM machines in your fleet!
If you just want to get the script and give it a shot, you can find it on my GitHub here along with the basic instructions: https://github.com/jbaker10/Remotely-Approving-UAMDM
Giving Ourselves over to Script Editor
As mentioned above, before we really do anything further, we might as well go ahead and grant Script Editor.app the necessary permissions it needs in order to help us. I also verified that this can be done remotely using Screen Sharing.
- Open System Preferences –> Security & Privacy
- Select the Accessibility option in the left column
- Click the plus (+) button to choose the app we want to allow, which in this case is under /Applications/Utilities/Script Editor.app
- Wonderful! We should now see that Script Editor has the necessary permissions to move forward!
Don’t Forget the “…”!
Now that Script Editor is authorized to have some additional rights to our machine, we need to start the process of finding out where the “Approve…” button is in the context of the UI. Upon enrolling a 10.13.2 (or higher) device into an MDM via something like a package or using the
profiles command, if you open the “Profiles” preference pane, you will see the following screen advising you that not all MDM functionality is yet available for the device.
This, ladies and gentlemen, is UAMDM. As most already know, trying to click that “Approve…” button via something like ARD or Screen Sharing results in the following alert: Profiles cannot be approved while using remote or automated input methods.
Well, we’ll see about that.
Let’s load up the Accessibility Inspector.app, and take a look at the UI Hierarchy.
Side Note: There are instructions on finding and using this tool in the post about Automating Location Services, so I will not be covering them here.
Using Accessibility Inspector, if we choose the “Approve” button in the Profiles preference pane, we can get the hierarchy of visual attributes, which we will need to write our AppleScript.
We can quickly see a few things that will be important. 1. The “Approve” button is actually “Approve…”, with an ellipsis included at the end. 2. We can see that it is an nested attribute in a “scroll area” that does not have a name or description, which may make this just a little harder. Other than those important little details, we can see that as expected, the scroll area is nested within the “Profiles” window, which is nested in the “System Preferences” application. Great, now we have the necessary components to write our script!
Again, borrowing from what we learned previously, we know that we have to send the button click that we are trying to automate to the “System Events” process, and then from there to the actual application, in this case “System Preferences”. Therefore, we know the starting of the script should look something like this:
From there, we just need to fill in the juicy bits, including the window (“Profiles”), the scroll area (no description), and the button (“Approve…”). However, sending the button click to the scroll area proved more difficult than I realized it would. I didn’t know what to call it when trying to “talk” to it, and went through several iterations. Turns out, it’s easier to just ask the application itself what to call it. We can do this by using a
get command within AppleScript, and ask for the
UI elements within a window. So our next iteration of the AppleScript was as so:
This spit out a result like so:
I’ve highlighted the two “scroll areas” that the command found. But we still don’t know which one is which. There are two scroll areas in the “Profiles” preference pane, the one on the left that lists all of the profiles installed, and the one on the right, which typically shows the description of the profile, as well as what settings the profile manages. You would think that “scroll area 1” would be the left column, based on how we read left to right, and therefore count as we go. Turns out, not so. If we do another
get of the scroll areas to see what kind of UI elements they contain, we can try to figure out which scroll area corresponds to which column in the preference pane. Let’s first query scroll area 1 and see what it contains:
And would you look at that, scroll area 1 is actually the right side scroll view, containing the attributes about the profile, including our “Approve…” button. So this is great news, we now know exactly where we need to click the button, with regards to what is nested in where. This leaves us with a script looking like so:
And would you believe it, this worked! Apple tried to get in our way and add a second prompt to really make sure the user wanted to give their soul over to the MDM, but using the same techniques we did above, we were able to overcome that quite quickly:
The final script ended up looking like this:
Putting It All to the Test, Remotely!
I have reworked the script a few times now to try and handle a few different scenarios and still work. Below is a screenshot of the end result of the script at this time:
So now that we’ve got ourselves a bona fide working AppleScript that will approve our UAMDM for us, does it work remotely? I opened up Screen Sharing and opened a remote session into the VM I was working on, held my breath, and clicked the Play button in Script Editor…
It worked! This may not be the cleanest, nicest, fanciest, or really even good way of doing this, but it is a way. You could theoretically take this method and remote into (remember that intern I recommended?) every non-UAMDM machine you have in your fleet, and get them “UAMDM’d”!
One of these days, I might actually try to learn the Objective-C ways of doing these kinds of things, but for now, Apple Script will have to do!