My Latest WUA 11 script

If you want the SDB decompressed, install python prior to running.
Using the FU.WhyAmIBlocked Powershell module

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 "Going 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
            }
            $SecureBootCheck=Invoke-ImmyCommand { return Confirm-SecureBootUEFI }
            if(!$SecureBootCheck){
                 Write-Error "SecureBoot Not Enabled."
            }else { Write-Host "System has SecureBoot enabled."}
            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 -Timeout 14000 {
                $logFile = 'C:\$WINDOWS.~BT\Sources\Panther\setupact.log'
                $WindowsBT='C:\$WINDOWS.~BT\'
                if (Test-Path -Path $logFile) {
                    #Take ownership of existing Panther file 
                    #updated provided by CCP_Jason
                    takeown /f $WindowsBT /r /d y > nul
                    Write-Host "Ownership of '$folderPath' and its contents has been taken by System."
                    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)"
                }
            }
            Write-Host "Starting Windows 11 Upgrade Assistant. Can't stream the setup log as it kills Immy. We wil get the contents after Windows 11 update completes before we reboot."       
            Invoke-ImmyCommand -timeout 14400 {
                $upgradeAssistant = $using:UpgradeAssistant
                Start-Process $upgradeAssistant -ArgumentList "/quietinstall /skipeula /auto upgrade /NoRestartUI /SkipCompatCheck /dynamicupdate disable /PreventWUUpgrade /SkipSelfUpdate /priority normal /copylogs $LogFolder" -Wait            
            }
            Invoke-ImmyCommand {
                $LogFile=$using:logfile
                Get-Content $LogFile
            }
            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 -Confirm:$false
                        $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.
                        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 -confirm:$false
                            Write-Host "Module installed, now let."
                        }
                        Write-Host "Importing Windows update Module"
                        Import-module -Name "PSWindowsUpdate" 
                        Write-Host "Now pulling Windows updates with Hidden updates"
                        Get-Windowsupdate -WithHidden -NotTitle "Windows 11" -Verbose
                        if((Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -Name 'Version' -ErrorAction SilentlyContinue | ForEach-Object {$_.Version -as [System.Version]} | Where-Object {$_.Major -eq 3 -and $_.Minor -eq 5}).Count -ge 1){
                            Write-Host ".Net FX 35 installed, good"
                        }else {
                            Write-Host "Installing .Net 3.5, required to unpack SDB files"
                            DISM /Online /Enable-Feature /FeatureName:NetFx3 /All 
                        }
                        #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-Module "PowershellGet" -Force -confirm:$false
                                Install-PackageProvider -Name "NuGet" -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
                        } else {
                         # 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"
                        Write-host "Refreshing System Detection Information"
                        Refresh-ComputerSystemInfo
                    }
                }               
            }        
    "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
    }
}

@Jeremy_Barnes how do you have this setup as a deployment to push out?

Create a new Task for the Win11 upgrade
Then in the script section , select combined script type
Create a new script, copy and paste that in there,

You want to make sure its a Type: Task, Execution: Metascript, Timeout: 14400, then save it.
Save your deployment task, then deploy it.

If you want the SDB to be parsed and checked against, you need Python 3.1.18 installed on the machine prior to running.

I also recommend that you check and run Windows Updates for all updates, including BIOS/driver updates as MFG and Windows Update DB can conflict, and can cause issues.

If you use anything like ThreatLocker, or AutoElevate, its best to put those into bypass mode, or in some cases with AutoElevate, uninstall it, reboot, and then process. Then reinstall AutoElevate afterwards.

The script does check to see if you meet required RAM, SecureBoot, and Disk space; I have it set to check for 64GB free, I’ve seen it fail at 63.9GB free though others claim its much lower, I’ve just never seen it work lower than 64GB free.

repeated runs will flush out the $Windows.`BT folder. Before you attempt to re-run the WUA script, review logs, both the setupacct.log and setuperr.log; Both will have beneficial information.
Check the script’s output for the SDB information, if it finds anything that can have an override, it should spit a ps1 and a .reg key.

1 Like