Install Windows 10 Upgrade 2004/20H2 from command line / using a PowerShell Script
Usually we deploy Windows 10 feature and cummulative updates using a deployment solution like Microsoft Endpoint Configuration Manager or Ivanti DSM or LANDesk or lately using the new Infrastructure Manager which is only available in beta by request. And then, sometimes we need to update notebooks which are not ‘well-connected’. First we used to ship/send a USB stick with a current Windows 10 ISO on it, plus a PowerShell script, plus a batch file etc. so the user had to login with his admin account, start the batch file, the batch started to PowerShell (hello to PowerShell execution-policy) script and the script started the Windows 10 Setup using some smart arguments to make sure the user does/did not have to answer any questions. But also we created a log file, just in case the update didn’t succeed – which happend/happens MANY times because of compatibility issue.. anyway.
No we added a new procedure, especially for our small and medium business clients. If the customer has Windows 10 Pro installed, this procedure is quite simple. Just send this PowerShell script, execute it -> dont’ forget about the execution policy..
# Solvia GmbH, Christian Casutt
# Update Windows using Windows Update Assistant
# Link https://go.microsoft.com/fwlink/?LinkID=799445 -> delivered the latest WUA Version as of today, May 28th of 2020 -> 2004!
# Script Version 1.0 - 2020-05-28
function Write-Log {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$Message
)
try {
if (!(Test-Path -path ([System.IO.Path]::GetDirectoryName($LogFilePath)))) {
New-Item -ItemType Directory -Path ([System.IO.Path]::GetDirectoryName($LogFilePath))
}
$DateTime = Get-Date -Format ‘yyyy-MM-dd HH:mm:ss’
Add-Content -Value "$DateTime - $Message" -Path $LogFilePath
}
catch {
Write-Error $_.Exception.Message
}
}
Function CheckIfElevated() {
Write-Log "Info: Checking for elevated permissions..."
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Log "ERROR: Insufficient permissions to run this script. Open the PowerShell console as an administrator and run this script again."
return $false
}
else {
Write-Log "Info: Code is running as administrator — go on executing the script..."
return $true
}
}
# Main
try {
# Declarations
[string]$DownloadDir = 'C:\Solvia\Windows_FU\packages'
[string]$LogDir = 'C:\Solvia\Logs'
[string]$LogFilePath = [string]::Format("{0}\{1}_{2}.log", $LogDir, "$(get-date -format `"yyyyMMdd_hhmmsstt`")", $MyInvocation.MyCommand.Name.Replace(".ps1", ""))
[string]$Url = 'https://go.microsoft.com/fwlink/?LinkID=799445'
[string]$UpdaterBinary = "$($DownloadDir)\Win10Upgrade.exe"
[string]$UpdaterArguments = '/quietinstall /skipeula /auto upgrade /copylogs $LogDir'
[System.Net.WebClient]$webClient = New-Object System.Net.WebClient
# Here the music starts playing ..
Write-Log -Message ([string]::Format("Info: Script init - User: {0} Machine {1}", $env:USERNAME, $env:COMPUTERNAME))
Write-Log -Message ([string]::Format("Current Windows Version: {0}", [System.Environment]::OSVersion.ToString()))
# Check if script is running as admin and elevated
if (!(CheckIfElevated)) {
Write-Log -Message "ERROR: Will terminate!"
break
}
# Check if folders exis
if (!(Test-Path $DownloadDir)) {
New-Item -ItemType Directory -Path $DownloadDir
}
if (!(Test-Path $LogDir)) {
New-Item -ItemType Directory -Path $LogDir
}
if (Test-Path $UpdaterBinary) {
Remove-Item -Path $UpdaterBinary -Force
}
# Download the Windows Update Assistant
Write-Log -Message "Will try to download Windows Update Assistant.."
$webClient.DownloadFile($Url, $UpdaterBinary)
# If the Update Assistant exists -> create a process with argument to initialize the update process
if (Test-Path $UpdaterBinary) {
Start-Process -FilePath $UpdaterBinary -ArgumentList $UpdaterArguments -Wait
Write-Log "Fired and forgotten?"
}
else {
Write-Log -Message ([string]::Format("ERROR: File {0} does not exist!", $UpdaterBinary))
}
}
catch {
Write-Log -Message $_.Exception.Message
Write-Error $_.Exception.Message
}
Update, January 7th 2021
User Patrice Martin asked if it’s possible to suppress the reboot. Sure it is. Just add /NoReboot /NoRestartUI /NoRestart to the arguments. Basically only /NoRestart is needed, /NoReboot /NoRestartUI is beeing used to suppress the UI and don’t give the user the choice to reboot. Anyway, didn’t try the swiches separately but together they worked like a charm.
Another Update, January 8th 2021
unlike the setup.exe that comes with the Windows ISO, the windows update assistant ignores the reboot suppression parameters. So the only viable solution is to kill the task/process?!
Feel free to comment.
Love this!!
I was so sick of downloading the update assistant manually and running it.
Now can just run the script out of our RMM tool.
Thanks heaps.
We are sending this update with our Deployment Software Lansweeper for our VPN users
Is there a way that it will not reboot by itself when the installation is done? Admins users have a choice of reboot or reboot later.
Same here. Tried to figure out how to workaround this, but without luck.
Hi,
We are with 1903 win10 feature update. We would like to stick with 1909. Do we have any tricks to suppress or to stick with 1909 instead of updating to 20H2?
1909 will not be supported beyond May 11 2021 which may change your thinking.
https://docs.microsoft.com/en-us/lifecycle/announcements/windows-10-1909-end-of-servicing
Cheers
Hi,
Thanks for the article.
I found when running this that the Win10Upgrade.exe only installs a ‘Windows10Upgrade’ folder and then nothing else.
To actually get the upgrade to get started, I then had to run the ‘Windows10UpgraderApp.exe’ file in this folder (with the same switches as the upgrade exe). This complicates the whole thing because it then becomes a two stage process.
Have you seen this? Or am I doing something wrong?
Hi ,
I have tried to run this script on my test VM . but somehow the process is stuck . its over 1 hr nothing happened. so I have checked the log file ,there it says “will try to download windows update assistant.
PowerShell is running as admin and I just copied the code ,paste on it and ran .
Please correct me If I am doing any wrong process.