Windows Autopilot Offline
- Pascal
- Jan 25
- 5 min read
Updated: Apr 23

Introduction
Windows Autopilot offers organizations an efficient way to configure and prepare new devices for use right out of the box. While offline mode using an Autopilot JSON file may seem ideal for scenarios without internet access, it also comes with some important considerations. In this blog, we’ll dive deeper into using the Windows Autopilot Offline JSON file, its benefits, but most importantly, the pitfalls and best practices to avoid issues. This will help ensure that your deployment runs smoothly and performs optimally.
Windows Autopilot Offline Scenarios: When to Choose an Offline JSON File?
Using a Windows Autopilot Offline JSON file can be an excellent choice in specific situations. It provides a solution for challenges where the standard online methodology is not directly applicable. For example, consider the following scenarios:
No agreements with a supplier: When no agreements have been made with a hardware supplier to pre-upload Autopilot Hashes to the tenant.
Lack of permissions: For new or existing devices that are not enrolled in Microsoft Intune Autopilot, and the rollout is performed by someone without permissions to upload the hashes online to the tenant.
Accelerate the process: To get end users up and running faster by immediately rolling out with the right Autopilot profile, without waiting for a device to be fully enrolled in Microsoft Intune Autopilot.
Other specific reasons: Such as deployments in environments with limited internet access or when time-critical rollouts are required.
Why be careful using Windows Autopilot Offline JSON?
A Windows Autopilot Offline JSON file contains valuable information such as the Tenant ID and domain suffix . While information such as the Tenant ID can be obtained from other sources (for example, websites such as WhatIsMyTenantID ), using these JSON files carries specific risks.
The Risks: Unauthorized Access and Validation Challenges
Unauthorized device enrollment: If an Autopilot Offline JSON file falls into the wrong hands, there is a risk that unauthorized devices can register as legitimate corporate devices in Microsoft Intune.
Difficult to distinguish: A device registered via a stolen or abused JSON file can be difficult to distinguish from a valid device, especially without strict validation processes.
Environment security: While users are still required to sign in with valid Microsoft 365 accounts, an attacker with access to the JSON file and credentials could cause additional damage, leading to potentially dangerous “supply chain”-style attacks.
Additional Security Measures for Windows Autopilot Offline JSON
Below we discuss some methods to further secure your Autopilot Offline rollout and minimize risks.
Security via Intune settings
Block personal devices in Intune:
Configure Microsoft Intune to prevent personal devices from enrolling.
While this has no direct impact on devices using an Offline Autopilot profile (they will automatically be marked as 'Corporate'), it does prevent unauthorized personal devices from logging in outside of Autopilot scenarios.
Setting: In Intune, go to Enrollment restrictions and block personal devices.
Block Personal Owned Devices
Conditional Access policies
Conditional Access allows you to apply additional layers of security, specifically focused on device registration.
Configure register or join devices: Set Conditional Access for the User Actions option Register or join devices and always require Multi-Factor Authentication (MFA).
This forces users to go through MFA before registering a device, significantly reducing the risk of unauthorized device registrations.
Why is this important? This prevents malicious parties from easily gaining access with just the JSON file and credentials.
Blocking Offline Autopilot profiles: Because an Offline Autopilot profile generates a specific name, you can configure Conditional Access to:
Completely block the use of this profile if it is not needed.
Only accept devices using this profile from trusted locations (e.g. an office with a fixed IP address).
Download Windows Autopilot
The Microsoft website explains in detail how to download the Windows Autopilot JSON files via this link .
Please note : PowerShell 7 is required to download the JSON files correctly. You can install it using the following command with Winget:
winget install --id Microsoft.PowerShell --source winget

Next, use the PowerShell script below to install the necessary modules and download the JSON files for Autopilot using PowerShell 7:
Powershell Script |
# PowerShell Script for Downloading Windows Autopilot Profiles # Description: # This script installs the necessary modules for interacting with Windows Autopilot and Microsoft Graph, # connects to the tenant, retrieves the Autopilot profiles, and saves them as JSON files into a local directory. # The script is designed to be run in PowerShell 7. # Prerequisites: # PowerShell 7.x must be installed on your system. # Make sure that you have the required permissions in Microsoft Intune to read the Autopilot profiles. # Define constants $logFolder = "C:\Autopilot" $logFile = "$logFolder\AutopilotDownload.log" # Ensure log folder exists if (-not (Test-Path $logFolder)) { New-Item -ItemType Directory -Path $logFolder -Force } # Logging function function Write-Log { param ( [string]$message ) $timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") Add-Content -Path $logFile -Value "$timestamp - $message" } Write-Log "Script started." try { Write-Log "Setting ExecutionPolicy to RemoteSigned..." Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force # Define required modules and minimum versions $requiredModules = @( @{ Name = 'WindowsAutopilotIntune'; MinVersion = '5.4.0' }, @{ Name = 'Microsoft.Graph.Groups' }, @{ Name = 'Microsoft.Graph.Authentication' }, @{ Name = 'Microsoft.Graph.Identity.DirectoryManagement' } ) foreach ($module in $requiredModules) { $name = $module.Name $minVersion = $module.MinVersion $isInstalled = Get-Module -ListAvailable -Name $name | Where-Object { -not $minVersion -or $_.Version -ge [Version]$minVersion } if (-not $isInstalled) { Write-Log "Installing module $name..." if ($minVersion) { Install-Module -Name $name -MinimumVersion $minVersion -Force -Scope CurrentUser -ErrorAction Stop } else { Install-Module -Name $name -Force -Scope CurrentUser -ErrorAction Stop } } else { Write-Log "Module $name is already installed, skipping..." } Write-Log "Importing module $name..." Import-Module -Name $name -ErrorAction Stop } # Connect to Microsoft Graph Write-Log "Connecting to Microsoft Graph..." Connect-MgGraph -Scopes "Device.ReadWrite.All", "DeviceManagementManagedDevices.ReadWrite.All", "DeviceManagementServiceConfig.ReadWrite.All", "Domain.ReadWrite.All", "Group.ReadWrite.All", "GroupMember.ReadWrite.All", "User.Read" -NoWelcome -ErrorAction Stop # Retrieve Autopilot profiles Write-Log "Retrieving Autopilot profiles..." $autopilotProfiles = Get-AutopilotProfile -ErrorAction Stop foreach ($profile in $autopilotProfiles) { $safeDisplayName = $profile.displayName -replace '[\\\/:*?"<>|]', '_' $profileDirectory = Join-Path -Path $logFolder -ChildPath $safeDisplayName if (-not (Test-Path $profileDirectory)) { Write-Log "Creating directory $profileDirectory..." New-Item -ItemType Directory -Path $profileDirectory -Force | Out-Null } else { Write-Log "Directory $profileDirectory already exists." } Write-Log "Saving profile $safeDisplayName as JSON..." $jsonContent = $profile | ConvertTo-AutopilotConfigurationJSON $jsonPath = Join-Path -Path $profileDirectory -ChildPath "AutopilotConfigurationFile.json" $jsonContent | Set-Content -Path $jsonPath -Encoding Ascii } Write-Host "✅ Autopilot profiles downloaded successfully to $logFolder" Write-Log "Script completed successfully." } catch { Write-Log "❌ Error occurred: $_" Write-Host "❌ An error occurred. Check the log file at $logFile for details." } |

Entra Dynamic Groups
When using Windows Autopilot Offline profiles, it is good to know that, as mentioned under the Conditional Access section, a specific Enrollment Profile Name is used. This value can also be used in combination with Entra Dynamic Groups. However, it is important to know that Windows Autopilot Offline will always be named OfflineAutopilotprofile-<CorrellatorID> used. The correlator ID, which corresponds to the ZtdCorrelationId, can be found in the Autopilot JSON file and is associated with the Autopilot profile.
If you are using Entra Dynamic Groups where the query is configured on the Autopilot profile name, be aware that the OfflineAutopilotprofile-<CorrellatorID> value will also need to be included in the query.