I must admit, I felt a bit dirty creating what I will describe in this blog. Here I am, always telling people that end users should not be local administrators on their devices… and then I go making something that does just that.
I resisted shortly but then gave in. Forgive me, fellow admins, for they really had a valid use case.
Just looking for a way to create a personal, device-bound, elevated accounts for specific users (and the option to take it all back) and don’t care why or how I did it? I gotcha. Just click here to skip to that part.
In essence, there was a small subset of users who needed to be able to perform actions with elevated permissions. I did insist we, at least, followed these requirements:
- The user shouldn’t be allowed to operate in an elevatable (is that a word?) session by default, because duh.
- The user should only be allowed to elevate a session on their own, personal device.
If things go wrong, they should only be able to destroy their own device and not annoy anyone else.
- The user, and only the user, should be able to use this method of elevation.
If things go wrong, I should be able to confidently shake my finger at them. Bad user, bad!
- Finally, it should just as easy to explain to administrators deploying it, as to end users (ab)using it.
A wild goose chase all over the good old internet didn’t turn up anything that completely fit the bill.
We’ll write off the Autopilot-option immediately. We don’t want them to have an elevatable (I am declaring this a word) session by default, remember? Also, I would like to have a simple rollback-scenario, which doesn’t exist here.
Sure, there’s Azure AD’s Privileged Identity Management (PIM) and the Azure AD Joined Device Local Administrator role. Although PIM is awesome and its out-of-box features would suit my needs, the AAD-role isn’t. This grants local administrator rights to the user on all (AAD-joined) Windows 10+ devices. It’s a great fit for the organization’s administrators though.
I’m assuming shelling out for AAD P2 licenses for administrators shouldn’t be an issue.
Then there’s MSFT’s Local Administrator Password Solution (LAPS). Although the MSFT’s implementation is for on-prem ADDS only, there are some great community Azure-solutions available. LAPS, however, is aimed at securing break-glass accounts for groups of administrators.
Although there are just-in-time solutions out there that could be molded to our needs, this would also mean that we’d need to instruct end-users on how to use it.
Remember, elevated privileges do not always equal elevated skills. …did I say that out loud?
Rise to the challenge
It seems some scripting had to be done. I decided to provision a generic, local account (I called it “poweruser”) on the device. I considered generating a truly personal, named account, based on the primary user (Graph rules!). That sounded needlessly complex, so I didn’t. It might be fun to figure out later though.
The theory was great, but I had to figure out how to get the password to the user. “Change at next logon” wasn’t an option because I couldn’t find a way to change a password from inside a UAC-prompt. To change the account’s password, you need the administrator-role and to get that you need to get past the UAC-prompt. Note the loop-de-loop.
I’m sure there are ways to do it. I’m also sure some users will not read (or understand) instructions.
Finally, I decided to simply generate a long, complex, random password and put it in a file on the local disk. These were personal, encrypted devices, so I could safely assume that only the user could access it.
Rolling back the privileges was easy: remove the “poweruser”-account and the user can’t elevate anything anymore.
All this resulted in these simple scripts. It does exactly what I described above, in the most minimal way. It doesn’t use any non-default modules or an online connection.
Begs the question: how would the scripts even get there in an offline scenario?
Download the scripts from my brand new Gist repository.
Log into your MEM-portal and add the scripts to your tenant. Keep the following in mind when configuring them.
I strongly recommend assigning this script to devices, not users. You do not want to create a scenario where someone logs into a shared device, triggering this script and allowing the user full access.
These scripts don’t work on x64-hosts unless you run the script in x64 PowerShell host. That’s because they use the default Microsoft.PowerShell.LocalAccounts module (always read the purple boxes in Microsoft’s docs, kids!).
Also, remember not to run this script as the current user.
If it would work as the current user, you don’t really need these scripts, do you?
My insecurities are showing
Now, I know I could (should?) have denied local log on rights for this account. And yes, there’s such a thing as password rotation. Let’s not forget about that little file we put on disk, as well.
Let’s just conclude that this solution isn’t fool-proof (yet).
But wait… there’s more!
You can even wrap these as a .INTUNEWIN-package and use the install and uninstall commands to provision and deprovision the account. Let me know if you’d like some instructions for that.