Windows Autopilot device preparation represents Microsoft’s next-generation approach to device provisioning, offering improved reliability and real-time reporting. However, the current implementation lacks four key features that many organizations depend on. This post introduces a device preparation script I’ve developed to bridge these gaps until Microsoft expands the native capabilities.
Quick link
If you’re already familiar with the concepts and want to get started, jump to the script on GitHub or continue reading for full details and configuration guidance.The gaps in Windows Autopilot device preparation
While Windows Autopilot device preparation brings significant improvements in deployment reliability and troubleshooting, it currently lacks four key features available in traditional Windows Autopilot:
| Gap | Impact |
|---|---|
| No partner device registration | Requires a different approach to device identity and enrollment restrictions. |
| No native device naming | Devices retain default names unless renamed through other means. |
| Limited OOBE customization | Certain prompts cannot be suppressed through the device preparation policy alone. |
| BitLocker policy timing | Microsoft Intune policies arrive too late to control initial encryption, potentially resulting in weaker algorithms than intended. |
The device preparation script addresses these limitations while also providing a location marker feature for multi-region deployments. This is common practice in the Nordics and other regions where organizations deploy a US English OS image but need to configure local keyboard layouts, timezones, and regional formatting for their users.
Prerequisites
Before deploying this script, ensure your environment meets the following requirements:
| Requirement | Details |
|---|---|
| Operating System | Windows 10 (1903+) or Windows 11 |
| PowerShell | Version 5.1 or later (64-bit recommended) |
| Microsoft Intune | Licensed and configured for device management |
| Windows Autopilot device preparation | Profile configured and assigned |
| Enrollment Time Grouping | Dynamic device group for script assignment |
Note
The script runs in the SYSTEM context during enrollment and requires administrator privileges.Script features
The script provides four independently configurable capabilities:
| Feature | Purpose |
|---|---|
| Device renaming | Apply consistent naming conventions using serial numbers, random digits, or SHA256 hashing |
| OOBE registry settings | Suppress prompts for a cleaner enrollment experience |
| BitLocker validation | Verify encryption status and method compliance |
| Location marker | Set regional configuration flags for downstream scripts |
Device renaming
Applying consistent device names is one of the most common enrollment requirements. The script supports three naming methods:
| Method | Description | Example |
|---|---|---|
| SHA256 Hash (default) | Creates a deterministic hash from the serial number | WSR578A7D663F45 |
| %SERIAL% | Uses the device’s BIOS serial number | WIN-ABC123DEF-01 |
| %RAND:x% | Generates x random digits | PC12345678 |
The SHA256 hash method generates consistent, unique names - the same device will always receive the same name, even if re-enrolled.
Naming logic:
- NetBIOS compliance: Names are truncated to 15 characters; invalid characters and leading/trailing hyphens are removed automatically
- Prefix matching: If the current name already starts with the specified prefix, the script skips renaming to avoid unnecessary reboots
- Fallback handling: When the BIOS serial number is empty (common in virtual environments), a GUID is used instead
Note
When using%SERIAL%, ensure your devices have unique serial numbers. Some hardware vendors use duplicate or generic serial numbers, which could result in naming conflicts.OOBE registry settings
The script configures registry settings to streamline the out-of-box experience:
| Setting | Purpose |
|---|---|
DisablePrivacyExperience | Skips privacy settings prompts |
DisableVoice | Disables Cortana voice features |
HideEULAPage | Hides the EULA acceptance page |
PrivacyConsentStatus | Sets privacy consent status |
ProtectYourPC | Configures Windows Defender settings |
These settings are written to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE]
"DisablePrivacyExperience"=dword:00000001
"DisableVoice"=dword:00000001
"HideEULAPage"=dword:00000001
"PrivacyConsentStatus"=dword:00000001
"ProtectYourPC"=dword:00000003OOBE Registry Export
BitLocker validation (Preview)
This feature addresses the timing challenge where Windows enables BitLocker with default settings before your Microsoft Intune policy arrives. The script logs the current encryption state including protection status, encryption method (e.g., XtsAes256), key protectors, and volume status.
Note
Preview Feature: A future version will include an option to re-encrypt the disk if the encryption method doesn’t match your requirements. This feature can be disabled if your organization is satisfied with the default BitLocker settings.Location marker
This convenience feature creates a registry-based flag for multi-region deployments. When deploying en-US images to locations like Denmark, downstream scripts can read this marker to apply appropriate regional settings (timezone, keyboard layout, date/number formatting).
This pairs well with solutions like my Windows gecko project for automated regional configuration.
Script parameters
The script accepts several parameters to customize its behavior:
| Parameter | Default | Description |
|---|---|---|
-Features | 15 | Bitmask to enable/disable features (see Feature Flags below) |
-Prefix | WSR5 | Custom prefix for computer name (max 5 characters) |
-Suffix | (empty) | Custom suffix for computer name (max 5 characters) |
-NamingMethod | (empty) | Naming method: %SERIAL% or %RAND:x% |
-LocationMarker | DEN | Registry marker for location/region settings |
-LocationMarkerPath | (default OOBE path) | Registry path for location marker |
-fLogContentFile | DevicePreparation.log | Custom log file path |
-WhatIf | (switch) | Preview changes without executing |
-Verbose | (switch) | Show detailed output during execution |
Enabling and disabling features
The -Features parameter uses a bitmask to control which features are enabled. This provides granular control over script behavior without modifying the script itself:
| Bit | Value | Feature |
|---|---|---|
| 1 | 0001 | Device Renaming |
| 2 | 0010 | OOBE Registry Settings |
| 4 | 0100 | BitLocker Validation |
| 8 | 1000 | Location Marker |
Common combinations:
| Value | Description |
|---|---|
| 0 | All features disabled |
| 1 | Device Renaming only |
| 3 | Renaming + OOBE |
| 4 | BitLocker Validation only |
| 5 | Renaming + BitLocker |
| 7 | Renaming + OOBE + BitLocker (no location marker) |
| 15 | All features enabled (default) |
Usage examples
Show examplesDefault SHA256 naming
.\device-preparation.ps1Generates a name like WSR578A7D663F45.
Serial number based naming
.\device-preparation.ps1 -Prefix "WIN-" -Suffix "-01" -NamingMethod "%SERIAL%"Generates a name like WIN-ABC123DEF-01.
Random digit naming
.\device-preparation.ps1 -Prefix "PC" -NamingMethod "%RAND:8%"Generates a name like PC12345678.
Selective features
.\device-preparation.ps1 -Features 7 -Prefix "PC" -NamingMethod "%SERIAL%"Enables renaming (1) + OOBE (2) + BitLocker (4) = 7, disabling the location marker.
Custom location marker
.\device-preparation.ps1 -LocationMarker "USA" -LocationMarkerPath "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Contoso\Location"Deploying with Microsoft Intune
Deploying this script involves three steps: customizing the default values in the script, uploading it to Microsoft Intune, and adding it to your Windows Autopilot device preparation policy.
Customizing default values
Microsoft Intune does not support passing parameters to PowerShell scripts, so you must modify the default parameter values directly in the script’s param() block before uploading. If your organization requires signed scripts, sign the script after making your modifications.
Locate the param() block and modify the values after the = sign:
param (
[int]$Features = 15, # Change to 7 to disable location marker
[string]$Prefix = "WSR5", # Your naming prefix (max 5 chars)
[string]$NamingMethod = "", # Use "%SERIAL%" or "%RAND:x%"
[string]$LocationMarker = "DEN" # Your region code
)Parameter block excerpt
Uploading the script to Microsoft Intune
- Navigate to Microsoft Intune admin center > Devices > Scripts and remediations > Platform scripts
- Click + Add and select Windows 10 and later
- Enter the script properties and upload the script file
- Configure the script settings as shown below
- Assign to your target group (see assignment options below)
Script settings:
| Setting | Value |
|---|---|
| Name | Windows Autopilot - Device Preparation Script |
| Run this script using the logged-on credentials | No |
| Enforce script signature check | No |
| Run script in 64-bit PowerShell host | Yes |
Note
Why disable signature check? During Windows Autopilot device preparation, code signing certificates may not yet be deployed to the device when the script executes. Since there’s no way to control the deployment order, enabling signature enforcement will likely cause the script to fail.Assignment options:
- Enrollment time grouping (Preferred): Assign to the same group used in your device preparation profile for immediate delivery during enrollment.
Adding the script to the Windows Autopilot device preparation policy
The script must be added to your device preparation policy to execute during enrollment:
- Navigate to Microsoft Intune admin center > Devices > Enrollment > Windows Autopilot device preparation
- Select Device preparation policies and choose your policy
- Under Settings > Scripts, click
+Addand select the uploaded script - Save and apply
Note
Upload the script as a platform script first. The device preparation policy references existing scripts rather than allowing direct upload.Testing and troubleshooting
Before deploying to production, thoroughly test the script in a non-production environment. My preferred approach is using Windows Sandbox - it provides a clean, isolated Windows environment that resets on every launch, making it ideal for testing scripts without affecting your host system.
To replicate how Microsoft Intune invokes scripts, run the script from an elevated command prompt using the same parameters:
powershell.exe -ExecutionPolicy Bypass -NoProfile -File ".\device-preparation.ps1"To preview changes without executing, add -WhatIf after the script path:
powershell.exe -ExecutionPolicy Bypass -NoProfile -File ".\device-preparation.ps1" -WhatIf -VerboseAfter execution, verify the results:
# View recent log entries
Get-Content "$env:ProgramData\Microsoft\IntuneManagementExtension\Logs\DevicePreparation.log" -Tail 50
# Verify pending reboot flag after rename
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" -Name "RebootRequired" -ErrorAction SilentlyContinueNote
The script logs the PowerShell architecture upon execution (Running 64 bit PowerShell: True/False). Microsoft Intune runs scripts in 32-bit PowerShell unless you enable “Run script in 64-bit PowerShell host.”
On a 64-bit Windows 11 system, you have two options for running powershell.exe:
- 64-bit:
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe - 32-bit:
%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
When testing, use the path that matches your Microsoft Intune script configuration to ensure consistent behavior.
Reading the logs
The script writes CMTrace-compatible logs to %ProgramData%\Microsoft\IntuneManagementExtension\Logs\DevicePreparation.log with entry types for informational messages (1), warnings (2), and errors (3). A summary at the end shows the status of each operation.
Common issues
Show troubleshooting| Issue | Cause | Solution |
|---|---|---|
| Access Denied | Not running as Administrator | Run as Administrator or deploy via Microsoft Intune |
| Name not changed | Device already has correct prefix | Expected behavior |
| BitLocker validation fails | Module not available | Ensure Windows 11 with BitLocker capability |
| Serial number fallback used | BIOS serial empty | Script uses GUID fallback; verify BIOS if consistent naming required |
Get the script
The device preparation script is available on GitHub as part of the Windows Kaleidoscope repository:
- Device Preparation Script (direct link)
- README and Documentation (direct link)
The script has been verified with PSScriptAnalyzer and tested in PowerShell Constrained Language mode for compatibility with enterprise security configurations.
Summary
This device preparation script bridges the gaps in Windows Autopilot device preparation by providing device naming, OOBE streamlining, BitLocker validation, and location markers in a single, well-logged solution. Test thoroughly with the -WhatIf parameter before production deployment.
Happy provisioning!
–Jesper
Header image attribution: Image created with help from Microsoft Copilot

