Deploying an Azure AD Joined machine to existing hardware with MDT and Windows Autopilot

We’ve recently started a refresh of our staff laptops to provide a better remote working experience, as well as baselining a common standard to their configuration (Windows 10, Office 365, BitLocker etc.) At this point we were also faced with a decision on how best to deploy this:

  • domained with DirectAccess
  • domained with VPN
  • Azure AD Joined

https://techcommunity.microsoft.com/t5/Azure-Active-Directory-Identity/Azure-AD-Join-on-Windows-10-devices/ba-p/244005

Given that we’re heavy users of Office 365 I decided to give Azure AD Join a try and go for a cloud-native solution, rather than extending the reach of internal services outwards. One flaw in the plan is that I’m still trying to make a case for adding InTune to our EES agreement so have had to get a bit creative in terms of deployment rather than using MDM to do the heavy lifting.

Windows Autopilot

Whilst at Future Decoded last year I attended a demo of Windows Autopilot, which sounded a very easy way to assign Windows 10 devices and get them up and running quickly.

Ref: https://docs.microsoft.com/en-us/windows/deployment/windows-autopilot/windows-10-autopilot

However looking a bit more closely it wouldn’t do here as without InTune we can’t install any additional software and on top of that the devices we’re using need upgrading to Windows 10, rather than being nice fresh kit with the latest OS already installed. That said it still has a part to play in this deployment, more on that later…

MDT time

So with that initial thought discounted we turn back to trusty MDT. Having already gained its Windows 10 deployment stripes over summer I wondered if there’s a way to make a Task Sequence that will give a similar Autopilot experience but with a bit more flexibility around apps and re-using existing kit.

A fresh Task Sequence was created to handle the usual driver packs, generic Applications and machine naming. Now time for the fun part of integrating Office 365 ProPlus and Azure AD Join!

Deploying Office 365 ProPlus

Before we get to the Azure AD Join we need to deploy some basic software to the machine such as Chrome, VLC and, of course Office Apps. Internally we use Office 2016 ProPlus but for these Azure AD Joined devices Office 365 ProPlus is a better bet in order to ensure smooth SSO from the Azure AD account.

Deployment of Office 365 ProPlus looks a lot simpler now than it was previously thanks to Microsoft creating a handy web app for generating the Configuration XML file you need for deployment.

First download the Office Deployment Tool
https://www.microsoft.com/en-us/download/details.aspx?id=49117

Then create the XML file using the Office Customization Tool, configuring your desired options
https://config.office.com/

Place all the files in a folder on your MDT server, along with a new file called install.cmd using the code from Rens Hollanders’ instructions (you don’t need to use his config.xml though as the one from the Customization Tool does the same job and is a bit more granular in terms of installation options)
http://renshollanders.nl/2015/08/office-365-updated-deployment-guide/

Finally create an MDT Application (with source files pointing to the folder above) that runs install.cmd

In your Task Sequence add this and any further Applications you wish to install in the usual place under State Restore.

If using a Volume Licensing versions of Windows I also create an Application to install the MAK product key at this point.

Preparing for Azure AD Join

Now at this point you have a pretty bog standard Task Sequence and might be wondering how we get back to the first-run wizard. The reason for this is because it’s where we get our only chance to properly join to Azure AD if we want to log into the machine using an Office 365 account, otherwise if you join later on you end up with a mix of a local account connected to Office 365, which we don’t want.

The process of getting back to that OOBE wizard is simpler than you might think and just requires one command at the end of your Task Sequence

cmd /c c:\windows\system32\sysprep\sysprep.exe /oobe /quiet /quit

This does assume a couple of things though:

  • your Deployment Share is configured with SkipDomainMembership=YES and JoinWorkgroup=WORKGROUP
    these are already set on my Deployment Share as I prefer to Join Domain manually via a TS step; that way I can control exactly when domain policies come down to the machine during deployment, or in this case not join a Domain at all
  • your FinishAction in MDT is set to SHUTDOWN
    you can either set this at Deployment Share level or override it (as I do) for a single TS by adding this step in early on…

With this configured the machine will automatically run sysprep and return to OOBE state, ready for the user (or admin) to join the machine to Azure AD via the first-run wizard.

Provisioning Packages and customisation

Now what we have so far is good, but we can go a bit further and add some InTune-esque customisation of the deployed system via the MDM method of Provisioning Packages. This will allow you to prepare an identical base set of machines that you can quickly customise by plugging a USB stick into them at the OOBE screen for any additional changes. It’s also a good insight into how the policies, or should I say CSPs (Configuration Service Providers) work.

To create a Provisioning Package you need to open the Windows ICD, which in turn is part of the ADK (don’t you just love acronyms!)
https://docs.microsoft.com/en-us/windows-hardware/get-started/adk-install

Windows Configuration Designer provisioning settings (reference)
https://docs.microsoft.com/en-us/windows/configuration/wcd/wcd

I initially started with this side of things via the Set up School PCs app but ended up opening up the package it built manually to take a look exactly what it did. Not all the settings were required so I decided to build a new one from scratch. Again it gives a good idea what’s going on “under the hood” though 🙂

Ref: https://docs.microsoft.com/en-us/education/windows/use-set-up-school-pcs-app

Applying the package file from a USB when OOBE appears works fine but I couldn’t resist the automated approach outlined in the post below to do it via MDT. If you’re using one of the latest builds of Windows 10 note the comment at the bottom that you don’t appear to need to sign the packages for 1803 onwards.

Ref: http://chrisreinking.com/apply-a-provisioning-package-with-mdt/

However I found that in MDT running the AddProvisioningPackage Powershell command with a UNC path didn’t work, giving me “path not supported errors”.

There’s not much documentation online about using this particular cmdlet (most people seem to be using DISM instead) but I found that if you map a drive letter to the Application path it works fine. My code for this is below (also includes the nifty transcript logging wrapper from deploymentresearch.com so you get full visibility of the process in your MDT Logs folder)

# Determine where to do the logging 
# https://deploymentresearch.com/Research/Post/318/Using-PowerShell-scripts-with-MDT-2013

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment 
$logPath = $tsenv.Value("LogPath") 
$logFile = "$logPath\$($myInvocation.MyCommand).log"
$DeployRoot = $tsenv.Value("DeployRoot")

# Start the logging 
Start-Transcript $logFile
Write-Output "Logging to $logFile"

net use P: "$DeployRoot\Applications\Provisioning Package - Your Name"

Write-Output "Adding TrustedProvisioners Registry Key"
Start-Process -filepath "C:\windows\regedit.exe" -argumentlist "/s P:\TrustedProvisioners.reg"

Write-Output "Adding Provisioning Package from folder: $DeployRoot\Applications\Provisioning Package - Your Name mapped to P:"
Add-ProvisioningPackage -Path "P:\Provisioning Package - Your Name.ppkg" -ForceInstall

# Stop logging
Stop-Transcript

Note: you need to copy the entire contents of the folder where the signed exported Provisioning Package is created for the silent install to work correctly. Thanks to Dhanraj B for pointing this out in the Technet forums otherwise I may well have given up on it…

https://social.technet.microsoft.com/Forums/en-US/a01ad169-7aaa-42be-937a-e82169f88d4f/provisioning-and-code-signing?forum=win10itprosetup

If you followed the Chris Reinking instructions to the letter you should see a successful import in your logs, which looks something like this…

IsInstalled : False
PackageID : d69c654b-3546-4b77-abcd-93f09285c123
PackageName : Provisioning Package - Your Name
PackagePath : P:\Provisioning Package - Your Name.ppkg
Description :
Rank : 1
Altitude : 5001
Version : 1.17
OwnerType : ITAdmin
Notes :
LastInstallTime : 22/11/2018 15:51:52
Result : 0__Personalization_DeployDesktopImage.provxml
Category:Content
LastResult:Success
Message:Provisioning succeeded
NumberOfFailures:0 (0x0)

1__Personalization_DeployLockScreenImage.provxml
Category:Content
LastResult:Success
Message:Provisioning succeeded
NumberOfFailures:0 (0x0)

2__Personalization_DesktopImageUrl.provxml
Category:UxLockdown
LastResult:Success
Message:Provisioning succeeded
NumberOfFailures:0 (0x0)

3__Personalization_LockScreenImageUrl.provxml
Category:UxLockdown
LastResult:Success
Message:Provisioning succeeded
NumberOfFailures:0 (0x0)

Start Menu layout

One part of ICD that I found didn’t seem to work at all was Start Menu layout deployment. In Active Directory land it’s a simple GPO but despite following the MS documentation to the letter it never applied despite the Provisioning Package working otherwise.

Instead of using the ICD method I took an easy way out and created another Application in MDT, which copies the desired LayoutModification.xml to the Default User AppData folder:

cscript.exe CopyFiles.vbs C:\Users\Default\AppData\Local\Microsoft\Windows\Shell

Get CopyFiles.vbs from here https://mdtguy.wordpress.com/2014/07/30/how-to-copy-folders-in-mdt-like-a-boss-the-easy-way/

The final piece of the puzzle – automatic Azure AD Join

At this point we’re very close to having a hands-off deployment but we need a method to join the machine to Azure AD itself. Of course you can do this manually if you wish; the machine at this point can be handed to a user to complete the OOBE wizard and they’ll be able to log in with their Office 365 credentials.

Be mindful that the user who performs the Azure AD Join becomes local admin on that device. If you don’t want this you’ll need to use the method below to get a bit more control.

Initially I thought the Azure AD Join would be simple as there’s an option sitting right there in the ICD wizard
https://docs.microsoft.com/en-us/intune/windows-bulk-enroll

However the URL gives away what seems to be the crux of the issue in that you need an InTune license to get the Bulk Token 😦 When I try it fails miserably with the error “Bulk token retrieval failed”

Again documentation on this isn’t exactly forthcoming but there’s one particular Technet post by a Microsoft staffer that suggests it is limited by licensing.

“By the way, the error message “Bulk token retrieval failed” might be caused if there are no more licenses available for Azure AD Premium and Microsoft Intune”

Interestingly the Set up School PCs app is able to join to Azure AD in bulk, which suggests Microsoft can enable this functionality to non-InTune users when they feel like it but seemingly not for ICD use.

Windows Autopilot returns

Remember I said I’d return to Autopilot… well, “later” in the post has now arrived and it’s time to make use of it.
https://docs.microsoft.com/en-us/windows/deployment/windows-autopilot/windows-autopilot

Without InTune we can still configure Autopilot using the Microsoft Store for Business (or Microsoft Store for Education if you’re an edu user). You’ll need to set it up if you haven’t already…
https://docs.microsoft.com/en-gb/microsoft-store/windows-store-for-business-overview

and then access it via one of the links below

https://businessstore.microsoft.com/en-gb/store
https://educationstore.microsoft.com/en-gb/store

Now follow the steps below:

At this point once your freshly imaged device hits the OOBE screen it’ll connect to Autopilot, apply the profile settings and skip all screens apart from bare minimum input required from the user for keyboard layout and login info. Once they log in Office 365 will already be installed, along with any other apps you provisioned via the Task Sequence and the device will be branded up as per your organisation’s design (provided you’ve configured this in the Azure Portal)

Note: during my testing Autopilot didn’t seem to work so well with a Hyper-V VM. The gather script managed to obtain 3 different sets of hardware hashes for the same VM on 3 separate image attempts, whereas on physical laptops the data was gathered consistently. One to keep an eye on but it was a case of third time lucky in this case, which allowed for some nice screenshots of the end product…

Multiple user access

An interesting observation during this process was the mysterious appearance of the “Other user” button, which I’d been chasing on Azure AD Joined machines for a while before this but without much joy. As you can imagine I was quite pleased when it popped up after running the first couple of test Task Sequences.

I’m not sure if it’s a recent Windows Update, enabling some of the “Shared PC” settings in ICD or (more likely) the additional of Azure AD Premium P1 licenses on our Office 365 tenant but it makes an Azure AD Joined machine much more usable for our use case, where machines need to be loaned out to multiple members of staff.

If anyone can clear up this quandary it’d be great to hear from you!


Note the use of the branded login screen to add some additional instructions for the user to help them log in for the first time 🙂

At this point once your freshly imaged device hits the OOBE screen it’ll connect to Autopilot, apply the profile settings and skip all screens apart from bare minimum input required from the user for keyboard layout and login info.

Once they log in Office 365 will already be installed and visible on the (customised) Start Menu, along with any other apps you provisioned via the Task Sequence and the device will be branded up as per your organisation’s design (provided you’ve configured this in the Azure Portal)

And here’s one we made earlier…

Not bad eh 😉

Troubleshooting

If Autopilot doesn’t work check network connectivity first, particularly if using a proxy server internally

https://docs.microsoft.com/en-us/windows/deployment/windows-autopilot/windows-autopilot-requirements-network
https://docs.microsoft.com/en-us/windows/deployment/windows-autopilot/troubleshooting

 

image credit: blickpixel – https://pixabay.com/en/gift-made-surprise-loop-christmas-548290/

4 Responses to Deploying an Azure AD Joined machine to existing hardware with MDT and Windows Autopilot

  1. Patrick says:

    Ummm…….wow…..and I mean that in a very good way!

    There is so much here to wrap your head around…..ADK, ICD, Autopilot, AzureAD, MDT, O365…

    MDT user here, but I’m currently looking into Autopilot and InTune. Thanks for sharing.

    So much to learn!

    • gshaw0 says:

      Hi Patrick, it’s certainly a case of “learn something new every day” when moving to modern management (as MS like to call it) but the best way is to dive right in and have a play. If you can get the InTune licenses then that’ll make the process a lot easier. Enjoy!

  2. Jurian says:

    Hi Gerrard,
    Very nice article!
    In your article you show a screenshot of a WIndows 10 loginscreen with below text.
    “Note the use of the branded login screen to add some additional instructions for the user to help them log in for the first time”
    How did you do that branding? I really like the blue banner at the top!
    Thanks,
    Jurian

    • gshaw0 says:

      Hi Jurian sorry for late reply, just got round to looking through the comments list. The branding was a Provisioning Package which copies the login screen image and enables the custom background.

      The image itself is a fill layer in Photoshop,opacity altered to give the banner effect with text added on top. Can upload a template Photoshop .PSD to OneDrive if you still need it?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: