OOBE sysprep in Azure VM
This script do the following:
- Install and Configure VNC Server
- Open 5900 port on local firewall
- Remove user appx packages (required to successful run the sysprep)
- Do a sysprep /generalize /oobe /reboot
All is unattended. After it reboot you can connect using VNC-Viewer-7.13.1-Windows-64bit to this VM and perform OOBE (Out-of-Box Experience). In this way you can utilize Intune Autopilot.
Before proceed make sure the machine is has all updates and no pending restart – just restart VM.
# TightVNC Unattended Installation and Configuration Script
# Requires Administrator privileges#Requires -RunAsAdministrator
# Configuration Variables
$Password = “Pa##word”
$TightVNCVersion = “2.8.84”
$InstallerURL = “https://www.tightvnc.com/download/$TightVNCVersion/tightvnc-$TightVNCVersion-gpl-setup-64bit.msi”
$InstallerPath = “$env:TEMP\tightvnc-setup.msi”
$Port = 5900Write-Host “Starting TightVNC Installation and Configuration…” -ForegroundColor Green
# Disable BitLocker on C: drive
Write-Host “`n=== Checking BitLocker Status ===” -ForegroundColor Yellow
try {
$BitLockerVolume = Get-BitLockerVolume -MountPoint “C:” -ErrorAction Stopif ($BitLockerVolume.ProtectionStatus -eq “On”) {
Write-Host “BitLocker is enabled on C: drive. Disabling…” -ForegroundColor Yellow# Disable BitLocker
Disable-BitLocker -MountPoint “C:” -ErrorAction Stop
Write-Host “BitLocker disable initiated.” -ForegroundColor Green# Wait for decryption to complete
Write-Host “Waiting for decryption to complete (this may take several minutes)…” -ForegroundColor Yellow$DecryptionComplete = $false
$MaxWaitTime = 3600 # 1 hour maximum wait
$ElapsedTime = 0
$CheckInterval = 10 # Check every 10 secondswhile (-not $DecryptionComplete -and $ElapsedTime -lt $MaxWaitTime) {
Start-Sleep -Seconds $CheckInterval
$ElapsedTime += $CheckInterval$BitLockerStatus = Get-BitLockerVolume -MountPoint “C:” -ErrorAction SilentlyContinue
$EncryptionPercentage = $BitLockerStatus.EncryptionPercentageWrite-Host “Decryption progress: $($EncryptionPercentage)% encrypted remaining…” -ForegroundColor Cyan
if ($BitLockerStatus.VolumeStatus -eq “FullyDecrypted”) {
$DecryptionComplete = $true
Write-Host “BitLocker decryption completed successfully!” -ForegroundColor Green
}
}if (-not $DecryptionComplete) {
Write-Host “Warning: Decryption is taking longer than expected.” -ForegroundColor Yellow
Write-Host “Current encryption status: $($EncryptionPercentage)% encrypted” -ForegroundColor Yellow
Write-Host “Continuing with installation, but Sysprep may have issues if encryption is not complete.” -ForegroundColor Yellow
}
}
elseif ($BitLockerVolume.ProtectionStatus -eq “Off”) {
Write-Host “BitLocker is already disabled on C: drive.” -ForegroundColor Green
}
else {
Write-Host “BitLocker status: $($BitLockerVolume.ProtectionStatus)” -ForegroundColor Cyan
}
}
catch {
Write-Host “Could not check BitLocker status: $_” -ForegroundColor Yellow
Write-Host “Continuing with installation…” -ForegroundColor Yellow
}# Download TightVNC Installer
Write-Host “Downloading TightVNC installer…” -ForegroundColor Yellow
try {
Invoke-WebRequest -Uri $InstallerURL -OutFile $InstallerPath -UseBasicParsing
Write-Host “Download completed successfully.” -ForegroundColor Green
}
catch {
Write-Host “Error downloading TightVNC: $_” -ForegroundColor Red
exit 1
}# Install TightVNC silently
Write-Host “Installing TightVNC…” -ForegroundColor Yellow
try {
$InstallArgs = @(
“/i”
“`”$InstallerPath`””
“/quiet”
“/norestart”
“ADDLOCAL=Server”
“SERVER_REGISTER_AS_SERVICE=1”
“SERVER_ADD_FIREWALL_EXCEPTION=1”
“SET_USEVNCAUTHENTICATION=1”
“VALUE_OF_USEVNCAUTHENTICATION=1”
“SET_PASSWORD=1”
“VALUE_OF_PASSWORD=$Password”
“SET_VIEWONLYPASSWORD=1”
“VALUE_OF_VIEWONLYPASSWORD=$Password”
)Start-Process “msiexec.exe” -ArgumentList $InstallArgs -Wait -NoNewWindow
Write-Host “TightVNC installed successfully.” -ForegroundColor Green
}
catch {
Write-Host “Error installing TightVNC: $_” -ForegroundColor Red
exit 1
}# Wait for installation to complete
Start-Sleep -Seconds 5# Configure TightVNC Registry Settings
Write-Host “Configuring TightVNC settings…” -ForegroundColor Yellow
$RegistryPath = “HKLM:\SOFTWARE\TightVNC\Server”try {
# Set port
Set-ItemProperty -Path $RegistryPath -Name “RfbPort” -Value $Port -Type DWord -Force# Set to run as system service (autostart)
Set-ItemProperty -Path $RegistryPath -Name “RunControlInterface” -Value 1 -Type DWord -Force# Enable authentication
Set-ItemProperty -Path $RegistryPath -Name “UseVncAuthentication” -Value 1 -Type DWord -Force# Additional security settings
Set-ItemProperty -Path $RegistryPath -Name “AcceptRfbConnections” -Value 1 -Type DWord -Force
Set-ItemProperty -Path $RegistryPath -Name “QueryAcceptOnTimeout” -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryPath -Name “QueryTimeout” -Value 30 -Type DWord -Force
Set-ItemProperty -Path $RegistryPath -Name “LocalInputPriority” -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryPath -Name “LocalInputPriorityTimeout” -Value 3 -Type DWord -ForceWrite-Host “Registry settings configured successfully.” -ForegroundColor Green
}
catch {
Write-Host “Error configuring registry: $_” -ForegroundColor Red
}# Configure Windows Firewall
Write-Host “Configuring Windows Firewall rules…” -ForegroundColor Yellow
try {
# Remove existing rules if they exist
Remove-NetFirewallRule -DisplayName “TightVNC Server” -ErrorAction SilentlyContinue# Add firewall rule for all profiles (Domain, Private, Public)
New-NetFirewallRule -DisplayName “TightVNC Server” `
-Direction Inbound `
-Protocol TCP `
-LocalPort $Port `
-Action Allow `
-Profile Domain,Private,Public `
-Enabled True `
-Description “Allow TightVNC Server connections on port $Port”Write-Host “Firewall rule created successfully for port $Port on all profiles.” -ForegroundColor Green
}
catch {
Write-Host “Error configuring firewall: $_” -ForegroundColor Red
}# Restart TightVNC Service
Write-Host “Restarting TightVNC Server service…” -ForegroundColor Yellow
try {
Restart-Service -Name “tvnserver” -Force -ErrorAction Stop
Write-Host “TightVNC Server service restarted successfully.” -ForegroundColor Green
}
catch {
Write-Host “Error restarting service: $_” -ForegroundColor Red
Write-Host “Attempting to start the service…” -ForegroundColor Yellow
try {
Start-Service -Name “tvnserver” -ErrorAction Stop
Write-Host “TightVNC Server service started successfully.” -ForegroundColor Green
}
catch {
Write-Host “Error starting service: $_” -ForegroundColor Red
}
}# Verify service is running
Write-Host “`nVerifying installation…” -ForegroundColor Yellow
$Service = Get-Service -Name “tvnserver” -ErrorAction SilentlyContinue
if ($Service) {
Write-Host “Service Status: $($Service.Status)” -ForegroundColor Cyan
Write-Host “Service Start Type: $($Service.StartType)” -ForegroundColor Cyan
}# Verify firewall rule
$FirewallRule = Get-NetFirewallRule -DisplayName “TightVNC Server” -ErrorAction SilentlyContinue
if ($FirewallRule) {
Write-Host “Firewall Rule: Enabled” -ForegroundColor Cyan
}# Clean up installer
Write-Host “`nCleaning up…” -ForegroundColor Yellow
Remove-Item -Path $InstallerPath -Force -ErrorAction SilentlyContinueWrite-Host “`n=== Installation Complete ===” -ForegroundColor Green
Write-Host “TightVNC Server is configured and running on port $Port” -ForegroundColor Green
Write-Host “Password has been set as specified” -ForegroundColor Green
Write-Host “Service is set to start automatically” -ForegroundColor Green
Write-Host “Firewall rule has been added for all profiles” -ForegroundColor Green# Remove problematic AppX packages that prevent Sysprep
Write-Host “`n=== Removing User-Specific AppX Packages ===” -ForegroundColor Yellow
Write-Host “Cleaning up AppX packages that could cause Sysprep to fail (Error 0x80073CF2)…” -ForegroundColor Yellowtry {
# Get all AppX packages for all users that aren’t provisioned
$AppxPackages = Get-AppxPackage -AllUsers | Where-Object {
$_.NonRemovable -eq $false -and
-not (Get-AppxProvisionedPackage -Online | Where-Object {$_.DisplayName -eq $_.Name})
}if ($AppxPackages) {
Write-Host “Found $($AppxPackages.Count) user-specific AppX packages to remove…” -ForegroundColor Cyanforeach ($Package in $AppxPackages) {
try {
Write-Host ” Removing: $($Package.Name)…” -ForegroundColor Gray
Remove-AppxPackage -Package $Package.PackageFullName -AllUsers -ErrorAction Stop
}
catch {
Write-Host ” Warning: Could not remove $($Package.Name): $_” -ForegroundColor Yellow
}
}Write-Host “AppX package cleanup completed.” -ForegroundColor Green
}
else {
Write-Host “No problematic AppX packages found.” -ForegroundColor Green
}
}
catch {
Write-Host “Warning: Error during AppX cleanup: $_” -ForegroundColor Yellow
Write-Host “Continuing with Sysprep…” -ForegroundColor Yellow
}# Check for pending reboots before Sysprep
Write-Host “`n=== Checking for Pending Reboots ===” -ForegroundColor Yellow$PendingReboot = $false
# Check Component Based Servicing
if (Test-Path “HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending”) {
Write-Host “Pending reboot detected: Component Based Servicing” -ForegroundColor Yellow
$PendingReboot = $true
}# Check Windows Update
if (Test-Path “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired”) {
Write-Host “Pending reboot detected: Windows Update” -ForegroundColor Yellow
$PendingReboot = $true
}# Check Pending File Rename Operations
$PendingFileRename = Get-ItemProperty “HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager” -Name PendingFileRenameOperations -ErrorAction SilentlyContinue
if ($PendingFileRename) {
Write-Host “Pending reboot detected: File Rename Operations” -ForegroundColor Yellow
$PendingReboot = $true
}if ($PendingReboot) {
Write-Host “`nWARNING: System has pending updates/reboots!” -ForegroundColor Red
Write-Host “Sysprep will fail if run now (Error 0x8007139F)” -ForegroundColor Red
Write-Host “`nRECOMMENDED ACTION:” -ForegroundColor Yellow
Write-Host “1. Reboot the system now to complete pending updates” -ForegroundColor Cyan
Write-Host “2. After reboot, run this script again” -ForegroundColor Cyan
Write-Host “`nAlternatively, the script can attempt to reboot now and you can run it again after.” -ForegroundColor Yellow$Response = Read-Host “`nDo you want to reboot now? (Y/N)”
if ($Response -eq “Y” -or $Response -eq “y”) {
Write-Host “Rebooting system in 10 seconds…” -ForegroundColor Yellow
Start-Sleep -Seconds 10
Restart-Computer -Force
}
else {
Write-Host “Sysprep cancelled. Please reboot manually and run the script again.” -ForegroundColor Yellow
exit 1
}
}
else {
Write-Host “No pending reboots detected. Proceeding with Sysprep…” -ForegroundColor Green
}# Run Sysprep
Write-Host “`n=== Running Sysprep ===” -ForegroundColor Yellow
Write-Host “The system will generalize and reboot…” -ForegroundColor Yellow
Start-Sleep -Seconds 3try {
$SysprepPath = “$env:SystemRoot\System32\Sysprep\sysprep.exe”if (Test-Path $SysprepPath) {
Write-Host “Executing Sysprep /generalize /oobe /reboot…” -ForegroundColor Yellow
Start-Process -FilePath $SysprepPath -ArgumentList “/generalize”, “/oobe”, “/reboot” -Wait -NoNewWindow
}
else {
Write-Host “Sysprep not found at $SysprepPath” -ForegroundColor Red
exit 1
}
}
catch {
Write-Host “Error running Sysprep: $_” -ForegroundColor Red
exit 1
}