Skip to content

Custom Autopilot Experience

Introduction

I recently published my blog around customizing the Dropship provisioning experience, where my app replaces explorer.exe to secure the device and give the end user / staging admin an idea of what’s going on on the device.

On the Omnissa Community portal, someone asked if there was something similar available on the market for Autopilot. This triggered me to test if and how my app would work when using Autopilot instead of Dropship provisioning.

Let’s start with showing the entire process:

0’0s installing app in audit mode using script
4’10s sysprep + reboot
5’15s progressing through OOBE screens
7’35s Windows Hello setup
8’08 app launches, device is locked for end user
10’15s workflows starts
21’40s workflow complete, device reboots
22’20s end user logon


If you’re interested, grab a copy of the app here and try it out yourself!

How did I make it work for Autopilot?

audit mode

First of all, my app still needs to be installed before handing over the device to the end user. Either you install it manually using audit mode (that’s how I did it in the video), or you use some other means (ask your OEM, custom image,…). If that’s a showstopper for you, you can stop reading here and look for any alternatives.

psexec

as we aren’t using dropship provisioning in this case, I also didn’t use a PPKG. You still could use a PPKG and just install the app using the Workspace ONE Provisioning tool, but I wanted to try without this time.

But I noticed that the app failed to install outside of the Provisioning tool. Apparently, the custom shell launcher feature needs to be activated using system context. Hence I used psexec to launch a PowerShell session in system context and install the app from there. The script I provide below installs (and later removes) the psexec module for you.

local admin

For all functions of my app to work properly, the user logged on to the system needs to be a local administrator. This isn’t a problem in dropship provisioning flows where a staging account is used, but in Autopilot you need to configure your profile accordingly.

At the end of the Freestyle workflow I publish to the device, I remove the admin privileges again using a simple script.

User Account Control (UAC)

When my app tries to remove the custom shell feature when the Freestyle Orchestrator workflow is completed, a UAC popup was triggered on the device asking for permission to execute stuff that requires elevation.

I solved that by disabling the UAC setting “ConsentPromptBehaviorAdmin”. You can easily revert that change using a script or a baseline later.

app config

To display the end user’s name on screen of my app, open the WorkspaceOneOnboardingApp.exe.config file (located in the SupportFiles folder) and set the “userDrivenEnrollment” key to true:

Scripts

to install the app, I used this script:

#install psexec
winget install "Sysinternals Suite" --accept-source-agreements --accept-package-agreements

#temporarily disable UAC, can be reactivated later by for example using a baseline
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 0

#launch powershell using system context and deploy app
#don't forget to modify the path to the deploy-application.exe!
PsExec -i -accepteula -s powershell.exe -executionpolicy bypass -file "C:\Users\Administrator\Downloads\Workspace ONE Onboarding App\Deploy-Application.ps1"

#remove psexec
winget remove "Sysinternals Suite"

#trigger sysprep
Get-process -name sysprep -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Process -FilePath "C:\Windows\System32\Sysprep\sysprep.exe" -ArgumentList "/oobe /reboot" -Wait -NoNewWindow

to remove the admin privileges set by the Autopilot profile, use the following script at the end of your Freestyle Orchestrator workflow:

# Get the currently logged-on user
$LoggedOnUser = (Get-WmiObject -Query "SELECT * FROM Win32_ComputerSystem").UserName

if ($LoggedOnUser -and $LoggedOnUser -like "*\*") {
    # Check if the user exists in the local Administrators group
    $AdminMembers = Get-LocalGroupMember -Group "Administrators"
    $UserToRemove = $AdminMembers | Where-Object { $_.Name -eq $LoggedOnUser }

    if ($UserToRemove) {
    # Remove the user from the Administrators group
    Remove-LocalGroupMember -Group "Administrators" -Member $LoggedOnUser -ErrorAction Stop
} 

Conclusion

It does work, but I don’t see a way to get this working without preinstalling my app.

Leave a Reply

Your email address will not be published. Required fields are marked *