Skip to content

Instantly share code, notes, and snippets.

@pszemraj
Last active June 7, 2026 14:30
Show Gist options
  • Select an option

  • Save pszemraj/af5823c756a4cb225d42f364d4622f89 to your computer and use it in GitHub Desktop.

Select an option

Save pszemraj/af5823c756a4cb225d42f364d4622f89 to your computer and use it in GitHub Desktop.
use https://setuserfta.com/ to reassign any extensions that would be opened in Edge to a browser of your choice
<#
.SYNOPSIS
Finds every file type and protocol currently assigned to Microsoft Edge
and reassigns them all to your preferred browser using SetUserFTA.
.DESCRIPTION
Windows protects file associations with a hash -- you can't just edit the
registry. SetUserFTA reverse-engineers that hash so it can set associations
from the command line.
This script:
1. Locates (or downloads) SetUserFTA
2. Detects installed browsers and lets you pick one
3. Finds ALL extensions/protocols currently mapped to any Edge ProgID
4. Reassigns every single one to your chosen browser
.NOTES
Run from a normal (non-admin) PowerShell terminal.
SetUserFTA operates per-user -- no admin required.
#>
$ErrorActionPreference = "Stop"
# --- 1. Ensure SetUserFTA is available ----------------------------------------
$setUserFtaDir = "$env:LOCALAPPDATA\SetUserFTA"
$setUserFtaExe = Join-Path $setUserFtaDir "SetUserFTA.exe"
if (-not (Test-Path $setUserFtaExe)) {
Write-Host "`n[*] SetUserFTA not found. Attempting download..." -ForegroundColor Cyan
New-Item -ItemType Directory -Path $setUserFtaDir -Force | Out-Null
$zipUrl = "https://kolbi.cz/SetUserFTA.zip"
$zipPath = Join-Path $setUserFtaDir "SetUserFTA.zip"
try {
Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath -UseBasicParsing
Expand-Archive -Path $zipPath -DestinationPath $setUserFtaDir -Force
Remove-Item $zipPath -Force
# The exe may be nested in a subfolder after extraction
$found = Get-ChildItem -Path $setUserFtaDir -Recurse -Filter "SetUserFTA.exe" |
Where-Object { $_.FullName -notmatch "x86" } |
Select-Object -First 1
if ($found -and $found.FullName -ne $setUserFtaExe) {
Copy-Item $found.FullName -Destination $setUserFtaExe -Force
}
}
catch {
Write-Host "`n[!] Auto-download failed." -ForegroundColor Red
Write-Host " Download SetUserFTA from: https://setuserfta.com/download-setuserfta/" -ForegroundColor Yellow
Write-Host " Place SetUserFTA.exe in: $setUserFtaDir" -ForegroundColor Yellow
exit 1
}
}
if (-not (Test-Path $setUserFtaExe)) {
Write-Host "[!] SetUserFTA.exe not found at $setUserFtaExe" -ForegroundColor Red
Write-Host " Download it from https://setuserfta.com/download-setuserfta/ and place it there." -ForegroundColor Yellow
exit 1
}
Write-Host "[OK] SetUserFTA found: $setUserFtaExe" -ForegroundColor Green
# --- 2. Detect installed browsers ---------------------------------------------
# Map of display name -> ProgID used for file associations
$knownBrowsers = [ordered]@{
"Google Chrome" = "ChromeHTML"
"Mozilla Firefox" = $null # Firefox ProgIDs have a per-install suffix; detected below
"Brave" = "BraveHTML"
"Vivaldi" = "VivaldiHTM"
"Opera" = "OperaStable"
"Opera GX" = "OperaGXStable"
}
# Detect Firefox's actual ProgID (it includes a hash like FirefoxHTML-308046B0AF4A39CB)
$firefoxProgId = Get-ChildItem "HKCU:\Software\Classes" -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -match "^FirefoxHTML-" } |
Select-Object -First 1 -ExpandProperty PSChildName
if (-not $firefoxProgId) {
$firefoxProgId = Get-ChildItem "HKLM:\Software\Classes" -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -match "^FirefoxHTML-" } |
Select-Object -First 1 -ExpandProperty PSChildName
}
if ($firefoxProgId) {
$knownBrowsers["Mozilla Firefox"] = $firefoxProgId
}
# Filter to only browsers that are actually registered on this system
$availableBrowsers = [ordered]@{}
foreach ($name in $knownBrowsers.Keys) {
$progId = $knownBrowsers[$name]
if (-not $progId) { continue }
$exists = (Test-Path "HKCU:\Software\Classes\$progId") -or
(Test-Path "HKLM:\Software\Classes\$progId")
if ($exists) {
$availableBrowsers[$name] = $progId
}
}
if ($availableBrowsers.Count -eq 0) {
Write-Host "`n[!] No supported browsers detected." -ForegroundColor Red
Write-Host " Install Chrome, Firefox, Brave, Vivaldi, or Opera first." -ForegroundColor Yellow
exit 1
}
# --- 3. Let user pick ---------------------------------------------------------
Write-Host "`nDetected browsers:" -ForegroundColor Cyan
$i = 1
$browserList = @($availableBrowsers.GetEnumerator())
foreach ($entry in $browserList) {
Write-Host " [$i] $($entry.Key) (ProgID: $($entry.Value))" -ForegroundColor White
$i++
}
do {
$choice = Read-Host "`nSelect browser [1-$($browserList.Count)]"
} while ($choice -notmatch '^\d+$' -or [int]$choice -lt 1 -or [int]$choice -gt $browserList.Count)
$targetName = $browserList[[int]$choice - 1].Key
$targetProgId = $browserList[[int]$choice - 1].Value
Write-Host "`n[*] Target: $targetName ($targetProgId)" -ForegroundColor Green
# --- 4. Find ALL Edge associations --------------------------------------------
# Known Edge ProgIDs -- there are several
$edgeProgIds = @(
"MSEdgeHTM"
"MSEdgePDF"
"MSEdgeMHT"
"AppXq0fevzme2pys62n3e0fbqa7peapykr8v" # Edge UWP protocol handler
"AppXd4nrz8ff68srnhf9t5a8sbjyar1cr723" # Edge PDF (UWP variant)
"AppXde74bfzw9j31bzhcvsrxsyjnhhbq66cs" # Edge HTML (UWP variant)
"AppX4hxtad77fbk3jkkeerkrm0ze94wjf3s9" # Edge MHT (UWP variant)
"AppXc6xm04by1gqrb4hhdg9g6tzk09eajvb2" # Edge SVG (UWP variant)
"AppXe1yx5t83bv01c2c6g01m22bhx10ns8y2" # Edge XML (UWP variant)
)
Write-Host "`n[*] Scanning all current file associations for Edge ProgIDs..." -ForegroundColor Cyan
# Get ALL current associations
$allAssociations = & $setUserFtaExe get 2>&1 | Where-Object { $_ -match "," }
$edgeAssociations = @()
foreach ($line in $allAssociations) {
# Format: .ext, ProgID or protocol, ProgID
if ($line -match "^(.+?),\s*(.+)$") {
$ext = $Matches[1].Trim()
$progId = $Matches[2].Trim()
if ($progId -in $edgeProgIds -or $progId -match "(?i)edge") {
$edgeAssociations += [PSCustomObject]@{
Extension = $ext
CurrentProgId = $progId
}
}
}
}
if ($edgeAssociations.Count -eq 0) {
Write-Host "`n[*] No file associations currently pointing to Edge. Nothing to do." -ForegroundColor Green
exit 0
}
Write-Host "`n[!] Found $($edgeAssociations.Count) associations mapped to Edge:" -ForegroundColor Yellow
foreach ($assoc in $edgeAssociations) {
Write-Host (" {0} -> {1}" -f $assoc.Extension, $assoc.CurrentProgId) -ForegroundColor Gray
}
# --- 5. Reassign everything ---------------------------------------------------
Write-Host "`n[*] Reassigning all to $targetName ($targetProgId)...`n" -ForegroundColor Cyan
# Some extensions need a different ProgID (Firefox uses FirefoxURL-* for protocols)
$targetUrlProgId = $targetProgId
if ($targetName -eq "Mozilla Firefox") {
$firefoxUrlProgId = $targetProgId -replace "^FirefoxHTML-", "FirefoxURL-"
$urlExists = (Test-Path "HKCU:\Software\Classes\$firefoxUrlProgId") -or
(Test-Path "HKLM:\Software\Classes\$firefoxUrlProgId")
if ($urlExists) {
$targetUrlProgId = $firefoxUrlProgId
}
}
$protocols = @("http", "https", "ftp", "mailto", "microsoft-edge", "microsoft-edge-holographic",
"read", "ie.http", "ie.https", "ie.ftp")
$successCount = 0
$failCount = 0
foreach ($assoc in $edgeAssociations) {
$ext = $assoc.Extension
# Use URL-type ProgID for protocols, HTML-type for file extensions
if ($ext -in $protocols -or $ext -notmatch "^\.") {
$useProgId = $targetUrlProgId
} else {
$useProgId = $targetProgId
}
$result = & $setUserFtaExe $ext $useProgId 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host (" [OK] {0} -> {1}" -f $ext, $useProgId) -ForegroundColor Green
$successCount++
} else {
Write-Host (" [FAIL] {0} -> {1} : {2}" -f $ext, $useProgId, $result) -ForegroundColor Red
$failCount++
}
}
# --- 6. Summary ---------------------------------------------------------------
Write-Host "`n----------------------------------------" -ForegroundColor DarkGray
Write-Host "Done. $successCount reassigned, $failCount failed." -ForegroundColor Cyan
if ($failCount -gt 0) {
Write-Host "Some failures are expected -- Windows enforces certain protocol handlers." -ForegroundColor Yellow
Write-Host "For those, MSEdgeRedirect (github.com/rcmaehl/MSEdgeRedirect) handles the rest." -ForegroundColor Yellow
}
Write-Host ""
@pszemraj

pszemraj commented Jun 7, 2026

Copy link
Copy Markdown
Author

Example run on my machine

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment