Here is my WUA11 2.1 script.
It checks for 64GB free disk space (I’ve seen Windows fail for disk all the way up to 63.9GB)
8GB RAM
It downloads the Windows Upgrade Assistant, and then installs silently doing a reboot (it prompts about 1 min, so don’t run this during the day against people)
It will stream the Panther Setup log which has some great information in it when you do have failures.
After it finishes the upgrade (or attempt)
it will then reboot (if you see a successfull Win11 upgrade, the WUA11 will reboot you, then Immy will also reboot you)
It will then pull the Panther setup error log, I usually use the error log and then go see what was happening around the error for better context of whats going on.
It will then install the Powershell module by AdamGrossTX (github) “FU.WhyAmiBlocked” and then run the module commands to pull why you are being blocked.
As a note, the good data comes from the SDB files, which you will need python 3.8 installed on the machine to deflate the compressed SDB file.
It Should, if it has a valid decompressed and parsable XML file, should then spit out all the BlockTypes that are preventing you from upgrading. You should carefully review these.
It should also, let you know the root cause of the block,
If there is a manual registry Block Override key to utilize,
Then spit out a reg and ps1 file for you to utilize to implement the BlockOverrides.
I will NOT provide any warranty on using a block override. You should ideally FIX the cause.
I’m in the MSPGeekChat all the time, and have shared this there as well. And will be working on updates to it when I can.
switch($method){
"set" {
Write-Host "Checking to see if we have the minimum requirements of RAM."
$totalMemoryGB=Invoke-ImmyCommand {
$computerSystem = Get-WmiObject -Class Win32_ComputerSystem
return [Math]::Round($computerSystem.TotalPhysicalMemory / (1GB))
}
Write-Output "Total System Memory: $totalMemoryGB GB"
if ($totalMemoryGB -lt 8) {
Write-Error -Message "System memory $($totalMemoryGB) is less than 8GB." -ErrorAction Stop
} else {
Write-Output "System memory is sufficient (8GB or more)."
}
Write-Host "Goign to Check for Disk space, Need at least 64GB free to be able to upgrade."
$freespacegb=Invoke-ImmyCommand{
$drive = Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Root -eq 'C:\'}
return [math]::Round($drive.Free / 1GB, 2)
}
if ($freeSpaceGB -ge 64) {
Write-Host "C: drive has $($freeSpaceGB) GB free, which is more than 64GB."
} else {
Write-Error -Message "Houston, we have a problem. Not enough Diskspace: $($freeSpaceGB) GB < 64GB" -ErrorAction Stop
}
Restart-ComputerAndWait
$uri = "https://go.microsoft.com/fwlink/?linkid=2171764"
$downloaduri = Get-RedirectedUri $uri
$upgradeAssistant = "C:\Windows\Temp\Win11Upgrade\UpgradeAssistant.exe"
Download-File -Source $downloaduri -Destination $upgradeAssistant -Force
$logFile = 'C:\`$WINDOWS.~BT\Sources\Panther\setupact.log'
$logFolder='C:\Win11UpgradeLogs'
Write-Host "Checking to see if `$Windows.~BT folder exists, and if so, remove it for clean run results."
Invoke-ImmyCommand {
$logFile = 'C:\$WINDOWS.~BT\Sources\Panther\setupact.log'
$WindowsBT='C:\$WINDOWS.~BT\'
if (Test-Path -Path $logFile) {
Write-Host "Panther setupact file already exists."
Write-Host "Removing $($WindowsBT) folder recursively prior to WUA launch."
Remove-Item -Path $WindowsBT -Recurse -Force
}
$FUPath='C:\FeatureUpdateBlocks'
Get-ChildItem -Path $FUPath -Directory | ForEach-Object {
Remove-Item -Path $_.FullName -Recurse -Force
Write-Host "Deleted FU Log directory, we want a clean log run each Immy run: $($_.FullName)"
}
}
Start-ProcessWithLogTail -Path $upgradeAssistant -ArgumentList "/quietinstall /skipeula /auto upgrade /NoRestartUI /copylogs $LogFolder" -LogFilePath $logFile -Timeout 14400
Restart-ComputerAndWait
Invoke-ImmyCommand -Timeout 14400 {
$currentbuild=[int](Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').CurrentBuild
if($currentbuild -lt 22000) {
$logPath = 'C:\$WINDOWS.~BT\Sources\Panther\setupact.log'
$errLogPath = 'C:\$WINDOWS.~BT\Sources\Panther\setuperr.log'
Write-Host "Checking for file $errLogPath`n"
if (Test-Path $errLogPath) {
Set-ExecutionPolicy Unrestricted -force
$errLogFileContent = Get-Content -Path $errLogPath -Force
Write-Host "$errLogPath found. Log contents:`n"
#Write-Host "$errLogFileContent`n"
Get-Content $errLogPath
#Sometimes Dell and Windows do not see eye to eye on BIOS updates, so let's check hidden Windows updates.
Install-Module -Name -Force
if (-not (Get-Module -ListAvailable -Name "PSWindowsUpdate")) {
Write-Host "Module 'PSWindowsUpdate' not found. Installing from PowerShell Gallery..."
Install-Module -Name "PSWindowsUpdate" -Force -Scope AllUsers -AllowClobber
Import-module -Name "PSWindowsUpdate"
} else { Import-module -Name "PSWindowsUpdate"}
Get-Windowsupdate -WithHidden
#Let's See Why we are blocked with this lovley little Powershell module by AdamGrossTX
#https://www.powershellgallery.com/packages/FU.WhyAmIBlocked/1.0.0.9
#https://github.com/AdamGrossTX/FU.WhyAmIBlocked
# Check if the module "FU.WhyAmIBlocked" is installed
#but before we do that, we need to ensure that NuGet is installed, at at the minimimum version from my testing, 3.0.0.1
try {
# Check if NuGet provider is installed and its version
$nugetProvider = Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue
if ($nugetProvider -eq $null -or $nugetProvider.Version -lt [Version]"3.0.0.1") {
Write-Host "NuGet provider is not installed or the version is less than 3.0.0.1. Installing NuGet provider..."
Install-PackageProvider -Name NuGet -MinimumVersion 3.0.0.1 -Force -Confirm:$False
Write-Host "NuGet provider installed successfully."
} else {
Write-Host "NuGet provider is already installed and meets the minimum version requirement."
}
} catch {
Write-Error "Failed to install NuGet provider: $_.Exception.Message"
exit 1
}
if (-not (Get-Module -ListAvailable -Name "FU.WhyAmIBlocked")) {
Write-Host "Module 'FU.WhyAmIBlocked' not found. Installing from PowerShell Gallery..."
Install-Module -Name "FU.WhyAmIBlocked" -Force -Scope AllUsers -AllowClobber
Import-module -Name "FU.WhyAmIBlocked"
Initialize-FUModule
}
# Import the module
Import-Module "FU.WhyAmIBlocked"
Write-Host "We are going to need python for this so, please make sure you have python deployed for machines being upgraded via WUA so we can see what the issue is."
# Lets now run the FU Why Am I Blocked powershell against the Panther install logs
#We also need to put the Pythong file SDBUnpacker useses.
$myDownloadUrl="https://raw.githubusercontent.com/TheEragon/SdbUnpacker/refs/heads/master/SdbUnpacker.py"
Invoke-WebRequest $myDownloadUrl -OutFile 'C:\Program Files\WindowsPowerShell\Modules\FU.WhyAmIBlocked\1.0.0.9\SdbUnpacker.py'
Get-FUBlocks -ProcessPantherLogs
$FUBlocksContent='C:\FeatureUpdateBlocks\*\Results.txt'
Write-Host "Please review the FU Blocks Content"
Write-host "It is recommend to correct the root cause vs using a Block."
Get-Content $FUBlocksContent
Write-Host "We will now go ahead and generate the reg keys to import to enable block overrides"
$BOPath="C:\BlockOverRide"
if (-Not (Test-Path -Path $BOPath)) {
New-Item -ItemType Directory -Path $BOPath
}
Export-FUBypassBlock -Path $BOPath
Write-Host "Please review the registry files in $($BOPath)"
Write-Host "Please note, we are not responsibile for any damages caused by using a block override."
}else {
Write-Host "$errLogPath not found`n"
}
}else{
Write-Host "It appears we have upgraded, version build shows as $($CurrentBuild) is > 22000"
}
}
}
"test" {
#Returns true or false if the Current Build should be upgraded, or has upgraded.
$CurrentBuild=Invoke-ImmyCommand {
$currentbuild=[int](Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').CurrentBuild
if($currentbuild -lt 22000) {
return $false
}else {
return $true
}
}
return $CurrentBuild
}
"get" {
$CurrentBuildNumber=Invoke-ImmyCommand {
$CurrentBuild=[int](Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').CurrentBuild
return $currentBuild
}
return $CurrentBuildNumber
}
}