Windows 11 23H2 to 25H2
Like many of us, you might have been put off by the issues with Windows 11 24H2. But are being forced to move on to a new version of Windows 11. Windows 11 23h2 to Windows 11 24H2 is not an enablement package, this not a quick upgrade. Its a full upgrade like going from Windows 10 to Windows 11.
The management requirement was to have the OS upgrade in the background, and then popup a message at the end. To tell the user their machine has been upgraded, and to allow some more time to get logged on next time you restart your machine.
So the only way could think off to do this was to use a ConfigMGR application and run the setup.exe from the iso with the required command line switches wrapped inside ADT. The logging that ADT brings is outstanding, and it can show a message at the end.
The technical requirements that i wanted to do to pull this off was to have the printer to Print to PDF Printer removed. The Fax printer to be removed, and the XPS Document Writer printer. And then once the OS was on the disk and the reboot had happened to put these back onto the users computer. And do a few other things as well. i wont paste the massive script in at the top, i will paste that at the end. And only put the relevant bits in at the top.
This script was written in version 4.1.5 Link here
The Script
There is no welcome screen, or installation progress shown
##================================================
## MARK: Pre-Install
##================================================
$adtSession.InstallPhase = "Pre-$($adtSession.DeploymentType)"
## Show Welcome Message, close processes if specified, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt.
$saiwParams = @{
AllowDefer = $false
DeferTimes = 3
CheckDiskSpace = $false
PersistPrompt = $false
}
if ($adtSession.AppProcessesToClose.Count -gt 0)
{
$saiwParams.Add('CloseProcesses', $adtSession.AppProcessesToClose)
}
#Show-ADTInstallationWelcome @saiwParams
## Show Progress Message (with the default message).
#Show-ADTInstallationProgressThis section is just laying out the folders that will be used in the script later on for detection methods, and copy files onto the drive to be accessed later
# Pre-Installation tasks
New-ADTFolder -LiteralPath "C:\Programdata\ORG\"
New-ADTFolder -LiteralPath "C:\Programdata\ORG\Windows1125H2"
Copy-ADTFile -Path "$($adtSession.DirSupportFiles)\*" -Destination "C:\ProgramData\ORG\Windows1125H2"In this section the first time the script ran, it check for the presence of the state file if this does not exist it it removes the required printers from the computer. Drops the state file into place, so the next time it runs the state file exists and it runs the windows setup.
The printers are removed from the computer at the start, because these have been known to cause issues with previous Windows upgrades, so they are removed.
The script then sends the return code of 3010 which is a soft reboot. This gives the user the standard countdown with the bar moving along. Ours is set to 24 hours. The reason i am using the built in ConfigMgr restart message rather than the ones that are built into ADT, is because our users are more familiar with that screen appearing on their devices.
Once the device has been restarted, either by the user or the countdown running down. Software centre will run the application again as the detection method does not match.
The second time this is ran the state file is present, which means it will now run the Windows setup. Once the setup is complete, it will leave a text file on the disk that will then match the detection method.
# Upgrade Process
$stateFile = "C:\ProgramData\Org\Windows11en-GB25H2State.txt"
if (Test-Path $stateFile) {
# State file found, run upgrade
Write-ADTLogEntry "State file found, running Windows setup"
Start-ADTProcess -FilePath "$($adtSession.DirFiles)\setup.exe" -ArgumentList '/Auto Upgrade /PostOOBE C:\ProgramData\ORG\Windows1125H2\SetupComplete.cmd /Bitlocker TryKeepActive /DynamicUpdate Enable /Eula Accept /NoReboot /Quiet /Showoobe None /Telemetry Disable' -WindowStyle 'Hidden' -PassThru
Out-File -FilePath "C:\ProgramData\ORG\Windows1125H2Upgraded.txt"
} else {
# No State file found, run clean up
Write-ADTLogEntry "No state file found, running OS cleanup"
Write-ADTLogEntry "Removing Print to PDF"
Disable-WindowsOptionalFeature -Online -FeatureName "Printing-PrintToPDFServices-Features" -NoRestart
Write-ADTLogEntry "Removed Print to PDF"
Write-ADTLogEntry "Removing XPD Document Writer"
Disable-WindowsOptionalFeature -Online -FeatureName "Printing-XPSServices-Features" -NoRestart
Remove-PrinterDriver -Name "Microsoft XPS Document Writer v4"
Write-ADTLogEntry "Removed XPS Document Writer"
Write-ADTLogEntry "Removing Fax Printer"
Remove-WindowsCapability -Online -Name Print.Fax.Scan~~~~0.0.1.0
Write-ADTLogEntry "Removed Fax Printer"
Out-File -FilePath "C:\ProgramData\ORG\Windows11en-GB25H2State.txt"
Write-ADTLogEntry "State file written"
Write-ADTLogEntry "Closing down ADT session"
Close-ADTSession -ExitCode 3010The script then moves on to this section. If no one is logged on, reboot the computer. Why leave the computer sitting there, with a windows upgrading waiting to happen! If the user is logged on, then throw up the message. We all know that they are are just going to press ok, and not read the message. But at least we have tried!
$loggedOnUsers = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName
if ($null -eq $loggedOnUsers) {
Write-ADTLogEntry "No user logged on, computer rebooted."
Restart-Computer -Force
} else {
Show-ADTInstallationPrompt -Message 'Windows 11 has been upgraded on your computer. The next time the computer is restarted, please allow 20-40 minutes for the update to complete. Clicking OK will dismiss this message, you can carry on working and reboot at a convenient time.' -ButtonRightText 'OK' -Icon Information -NoWait
}