Windows 10 20H2 and Edge

To start of this blog-post we have to set a few basics…

Image result for edge chromium

Windows 10 20H2 includes Edge Chromium. Specifically – Edge Chromium v84 (something something)

If you deploy Edge Chromium later version (like 87? 88?) to your 1909/2004 devices – and then upgrade to Windows 10 20H2, you will effectively downgrade Edge Chromium to 84.

As far as I can understand – the details, the workarounds and apparently a promise that this will be better is all published on Borncity.

The issue at hand though is that Edge Chromium is a moving target, so including even the latest version today in whatever upgrade process you have – will most likely in a months time have an older version than what you have installed on your endpoint. This is installer will bomb-out with “there is a newer version already installed”. Yet, the users will be stuck with Edge Chromium 84. I don’t quite get why this is the case. The previous version is installed, but version 84 always starts and you can’t upgrade because of this and for some reason Edge Chromium is special software that just doesn’t tag along?

Now, to workaround this you can read the information regarding the installed Edge Chromium (it is installed, just not running) and then perform an over-ride (REINSTALL=ALL REINSTALLMODE=A according to the comments on Borncity).

Let’s gather what we need to create something simplistic.

Function to retrieve installed software in Powershell. There are a bunch out there. You can use PSADT. I just found one that was small and did the trick. I can see so many problems with it – but it works. Unfortunately I have no idea where I stole this from. If you want todo properly – use PSADT. If I stole this from you – post a comment and I will remove it and post a link instead.

function Get-InstalledSoftware {
    <#
    .SYNOPSIS
        Retrieves a list of all software installed
    .EXAMPLE
        Get-InstalledSoftware
        
        This example retrieves all software installed on the local computer
    .PARAMETER Name
        The software title you'd like to limit the query to.
    #>
    [OutputType([System.Management.Automation.PSObject])]
    [CmdletBinding()]
    param (
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$Name
    )
 
    $UninstallKeys = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    $null = New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS
    $UninstallKeys += Get-ChildItem HKU: -ErrorAction SilentlyContinue | Where-Object { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' } | ForEach-Object { "HKU:\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall" }
    if (-not $UninstallKeys) {
        Write-Verbose -Message 'No software registry keys found'
    } else {
        foreach ($UninstallKey in $UninstallKeys) {
            if ($PSBoundParameters.ContainsKey('Name')) {
                $WhereBlock = { ($_.PSChildName -match '^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$') -and ($_.GetValue('DisplayName') -like "$Name*") }
            } else {
                $WhereBlock = { ($_.PSChildName -match '^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$') -and ($_.GetValue('DisplayName')) }
            }
            $gciParams = @{
                Path        = $UninstallKey
                ErrorAction = 'SilentlyContinue'
            }
            $selectProperties = @(
                @{n='GUID'; e={$_.PSChildName}}, 
                @{n='Name'; e={$_.GetValue('DisplayName')}}
            )
            Get-ChildItem @gciParams | Where $WhereBlock | Select-Object -Property $selectProperties
        }
    }
}

Second you need something to validate that MSIExec isn’t busy. Like the function Test-IsMutexAvailable from (you guessed it) PSADT. Come to think of it – you really should just throw everything I did in a garbage bin and rewrite it using the PSADT framework.

Third – here is the crude and basic logic of what we want to run after the Windows 10 20H2 upgrade is completed.

Consists of – arguments to run the re-install of Edge. Oddly – the latest version should have a ProductCode, but not version 84 which comes in the box. Then wait until MSIExec had its coffee. Once coffee is up – run the install…. Logging optional.

$args = "/i `"$((Get-InstalledSoftware -Name "Microsoft Edge").guid)`" /qn REINSTALL=ALL REINSTALLMODE=A"
Test-IsMutexAvailable -MutexName 'Global\_MSIExecute' -MutexWaitTimeInMilliseconds (New-TimeSpan -Minutes 5).TotalMilliseconds
$process = Start-Process -FilePath "msiexec" -ArgumentList  $args -wait -PassThru

Set-Content -Path c:\windows\temp\edge.txt -Value "Edge Exit code: $($process.exitcode) - Argument: $($args)"

This should run if the upgrade is successful. Not entirely sure how this works in reality – but Microsoft offers a success.cmd since 2004 so that would be a good idea to use.