Manually update

Hi All,
I try create manual update script to install .msu files for multiple Windows ver.
I run this from usb with .bat file, script exit with out any error but nothing installed
Please, help
Thanks.

$currentLocation = Split-Path -parent $MyInvocation.MyCommand.Definition
$OSmBuild = (Get-WmiObject Win32_OperatingSystem).Version

# Update Directory Location
$updatedir_1507 = "Updates\version_1507"
$updatedir_1511 = "Updates\version_1511"
$updatedir_1607 = "Updates\version_1607"

if($OSmBuild -like '10.0.10240')
{
  
$updatedir = "$currentLocation\$updatedir_1507"

$files = Get-ChildItem $updatedir -Recurse
$msus = $files | ? {$_.extension -eq ".msu"}

foreach ($msu in $msus)
{
    write-host "Installing update $msu ..."
    $fullname = $msu.fullname
    $fullname = "`"" + $fullname + "`""
    $parameters = $fullname + " /quiet /norestart"
    $install = [System.Diagnostics.Process]::Start( "wusa",$parameters )
    $install.WaitForExit()
    write-host "Finished installing $msu"
}

write-host "Restarting Computer"
#Restart-Computer

### Windows_10_version_1511 ###

    ElseIf($OSmBuild -like '10.0.10586')
    {
       
$updatedir = "$currentLocation\$updatedir_1511"

$files = Get-ChildItem $updatedir -Recurse
$msus = $files | ? {$_.extension -eq ".msu"}

foreach ($msu in $msus)
{
    write-host "Installing update $msu ..."
    $fullname = $msu.fullname
    $fullname = "`"" + $fullname + "`""
    $parameters = $fullname + " /quiet /norestart"
    $install = [System.Diagnostics.Process]::Start( "wusa",$parameters )
    $install.WaitForExit()
    write-host "Finished installing $msu"
}

write-host "Restarting Computer"
#Restart-Computer
}

 ### Windows_10_version_1607 ###

    ElseIf($OSmBuild -like '10.0.14393')
    {
        $updatedir = "$currentLocation\$updatedir_1607"

$files = Get-ChildItem $updatedir -Recurse
$msus = $files | ? {$_.extension -eq ".msu"}

foreach ($msu in $msus)
{
    write-host "Installing update $msu ..."
    $fullname = $msu.fullname
    $fullname = "`"" + $fullname + "`""
    $parameters = $fullname + " /quiet /norestart"
    $install = [System.Diagnostics.Process]::Start( "wusa",$parameters )
    $install.WaitForExit()
    write-host "Finished installing $msu"
}

write-host "Restarting Computer"
#Restart-Computer
}
Else
{
 Write-Host "Windows 7 or XP"
}

Brad,
Welcome back to the forum. :wave:t4:

It sounds weird that you don’t get any errors since there 's a closing culry brace missing after your first Restart-Computer command.

Regardless of that … since the only difference between your if conditions is the source path you can write your code much less repetitive like this:

[cmdletbinding()]
Param()
$OSmBuild = (Get-CimInstance -ClassName CIM_OperatingSystem -Verbose:$false ).Version 
Write-Verbose "detected version: '$($OSmBuild)'"
switch ($OSmBuild) {
    '10.0.10240' { $Path = Join-Path -Path $PSScriptRoot -ChildPath 'Updates\version_1507' }
    '10.0.10586' { $Path = Join-Path -Path $PSScriptRoot -ChildPath 'Updates\version_1511' }
    '10.0.14393' { $Path = Join-Path -Path $PSScriptRoot -ChildPath 'Updates\version_1607' }
    Default { $UnsupportedOS = $true }
}
if (-not $UnsupportedOS) {
    $MsuList = Get-ChildItem -Path $Path -Filter '*.msu' -File -Recurse
    foreach ($Msu in $MsuList) {
        Write-Verbose "Installing update $msu ..."
        Start-Process -FilePath 'wusa.exe' -ArgumentList "$($Msu.FullName) /quiet /norestart" -Wait
        Write-Verbose "Finished installing $msu"
    }
    Write-Verbose "Restarting Computer ..."
    Restart-Computer -Confirm
}
else {
    Write-Verbose 'Unsupported OS ... '
}

With the [cmdletbinding] at the top of your script and using Write-Verbose instead of Write-Host it does not output unnecessary messages until you run it with the parameter -Verbose. If you tested the script successfully of course you can remove the parameter -Confirm from the Restart-Computer command. :wink:

Regardless of that … are you really still working with WIndows 10 1507, 1511 or 1607?? The support for those already ended years ago. You should not run those Windows versions anymore in any production environment!!!

Hi Olaf,

Thank you for your help
Look like all working correct, BUT nothing installed
This old systems just for the test, i also try update 1909 with latest .msu, script finish no errors but i not see new KB installed

Thanks for your help as always :handshake:

I wrote a script a while back to do pretty much what you are doing. I chose a slightly different approach as my script was designed to install ANY updates in a specific folder be they .EXE, .CAB or .MSU. The only thing I can see that I did differently was defined the full path to WUSA.exe. Have you tried that?

$WSU = "$($ENV:SystemRoot)\System32\Wusa.exe"
$cmdToExec = 'Start-Process -FilePath $WSU -ArgumentList ($($Msu.FullName), /quiet, /norestart) -Wait'
Invoke-Expression $cmdToExec

Another option I chose to use to help in troubleshooting was to add a logfile.

$WusaLog = Join-Path $ENV:Temp "$($Wsu.Name).evtx"
$LogArg = "/log:$WusaLog"
$cmdToExec = 'Start-Process -FilePath $WSU -ArgumentList ($($Msu.FullName), /quiet, /norestart, $LogArg) -Wait'
Invoke-Expression $cmdToExec

Hi tonyd,
Thank you for your exemple,
Olaf script and your working perfect
it was my mistake, i downloaded comulative updates but tottaly forget download stack updates
but now look like all working perfect , but script stop in one point and in EventLog i see this message:
“A reboot is necessary before package KB5009545 can be changed to the Installed state.”
How i can continue process and reboot in the end when all .msu installed
also,
Do you mind to share your code how to install mix files( .EXE, .CAB or .MSU)
Thanks