6

I'm running the following powershell commmand

$chromePath = "${Env:ProgramFiles(x86)}\Google\Chrome\Application\" 
$chromeApp = "chrome.exe"
$chromeCommandArgs = @('--make-default-browser')
Invoke-Expression “cmd.exe /C `"$chromePath$chromeApp`" $chromeCommandArgs”

Unfortunatley, when I run this, I get the following error message.

cmd.exe : [1396:2128:0708/153347:ERROR:gpu_info_collector_win.cc(98)] Can't retrieve a valid WinSAT assessment. At line:1 char:1 + cmd.exe /C "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --make- ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: ([1396:2128:0708...SAT assessment.:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError

[1396:2128:0708/153347:ERROR:shell_integration_win.cc(200)] Chrome could not be set as default browser.

What could be causing this error? I realize there are various ways of executing the command, but the bottom line is that executing Chrome with the --make-default-browser switch is failing.

3
  • Is this a PowerShell specific issue? In other words, does it work on your machine from a standard command line?
    – neontapir
    Commented Jul 8, 2013 at 21:46
  • I can set it in the Settings of Chrome. If I run a straight cmd no error is thrown, but it doesn't appear to set the setting either. Commented Jul 8, 2013 at 22:00
  • 1
    I love how the question, which exactly describes my issue and shows up at the top of my Google search, has been downvoted but the highest ranked answer has a dead link.
    – Christine
    Commented Oct 14, 2018 at 14:42

7 Answers 7

11

Adapted from this archived poshcode user script, with which you can switch between Chrome, Firefox, Internet Explorer, Opera and Safari. Add the Set-DefaultBrowser function like this:

function Set-DefaultBrowser
{
    param($defaultBrowser)

    $regKey      = "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\{0}\UserChoice"
    $regKeyFtp   = $regKey -f 'ftp'
    $regKeyHttp  = $regKey -f 'http'
    $regKeyHttps = $regKey -f 'https'

    switch -Regex ($defaultBrowser.ToLower())
    {
        # Internet Explorer
        'ie|internet|explorer' {
            Set-ItemProperty $regKeyFtp   -name ProgId IE.FTP
            Set-ItemProperty $regKeyHttp  -name ProgId IE.HTTP
            Set-ItemProperty $regKeyHttps -name ProgId IE.HTTPS
            break
        }
        # Firefox
        'ff|firefox' {
            Set-ItemProperty $regKeyFtp   -name ProgId FirefoxURL
            Set-ItemProperty $regKeyHttp  -name ProgId FirefoxURL
            Set-ItemProperty $regKeyHttps -name ProgId FirefoxURL
            break
        }
        # Google Chrome
        'cr|google|chrome' {
            Set-ItemProperty $regKeyFtp   -name ProgId ChromeHTML
            Set-ItemProperty $regKeyHttp  -name ProgId ChromeHTML
            Set-ItemProperty $regKeyHttps -name ProgId ChromeHTML
            break
        }
        # Safari
        'sa*|apple' {
            Set-ItemProperty $regKeyFtp   -name ProgId SafariURL
            Set-ItemProperty $regKeyHttp  -name ProgId SafariURL
            Set-ItemProperty $regKeyHttps -name ProgId SafariURL
            break
        }
        # Opera
        'op*' {
            Set-ItemProperty $regKeyFtp   -name ProgId Opera.Protocol
            Set-ItemProperty $regKeyHttp  -name ProgId Opera.Protocol
            Set-ItemProperty $regKeyHttps -name ProgId Opera.Protocol
            break
        }
    } 

}

Then invoke it with your desired browser like this:

Set-DefaultBrowser cr # cr|ff|ie|op|sa

And you can check that the correct values are set in the registry like this:

(Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\ftp\UserChoice').ProgId
(Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice').ProgId
(Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice').ProgId

I've tested with all 5 browsers with the following versions:

  • Chrome = 39
  • Firefox = 34
  • Internet Explorer = 11
  • Opera = 11
  • Safari = 5

Further Reading: How Does Your Browser Know that It’s Not The Default?

4
  • 5
    I just tried this in Windows 10 and it didn't work. It just triggered the following Windows error: An app caused a problem with your default browser setting, so it was reset to Microsoft Edge.
    – Sam
    Commented Apr 5, 2017 at 23:58
  • 3
    @Sam, it's a known Windows 10 issue. See: winhelponline.com/blog/windows-10-resetting-file-associations or winaero.com/blog/…
    – TechSpud
    Commented Apr 6, 2017 at 6:46
  • I'm just wondering how to add Opera to the lis options.
    – JorgeM
    Commented Oct 31, 2021 at 23:15
  • @jorgemits already there as the last option
    – TechSpud
    Commented Nov 3, 2021 at 0:01
2

In a search for an answer, I found The Kolbicz Blog which shows how to do this with SetDefaultBrowser.exe. Which is much simpler. SetDefaultBrowser – SetDefaultBrowser and SetUserFTA which sets user choices for default programs.

I've taken the code from @TechSpud and made some changes. Also included some functions from Disassambler's Github Win10-Initial-Setup-Script and removed Safari. I made the changes manually to see the changes made in the registry and observed that along with the Browser ProgID a Hash was changed too:

<dl>
<dt>opera</dt><dd>https: 84VcShSmrms=   <br>http: EBgmhN4KR60=  <br>ProgID: OperaStable</dd>
<dt>vivaldi</dt><dd>https: wxeuCoUyJR0= <br>http: Pr6mP1NhKy0=  <br>ProgID: VivaldiHTM.AQHSUMD27WSPRY7GH5RXFKR6WM</dd>
<dt>chrome</dt><dd>https: /vl+ronxuA4=  <br>http: k9Da/QqU74c=  <br>ProgID: ChromeHTML</dd>
<dt>firefox</dt><dd>https: IhKJ36zo2D8= <br>http: yWnRoYQTfbs=  <br>ProgID: FirefoxURL-308046B0AF4A39CB</dd>
<dt>chromium</dt><dd>https: EWoUqQneOv4=    <br>http: Kh+mL2zZByo=  <br>ProgID: ChromiumHTM</dd>
<dt>edge</dt><dd>https: kQz/gLoO7oo=    <br>http: 1cwyZ2KB040=  <br>ProgID: AppX90nv6nhay5n6a98fnetv7tpk64pp35es</dd>
<dt>brave</dt><dd>https: 90HsnuS5S6M=   <br>http: wlBpCu412iI=  <br>ProgID: BraveHTML</dd>
<dt>waterfox</dt><dd>https: j9aaZZ30p3Y=    <br>http: e3oYc6aZ6UA=  <br>ProgID: WaterfoxURL-6F940AC27A98DD61</dd>
<dt>ie</dt><dd>https: m1UWOHOva/s= <br>http: 98qL1nQ8CNQ=  <br>ProgID: IE.HTTPS</dd>
</dl>

I took all the hashes put in the code and tested. Worked!

Function Restart {
    Write-Output "Restarting..."
    Restart-Computer
}
Function ChangeTheDefaultBrowser {
    param($defaultBrowser)

    $regKey = "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\{0}\UserChoice"
    $regKeyHttp = $regKey -f 'http'
    $regKeyHttps = $regKey -f 'https'

    switch -Regex ($defaultBrowser.ToLower()) {
        # Brave Browser
        # https://brave.com
        'bb|brave' {
            Write-Output "`nChanging to Brave as the default browser $ThisUser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId BraveHTML
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash wlBpCu412iI=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId BraveHTML
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash 90HsnuS5S6M=
            break
        }
        # Google Chrome
        # https://www.google.com/chrome/
        'gc|google|chrome' {
            Write-Output "`nChanging to Chrome as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId ChromeHTML
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash k9Da/QqU74c=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId ChromeHTML
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash /vl+ronxuA4=
            break
        }
        # Chromium Browser
        # https://www.chromium.org/getting-involved/download-chromium
        'cb|chromium' {
            Write-Output "`nChanging to Chromium as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId ChromiumHTM
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash Kh+mL2zZByo=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId ChromiumHTM
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash EWoUqQneOv4=
            break
        }
        # Microsoft Edge
        # https://www.microsoft.com/pt-br/windows/microsoft-edge
        'me|edge' {
            Write-Output "`nChanging to Edge as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId AppX90nv6nhay5n6a98fnetv7tpk64pp35es
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash 1cwyZ2KB040=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId AppX90nv6nhay5n6a98fnetv7tpk64pp35es
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash kQz/gLoO7oo=
            break
        }
        # Internet Explorer
        # https://www.microsoft.com/pt-br/download/internet-explorer.aspx
        'ie|internet|explorer' {
            Write-Output "`nChanging to Explorer as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId IE.HTTP
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash 98qL1nQ8CNQ=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId IE.HTTPS
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash m1UWOHOva/s=
            break
        }
        # Mozilla Firefox
        # https://www.mozilla.org/
        'ff|firefox' {
            Write-Output "`nChanging to Firefox as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId FirefoxURL-308046B0AF4A39CB
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash yWnRoYQTfbs=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId FirefoxURL-308046B0AF4A39CB
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash IhKJ36zo2D8=
            break
        }
        # Opera Browser
        # https://www.opera.com/
        'ob|opera' {
            Write-Output "`nChanging to Opera as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId OperaStable
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash EBgmhN4KR60=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId OperaStable
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash 84VcShSmrms=
            break
        }
        # The Waterfox Project
        # https://www.waterfoxproject.org/
        'wf|waterfox' {
            Write-Output "`nChanging to Waterfox as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId WaterfoxURL-6F940AC27A98DD61
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash e3oYc6aZ6UA=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId WaterfoxURL-6F940AC27A98DD61
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash j9aaZZ30p3Y=
            break
        }
        # Vivaldi
        # https://vivaldi.com
        'vi|vivaldi' {
            Write-Output "`nChanging to Vivaldi as the default browser..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId VivaldiHTM.AQHSUMD27WSPRY7GH5RXFKR6WM
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash Pr6mP1NhKy0=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId VivaldiHTM.AQHSUMD27WSPRY7GH5RXFKR6WM
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash wxeuCoUyJR0=
            break
        }
    } 

    # thanks to http://newoldthing.wordpress.com/2007/03/23/how-does-your-browsers-know-that-its-not-the-default-browser/

}
Function RestoreTheDefaultBrowser {
    param($defaultBrowser)

    $regKey = "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\{0}\UserChoice"
    #$HKLMregKey = "Computador\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\{0}\"
    $regKeyHttp = $regKey -f 'http'
    $regKeyHttps = $regKey -f 'https'

    switch -Regex ($defaultBrowser.ToLower()) {
        # Why, Mister Anderson?! Why?!
        # Microsoft Edge
        # https://www.microsoft.com/pt-br/windows/microsoft-edge
        'me|edge' {
            Write-Output "`nChanging back to Edge..."
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name ProgId AppX90nv6nhay5n6a98fnetv7tpk64pp35es
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttp  -name Hash 1cwyZ2KB040=
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name ProgId AppX90nv6nhay5n6a98fnetv7tpk64pp35es
            Set-ItemProperty -Force -PassThru -Verbose $regKeyHttps -name Hash kQz/gLoO7oo=
            break
        }
    }
}

# Uncomment one of the lines below
#ChangeTheDefaultBrowser bb
#ChangeTheDefaultBrowser gc
#ChangeTheDefaultBrowser cb
#ChangeTheDefaultBrowser me
#ChangeTheDefaultBrowser ie
#ChangeTheDefaultBrowser ff
#ChangeTheDefaultBrowser ob
#ChangeTheDefaultBrowser wf
ChangeTheDefaultBrowser vi
Write-Host "`n Changes made for the current user"
# Wait for keypress
Write-Host "`n Is necessary to restart your computer"
WaitForKey
# Restart computer
Restart

BUT after testing again, Edge started to be set as default again and I didn't know why. I thought it was the "marvelous" Windows 10 doing its things, and in a certain way, it is. Every time you set the default browser even being the same browser, the same version, the same machine, the same user profile, doesn't matter if is seconds later, the hash changes. So the code works-ish.

1
  • 1
    You should put the bit about "The Kolbicz Blog" at the top of your answer instead of the bottom for better visibility.
    – yohosuff
    Commented Feb 22, 2019 at 20:01
2

I've found a nice script over here, which you can easily use to change your default browser:

<#
.SYNOPSIS
    Set File Type Association Windows 8/10
.DESCRIPTION
    Set File/Protocol Type Association Default Application Windows 8/10
.NOTES
    Version    : 1.1.0
    Author(s)  : Danyfirex & Dany3j
    Credits    : https://bbs.pediy.com/thread-213954.htm
                 LMongrain - Hash Algorithm PureBasic Version
    License    : MIT License
    Copyright  : 2020 Danysys. <danysys.com>
  
.EXAMPLE
    Get-FTA
    Show All Application Program Id
.EXAMPLE
    Get-FTA .pdf
    Show Default Application Program Id for an Extension
    
.EXAMPLE
    Set-FTA AcroExch.Document.DC .pdf
    Set Acrobat Reader DC as Default .pdf reader
 
.EXAMPLE
    Set-FTA Applications\SumatraPDF.exe .pdf
    Set Sumatra PDF as Default .pdf reader
.EXAMPLE
    Set-PTA ChromeHTML http
    Set Google Chrome as Default for http Protocol
.EXAMPLE
    Register-FTA "C:\SumatraPDF.exe" .pdf -Icon "shell32.dll,100"
    Register Application and Set as Default for .pdf reader
.LINK
    https://github.com/DanysysTeam/PS-SFTA
    
#>

function Get-FTA {
  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $false)]
    [String]
    $Extension
  )

  
  if ($Extension) {
    Write-Verbose "Get File Type Association for $Extension"
    
    $assocFile = (Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice"-ErrorAction SilentlyContinue).ProgId
    Write-Output $assocFile
  }
  else {
    Write-Verbose "Get File Type Association List"

    $assocList = Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\* |
    ForEach-Object {
      $progId = (Get-ItemProperty "$($_.PSParentPath)\$($_.PSChildName)\UserChoice" -ErrorAction SilentlyContinue).ProgId
      if ($progId) {
        "$($_.PSChildName), $progId"
      }
    }
    Write-Output $assocList
  }
  
}


function Register-FTA {
  [CmdletBinding()]
  param (
    [Parameter( Position = 0, Mandatory = $true)]
    [ValidateScript( { Test-Path $_ })]
    [String]
    $ProgramPath,

    [Parameter( Position = 1, Mandatory = $true)]
    [Alias("Protocol")]
    [String]
    $Extension,
    
    [Parameter( Position = 2, Mandatory = $false)]
    [String]
    $ProgId,
    
    [Parameter( Position = 3, Mandatory = $false)]
    [String]
    $Icon
  )

  Write-Verbose "Register Application + Set Association"
  Write-Verbose "Application Path: $ProgramPath"
  if ($Extension.Contains(".")) {
    Write-Verbose "Extension: $Extension"
  }
  else {
    Write-Verbose "Protocol: $Extension"
  }
  
  if (!$ProgId) {
    $ProgId = "SFTA." + [System.IO.Path]::GetFileNameWithoutExtension($ProgramPath).replace(" ", "") + $Extension
  }
  
  $progCommand = """$ProgramPath"" ""%1"""
  Write-Verbose "ApplicationId: $ProgId" 
  Write-Verbose "ApplicationCommand: $progCommand"
  
  try {
    $keyPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\$Extension\OpenWithProgids"
    [Microsoft.Win32.Registry]::SetValue( $keyPath, $ProgId, ([byte[]]@()), [Microsoft.Win32.RegistryValueKind]::None)
    $keyPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\$ProgId\shell\open\command"
    [Microsoft.Win32.Registry]::SetValue($keyPath, "", $progCommand)
    Write-Verbose "Register ProgId and ProgId Command OK"
  }
  catch {
    throw "Register ProgId and ProgId Command FAIL"
  }
  
  Set-FTA -ProgId $ProgId -Extension $Extension -Icon $Icon
}


function Remove-FTA {
  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [Alias("ProgId")]
    [String]
    $ProgramPath,

    [Parameter(Mandatory = $true)]
    [String]
    $Extension
  )
  
  function local:Remove-UserChoiceKey {
    param (
      [Parameter( Position = 0, Mandatory = $True )]
      [String]
      $Key
    )

    $code = @'
    using System;
    using System.Runtime.InteropServices;
    using Microsoft.Win32;
    
    namespace Registry {
      public class Utils {
        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
    
        [DllImport("advapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)]
        private static extern uint RegDeleteKey(UIntPtr hKey, string subKey);
        public static void DeleteKey(string key) {
          UIntPtr hKey = UIntPtr.Zero;
          RegOpenKeyEx((UIntPtr)0x80000001u, key, 0, 0x20019, out hKey);
          RegDeleteKey((UIntPtr)0x80000001u, key);
        }
      }
    }
'@

    try {
      Add-Type -TypeDefinition $code
    }
    catch {}

    try {
      [Registry.Utils]::DeleteKey($Key)
    }
    catch {} 
  } 

  function local:Update-Registry {
    $code = @'
    [System.Runtime.InteropServices.DllImport("Shell32.dll")] 
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
    public static void Refresh() {
        SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero);    
    }
'@ 

    try {
      Add-Type -MemberDefinition $code -Namespace SHChange -Name Notify
    }
    catch {}

    try {
      [SHChange.Notify]::Refresh()
    }
    catch {} 
  }

  if (Test-Path -Path $ProgramPath) {
    $ProgId = "SFTA." + [System.IO.Path]::GetFileNameWithoutExtension($ProgramPath).replace(" ", "") + $Extension
  }
  else {
    $ProgId = $ProgramPath
  }

  try {
    $keyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice"
    Write-Verbose "Remove User UserChoice Key If Exist: $keyPath"
    Remove-UserChoiceKey $keyPath

    $keyPath = "HKCU:\SOFTWARE\Classes\$ProgId"
    Write-Verbose "Remove Key If Exist: $keyPath"
    Remove-Item -Path $keyPath -Recurse -ErrorAction Stop | Out-Null
    
  }
  catch {
    Write-Verbose "Key No Exist: $keyPath"
  }

  try {
    $keyPath = "HKCU:\SOFTWARE\Classes\$Extension\OpenWithProgids"
    Write-Verbose "Remove Property If Exist: $keyPath Property $ProgId"
    Remove-ItemProperty -Path $keyPath -Name $ProgId  -ErrorAction Stop | Out-Null
    
  }
  catch {
    Write-Verbose "Property No Exist: $keyPath Property: $ProgId"
  } 

  Update-Registry
  Write-Output "Removed: $ProgId" 
}


function Set-FTA {

  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [String]
    $ProgId,

    [Parameter(Mandatory = $true)]
    [Alias("Protocol")]
    [String]
    $Extension,
      
    [String]
    $Icon
  )
  
  if (Test-Path -Path $ProgId) {
    $ProgId = "SFTA." + [System.IO.Path]::GetFileNameWithoutExtension($ProgId).replace(" ", "") + $Extension
  }

  Write-Verbose "ProgId: $ProgId"
  Write-Verbose "Extension/Protocol: $Extension"


  function local:Update-RegistryChanges {
    $code = @'
    [System.Runtime.InteropServices.DllImport("Shell32.dll")] 
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
    public static void Refresh() {
        SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero);    
    }
'@ 

    try {
      Add-Type -MemberDefinition $code -Namespace SHChange -Name Notify
    }
    catch {}

    try {
      [SHChange.Notify]::Refresh()
    }
    catch {} 
  }
  

  function local:Set-Icon {
    param (
      [Parameter( Position = 0, Mandatory = $True )]
      [String]
      $ProgId,

      [Parameter( Position = 1, Mandatory = $True )]
      [String]
      $Icon
    )

    try {
      $keyPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\$ProgId\DefaultIcon"
      [Microsoft.Win32.Registry]::SetValue($keyPath, "", $Icon) 
      Write-Verbose "Write Reg Icon OK"
      Write-Verbose "Reg Icon: $keyPath"
    }
    catch {
      Write-Verbose "Write Reg Icon Fail"
    }
  }


  function local:Write-ExtensionKeys {
    param (
      [Parameter( Position = 0, Mandatory = $True )]
      [String]
      $ProgId,

      [Parameter( Position = 1, Mandatory = $True )]
      [String]
      $Extension,

      [Parameter( Position = 2, Mandatory = $True )]
      [String]
      $ProgHash
    )
    

    function local:Remove-UserChoiceKey {
      param (
        [Parameter( Position = 0, Mandatory = $True )]
        [String]
        $Key
      )

      $code = @'
      using System;
      using System.Runtime.InteropServices;
      using Microsoft.Win32;
      
      namespace Registry {
        public class Utils {
          [DllImport("advapi32.dll", SetLastError = true)]
          private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
      
          [DllImport("advapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)]
          private static extern uint RegDeleteKey(UIntPtr hKey, string subKey);
  
          public static void DeleteKey(string key) {
            UIntPtr hKey = UIntPtr.Zero;
            RegOpenKeyEx((UIntPtr)0x80000001u, key, 0, 0x20019, out hKey);
            RegDeleteKey((UIntPtr)0x80000001u, key);
          }
        }
      }
'@
  
      try {
        Add-Type -TypeDefinition $code
      }
      catch {}

      try {
        [Registry.Utils]::DeleteKey($Key)
      }
      catch {} 
    } 

    
    try {
      $keyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice"
      Write-Verbose "Remove Extension UserChoice Key If Exist: $keyPath"
      Remove-UserChoiceKey $keyPath
    }
    catch {
      Write-Verbose "Extension UserChoice Key No Exist: $keyPath"
    }
  

    try {
      $keyPath = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice"
      [Microsoft.Win32.Registry]::SetValue($keyPath, "Hash", $ProgHash)
      [Microsoft.Win32.Registry]::SetValue($keyPath, "ProgId", $ProgId)
      Write-Verbose "Write Reg Extension UserChoice OK"
    }
    catch {
      throw "Write Reg Extension UserChoice FAIL"
    }
  }


  function local:Write-ProtocolKeys {
    param (
      [Parameter( Position = 0, Mandatory = $True )]
      [String]
      $ProgId,

      [Parameter( Position = 1, Mandatory = $True )]
      [String]
      $Protocol,

      [Parameter( Position = 2, Mandatory = $True )]
      [String]
      $ProgHash
    )
      

    try {
      $keyPath = "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Protocol\UserChoice"
      Write-Verbose "Remove Protocol UserChoice Key If Exist: $keyPath"
      Remove-Item -Path $keyPath -Recurse -ErrorAction Stop | Out-Null
    
    }
    catch {
      Write-Verbose "Protocol UserChoice Key No Exist: $keyPath"
    }
  

    try {
      $keyPath = "HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Protocol\UserChoice"
      [Microsoft.Win32.Registry]::SetValue( $keyPath, "Hash", $ProgHash)
      [Microsoft.Win32.Registry]::SetValue($keyPath, "ProgId", $ProgId)
      Write-Verbose "Write Reg Protocol UserChoice OK"
    }
    catch {
      throw "Write Reg Protocol UserChoice FAIL"
    }
    
  }

  
  function local:Get-UserExperience {
    [OutputType([string])]
      
    $userExperienceSearch = "User Choice set via Windows User Experience"
    $user32Path = [Environment]::GetFolderPath([Environment+SpecialFolder]::SystemX86) + "\Shell32.dll"
    $fileStream = [System.IO.File]::Open($user32Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
    $binaryReader = New-Object System.IO.BinaryReader($fileStream)
    [Byte[]] $bytesData = $binaryReader.ReadBytes(5mb)
    $fileStream.Close()
    $dataString = [Text.Encoding]::Unicode.GetString($bytesData)
    $position1 = $dataString.IndexOf($userExperienceSearch)
    $position2 = $dataString.IndexOf("}", $position1)

    Write-Output $dataString.Substring($position1, $position2 - $position1 + 1)
  }
  

  function local:Get-UserSid {
    [OutputType([string])]
    $userSid = ((New-Object System.Security.Principal.NTAccount([Environment]::UserName)).Translate([System.Security.Principal.SecurityIdentifier]).value).ToLower()
    Write-Output $userSid
  }


  function local:Get-HexDateTime {
    [OutputType([string])]

    $now = [DateTime]::Now
    $dateTime = [DateTime]::New($now.Year, $now.Month, $now.Day, $now.Hour, $now.Minute, 0)
    $fileTime = $dateTime.ToFileTime()
    $hi = ($fileTime -shr 32)
    $low = ($fileTime -band 0xFFFFFFFFL)
    $dateTimeHex = ($hi.ToString("X8") + $low.ToString("X8")).ToLower()
    Write-Output $dateTimeHex
  }
  
  function Get-Hash {
    [CmdletBinding()]
    param (
      [Parameter( Position = 0, Mandatory = $True )]
      [string]
      $BaseInfo
    )


    function local:Get-ShiftRight {
      [CmdletBinding()]
      param (
        [Parameter( Position = 0, Mandatory = $true)]
        [long] $iValue, 
            
        [Parameter( Position = 1, Mandatory = $true)]
        [int] $iCount 
      )
    
      if ($iValue -band 0x80000000) {
        Write-Output (( $iValue -shr $iCount) -bxor 0xFFFF0000)
      }
      else {
        Write-Output  ($iValue -shr $iCount)
      }
    }
    

    function local:Get-Long {
      [CmdletBinding()]
      param (
        [Parameter( Position = 0, Mandatory = $true)]
        [byte[]] $Bytes,
    
        [Parameter( Position = 1)]
        [int] $Index = 0
      )
    
      Write-Output ([BitConverter]::ToInt32($Bytes, $Index))
    }
    

    function local:Convert-Int32 {
      param (
        [Parameter( Position = 0, Mandatory = $true)]
        $Value
      )
    
      [byte[]] $bytes = [BitConverter]::GetBytes($Value)
      return [BitConverter]::ToInt32( $bytes, 0) 
    }

    [Byte[]] $bytesBaseInfo = [System.Text.Encoding]::Unicode.GetBytes($baseInfo) 
    $bytesBaseInfo += 0x00, 0x00  
    
    $MD5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    [Byte[]] $bytesMD5 = $MD5.ComputeHash($bytesBaseInfo)
    
    $lengthBase = ($baseInfo.Length * 2) + 2 
    $length = (($lengthBase -band 4) -le 1) + (Get-ShiftRight $lengthBase  2) - 1
    $base64Hash = ""

    if ($length -gt 1) {
    
      $map = @{PDATA = 0; CACHE = 0; COUNTER = 0 ; INDEX = 0; MD51 = 0; MD52 = 0; OUTHASH1 = 0; OUTHASH2 = 0;
        R0 = 0; R1 = @(0, 0); R2 = @(0, 0); R3 = 0; R4 = @(0, 0); R5 = @(0, 0); R6 = @(0, 0); R7 = @(0, 0)
      }
    
      $map.CACHE = 0
      $map.OUTHASH1 = 0
      $map.PDATA = 0
      $map.MD51 = (((Get-Long $bytesMD5) -bor 1) + 0x69FB0000L)
      $map.MD52 = ((Get-Long $bytesMD5 4) -bor 1) + 0x13DB0000L
      $map.INDEX = Get-ShiftRight ($length - 2) 1
      $map.COUNTER = $map.INDEX + 1
    
      while ($map.COUNTER) {
        $map.R0 = Convert-Int32 ((Get-Long $bytesBaseInfo $map.PDATA) + [long]$map.OUTHASH1)
        $map.R1[0] = Convert-Int32 (Get-Long $bytesBaseInfo ($map.PDATA + 4))
        $map.PDATA = $map.PDATA + 8
        $map.R2[0] = Convert-Int32 (($map.R0 * ([long]$map.MD51)) - (0x10FA9605L * ((Get-ShiftRight $map.R0 16))))
        $map.R2[1] = Convert-Int32 ((0x79F8A395L * ([long]$map.R2[0])) + (0x689B6B9FL * (Get-ShiftRight $map.R2[0] 16)))
        $map.R3 = Convert-Int32 ((0xEA970001L * $map.R2[1]) - (0x3C101569L * (Get-ShiftRight $map.R2[1] 16) ))
        $map.R4[0] = Convert-Int32 ($map.R3 + $map.R1[0])
        $map.R5[0] = Convert-Int32 ($map.CACHE + $map.R3)
        $map.R6[0] = Convert-Int32 (($map.R4[0] * [long]$map.MD52) - (0x3CE8EC25L * (Get-ShiftRight $map.R4[0] 16)))
        $map.R6[1] = Convert-Int32 ((0x59C3AF2DL * $map.R6[0]) - (0x2232E0F1L * (Get-ShiftRight $map.R6[0] 16)))
        $map.OUTHASH1 = Convert-Int32 ((0x1EC90001L * $map.R6[1]) + (0x35BD1EC9L * (Get-ShiftRight $map.R6[1] 16)))
        $map.OUTHASH2 = Convert-Int32 ([long]$map.R5[0] + [long]$map.OUTHASH1)
        $map.CACHE = ([long]$map.OUTHASH2)
        $map.COUNTER = $map.COUNTER - 1
      }

      [Byte[]] $outHash = @(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
      [byte[]] $buffer = [BitConverter]::GetBytes($map.OUTHASH1)
      $buffer.CopyTo($outHash, 0)
      $buffer = [BitConverter]::GetBytes($map.OUTHASH2)
      $buffer.CopyTo($outHash, 4)
    
      $map = @{PDATA = 0; CACHE = 0; COUNTER = 0 ; INDEX = 0; MD51 = 0; MD52 = 0; OUTHASH1 = 0; OUTHASH2 = 0;
        R0 = 0; R1 = @(0, 0); R2 = @(0, 0); R3 = 0; R4 = @(0, 0); R5 = @(0, 0); R6 = @(0, 0); R7 = @(0, 0)
      }
    
      $map.CACHE = 0
      $map.OUTHASH1 = 0
      $map.PDATA = 0
      $map.MD51 = ((Get-Long $bytesMD5) -bor 1)
      $map.MD52 = ((Get-Long $bytesMD5 4) -bor 1)
      $map.INDEX = Get-ShiftRight ($length - 2) 1
      $map.COUNTER = $map.INDEX + 1

      while ($map.COUNTER) {
        $map.R0 = Convert-Int32 ((Get-Long $bytesBaseInfo $map.PDATA) + ([long]$map.OUTHASH1))
        $map.PDATA = $map.PDATA + 8
        $map.R1[0] = Convert-Int32 ($map.R0 * [long]$map.MD51)
        $map.R1[1] = Convert-Int32 ((0xB1110000L * $map.R1[0]) - (0x30674EEFL * (Get-ShiftRight $map.R1[0] 16)))
        $map.R2[0] = Convert-Int32 ((0x5B9F0000L * $map.R1[1]) - (0x78F7A461L * (Get-ShiftRight $map.R1[1] 16)))
        $map.R2[1] = Convert-Int32 ((0x12CEB96DL * (Get-ShiftRight $map.R2[0] 16)) - (0x46930000L * $map.R2[0]))
        $map.R3 = Convert-Int32 ((0x1D830000L * $map.R2[1]) + (0x257E1D83L * (Get-ShiftRight $map.R2[1] 16)))
        $map.R4[0] = Convert-Int32 ([long]$map.MD52 * ([long]$map.R3 + (Get-Long $bytesBaseInfo ($map.PDATA - 4))))
        $map.R4[1] = Convert-Int32 ((0x16F50000L * $map.R4[0]) - (0x5D8BE90BL * (Get-ShiftRight $map.R4[0] 16)))
        $map.R5[0] = Convert-Int32 ((0x96FF0000L * $map.R4[1]) - (0x2C7C6901L * (Get-ShiftRight $map.R4[1] 16)))
        $map.R5[1] = Convert-Int32 ((0x2B890000L * $map.R5[0]) + (0x7C932B89L * (Get-ShiftRight $map.R5[0] 16)))
        $map.OUTHASH1 = Convert-Int32 ((0x9F690000L * $map.R5[1]) - (0x405B6097L * (Get-ShiftRight ($map.R5[1]) 16)))
        $map.OUTHASH2 = Convert-Int32 ([long]$map.OUTHASH1 + $map.CACHE + $map.R3) 
        $map.CACHE = ([long]$map.OUTHASH2)
        $map.COUNTER = $map.COUNTER - 1
      }
    
      $buffer = [BitConverter]::GetBytes($map.OUTHASH1)
      $buffer.CopyTo($outHash, 8)
      $buffer = [BitConverter]::GetBytes($map.OUTHASH2)
      $buffer.CopyTo($outHash, 12)
    
      [Byte[]] $outHashBase = @(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
      $hashValue1 = ((Get-Long $outHash 8) -bxor (Get-Long $outHash))
      $hashValue2 = ((Get-Long $outHash 12) -bxor (Get-Long $outHash 4))
    
      $buffer = [BitConverter]::GetBytes($hashValue1)
      $buffer.CopyTo($outHashBase, 0)
      $buffer = [BitConverter]::GetBytes($hashValue2)
      $buffer.CopyTo($outHashBase, 4)
      $base64Hash = [Convert]::ToBase64String($outHashBase) 
    }

    Write-Output $base64Hash
  }

  Write-Verbose "Getting Hash For $ProgId   $Extension"

  $userSid = Get-UserSid
  $userExperience = Get-UserExperience
  $userDateTime = Get-HexDateTime
  Write-Debug "UserDateTime: $userDateTime"
  Write-Debug "UserSid: $userSid"
  Write-Debug "UserExperience: $userExperience"

  $baseInfo = "$Extension$userSid$ProgId$userDateTime$userExperience".ToLower()
  Write-Verbose "baseInfo: $baseInfo"

  $progHash = Get-Hash $baseInfo
  Write-Verbose "Hash: $progHash"
  
  #Handle Extension Or Protocol
  if ($Extension.Contains(".")) {
    Write-Verbose "Write Registry Extension: $Extension"
    Write-ExtensionKeys $ProgId $Extension $progHash

  }
  else {
    Write-Verbose "Write Registry Protocol: $Extension"
    Write-ProtocolKeys $ProgId $Extension $progHash
  }

   
  if ($Icon) {
    Write-Verbose  "Set Icon: $Icon"
    Set-Icon $ProgId $Icon
  }

  Update-RegistryChanges 

}

function Set-PTA {
  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [String]
    $ProgId,

    [Parameter(Mandatory = $true)]
    [String]
    $Protocol,
      
    [String]
    $Icon
  )

  Set-FTA -ProgId $ProgId -Protocol $Protocol -Icon $Icon
}

Set-PTA ChromeHTML http
Set-PTA ChromeHTML https
Set-FTA ChromeHTML .pdf
Set-FTA ChromeHTML .htm
Set-FTA ChromeHTML .html

You can find the identifier for Chrome, Edge, Firefox etc. when you have a look at this regkey: HKEY_CLASSES_ROOT\.html\OpenWithProgids

2

You can use the below PowerShell script to change the default browser to Mozilla:

function Set-DefaultBrowser {
    Add-Type -AssemblyName 'System.Windows.Forms'
    Start-Process $env:windir\system32\control.exe -LoadUserProfile -Wait `
        -ArgumentList '/name Microsoft.DefaultPrograms /page pageDefaultProgram\pageAdvancedSettings?pszAppName=Firefox-308046B0AF4A39CB'
    Sleep 2
    [System.Windows.Forms.SendKeys]::SendWait("{TAB}{TAB}{DOWN}{DOWN} {DOWN} {DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN} {DOWN} {TAB} ")
}
Set-DefaultBrowser
1

The following worked for me:

$chromePath = "${Env:ProgramFiles(x86)}\Google\Chrome\Application\" 
$chromeApp = "chrome.exe"
$chromeCommandArgs = "--make-default-browser"
& "$chromePath$chromeApp" $chromeCommandArgs
1
  • Yeah I tried that. I'm wondering now if it's a problem in Chrome/Win8. I've got a fresh install of Win8 and I used Chocolatey to install chrome cinstm GoogleChrome Commented Jul 8, 2013 at 22:45
1

The following code works for GCP Windows 10 server image:

function Set-DefaultBrowser {
    Add-Type -AssemblyName 'System.Windows.Forms'
    Start-Process $env:windir\system32\control.exe -LoadUserProfile -Wait `
        -ArgumentList '/name Microsoft.DefaultPrograms /page pageDefaultProgram\pageAdvancedSettings?pszAppName=Firefox-308046B0AF4A39CB'
    Sleep 10
    [System.Windows.Forms.SendKeys]::SendWait("{TAB}{TAB}{TAB}{TAB}{TAB} {ENTER}{ENTER} ")
}

Set-DefaultBrowser
1
  • I made the code shorter/simpler: start ms-settings:defaultapps Sleep 10 # wait 10sec for it to open # tabs down to default browser, & selects the first one, would have to enter {DOWN} however many times to select another browser, its in alphabatical format [System.Windows.Forms.SendKeys]::SendWait("{TAB 5} {ENTER 2}") Sleep 2 # wait 2sec then press Alt+F4 to close Settings. If I didn't wait the default browser didn't get changed [System.Windows.Forms.SendKeys]::SendWait("%{F4}")
    – gregg
    Commented Feb 24, 2021 at 16:40
0

WinSAT is the Windows System Assessment Tool. It measures system performance: CPU, memory, graphics, and hard disk speeds and comes up with a single number from 1 to 7.9, that supposed to represent your systems performance. Software publishers (mainly graphics intensive games) were supposed to publish the minimum WinSAT score to get a good experience from their game. (This was the plan prior to Win7, but I don't to what extent it is actually used).

Anyway you can go to the Control Panel, System and you should see "Rating" in the middle of the window. You can click the message next to it to get a rating.

I think Chrome is complaining about not having a rating. (Although it is a big ambiguous whether it is Chrome or CMD) Try rating your system and see if it works.

Not the answer you're looking for? Browse other questions tagged or ask your own question.