Azure Active Directory

Automatically join devices to Azure AD

It started off as a simple task: Create a provisioning package that can be used to join a device to Azure AD. But when it comes to using the Windows Configuration Designer, nothing ever seems to be easy. First, the store version (the one that is supposed to be kept most up to date) wouldn’t work after installing it:

Then, the Windows 11 ADK version wouldn’t run properly on Windows Server 2019, failing to retrieve a bulk enrollment token:

Finally, it worked using the ADK for Windows 11 installed on Windows 11, letting me create a provisioning package that contains the bulk enrollment token. But you can only do that when going through the full “Provision desktop devices” wizard:

The resulting PPKG then contains other settings, which isn’t exactly what I wanted. I just wanted a PPKG that could be used to join a device to Azure AD (at least for 180 days, until that bulk enrollment token expired). You can see the other settings in the customizations.xml file saved by Windows Configuration Designer:

I purposely blocked out the BPRT value because that’s the bulk enrollment token itself. If you cared to type in that entire value, you could use it to join devices to my Azure AD tenant, and I don’t want that.

Also note the GUID in the <ID> element toward the top of that file. You’ll find that there was a user account created in Azure AD with that in the name:

You really can’t tell much about it from that account, but if you ever wondered where these accounts come from, each new PPKG will create a new account.

So if you wanted a PPKG that did only an Azure AD join, you can click the “Switch to advanced editor” link at the bottom left of the “Provision desktop computer” wizard, then remove all but the “Accounts / Azure” settings, ending up with this:

You can then export (generate/create) a provisioning package with only that setting, then inject it offline into a computer using the Add/Install-ProvisioningPackage cmdlet (challenging to do from Windows PE as this is another module that isn’t available there) or DISM /Add-ProvisioningPackage. It will be picked up automatically during the Windows OOBE process, completing the join.

But wait, there’s more

While I was researching this whole setup, I came across a fascinating blog post by Dr. Nestori Syynimaa (@DrAzureAD) that goes into great detail about the whole bulk provisioning / BPRT process. You can read the full detail here:

BPRT unleashed: Joining multiple devices to Azure AD and Intune

It’s an enlightening, and in some ways frightening, discussion. Included in that conversation is some details about the AADInternals PowerShell module that he has built, which you can install from the PowerShell Gallery using “install-module AADInternals”. It has 225 cmdlets in it at the moment, so we certainly won’t go through all of them. In fact, we’ll focus on a very small number related to this bulk provisioning process.

First, there is a cmdlet that can completely automate the process of generating a BPRT, which is ready to be copied and pasted into the Windows Configuration Designer advanced view directly, saving yourself the trouble of using/troubleshooting Windows Configuration Designer.

The “refresh_token” value in the generated JSON file will look very similar to what WCD generates, and no surprise you’ll also see a new account created. The New-AADIntBulkPRTToken cmdlet defaults to 30 days, but you can specify an expiration date up to 180 days in the future using the -Expires parameter. As a nice touch, it uses the “name” parameter that you specified as the name of the account, with the UPN (the package_* value below) being in line with what you would see with WCD:

Given the BPRT token generated, there are then two other cmdlets that could be used to actually automate the Azure AD join process:

Get-AADIntAccessTokenForAADJoin -BPRT $BPRT -SaveToCache
Join-AADIntDeviceToAzureAD -DeviceName "My computer"

Cool stuff. With something like that, you wouldn’t need the PPKG file at all. Instead, you could just provide a (secure) method of getting the BPRT value to the machine, then use that to complete the Azure AD join process. Very nice.