Skip to content

Instantly share code, notes, and snippets.

@sba923
Last active August 20, 2025 13:08
Show Gist options
  • Save sba923/d5406e7fded598b9c1131ddf9f099564 to your computer and use it in GitHub Desktop.
Save sba923/d5406e7fded598b9c1131ddf9f099564 to your computer and use it in GitHub Desktop.
Update Selenium drivers found on the PATH
# this is one of Stéphane BARIZIEN's public domain scripts
# the most recent version can be found at:
# https://gist.github.com/sba923/d5406e7fded598b9c1131ddf9f099564#file-update-seleniumdriver-ps1
[CmdletBinding()]
param(
[Parameter(ParameterSetName = 'InstallIfMissing', Mandatory = $true)][switch] $InstallIfMissing,
[Parameter(ParameterSetName = 'InstallIfMissing', Mandatory = $true)][string] $Destination,
[Parameter(ParameterSetName = 'NoParameters')] [switch] $_NeverUseThisParameter,
[switch]$ClearCache
)
# requires the scripts in https://gist.github.com/sba923/d0d5ad16f2b12d7785adf830b0395dc2
$seleniummanager = whence -q selenium-manager
if ($null -eq $seleniummanager)
{
throw ("'selenium-manager' not found on PATH")
}
# make sure selenium-manager is the latest version
$tmpfile = Join-Path -Path $env:TEMP -ChildPath 'selenium-manager.exe'
# determine URL for latest production-ready, released selenium-manager.exe
# (see https://github.com/SeleniumHQ/selenium/issues/11694#issuecomment-1927884476)
Write-Verbose("Determining latest version of 'selenium-manager.exe'...")
$url = @(((Invoke-WebRequest -Uri 'https://github.com/SeleniumHQ/selenium/blob/selenium-4.17.0/common/selenium_manager.bzl').Content -split "`n") -match '\.exe' -replace '.*(https://[^"]+selenium-manager-windows\.exe).*', '$1')[0]
Write-Verbose ("Retrieving latest 'selenium-manager.exe' from '{0}'..." -f $url)
Invoke-WebRequest -Uri $url -OutFile $tmpfile
if (!(Test-Path -LiteralPath $tmpfile))
{
throw ("Cannot retrieve latest 'selenium-manager.exe' from '{0}'" -f $url)
}
if ((Get-FileHash -Path $tmpfile).Hash -ne ((Get-FileHash -Path $seleniummanager).Hash))
{
Write-Verbose ("Updating '{0}'..." -f $seleniummanager)
Copy-Item -Destination $seleniummanager -Path $tmpfile
}
else
{
Write-Verbose ("'{0}' is already the latest version of 'selenium-manager.exe'" -f $seleniummanager)
}
Remove-Item -Path $tmpfile
Write-Verbose ("Using {0}" -f (selenium-manager --version))
if ($ClearCache)
{
Remove-Item -Force -Recurse -LiteralPath (Join-Path -Path $env:USERPROFILE -ChildPath ".cache\selenium") -Verbose:($PSBoundParameters.ContainsKey('Verbose'))
}
function ObjectToString($Object, $Prefix = '')
{
if ($Object -is 'Object[]')
{
$string = ''
for ($index = 0; $index -lt $object.Count; $index++)
{
$string += ("`n{2}[{0}]: {1}" -f $index, (ObjectToString -Object $Object[$index] -Prefix ("{0}[{1}]" -f $Prefix, $index)), $Prefix)
}
}
elseif ($Object -is 'PSCustomObject')
{
$string = ''
foreach ($propertyName in $Object.PSObject.Properties.Name)
{
$string += ("`n{0}" -f (ObjectToString -Object $Object.$propertyName -Prefix ($Prefix + '.' + $propertyName)))
}
}
else
{
$string = ("`n{1}:{0}" -f $Object, $Prefix)
}
return ($string -replace '\n{2,}', "`n")
}
# direct download of Selenium driver for Edge when selenium-manager.exe fails to retrieve it
function DownloadEdgeDriver
{
Write-Verbose("Failed to retrieve Selenium driver for '{0}': selenium-manager returned:`n{1}" -f $browser, ((ObjectToString -Object $sm) -replace '^\n+'))
if ($Destination -eq '')
{
$olddriveronpath = whence -q $drivers[$browser]
if ($null -eq $olddriveronpath)
{
$olddriveronpath = whence -q 'MicrosoftWebDriver.exe'
if ($null -eq $olddriveronpath)
{
throw ("'{0}' not found on PATH, cannot determine where to download the new Selenium driver for Edge to" -f $drivers[$browser])
}
}
$script:Destination = dirname $olddriveronpath
}
$baseUrl = "https://msedgedriver.microsoft.com/"
Write-Verbose("Retrieving the Selenium driver for Edge from {0}" -f $baseUrl)
# Detect installed Edge version
$edgePath = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
if (-not (Test-Path $edgePath))
{
throw "Edge executable not found at $edgePath"
}
$edgeVersion = (Get-Item $edgePath).VersionInfo.ProductVersion
Write-Verbose "Detected Edge version: $edgeVersion"
# Construct download URL
$driverZip = "edgedriver_win64.zip"
$driverUrl = "$baseUrl$edgeVersion/$driverZip"
# Test if the driver exists at the URL computed above
try
{
$response = Invoke-WebRequest -Uri $driverUrl -Method Head -ErrorAction Stop
Write-Verbose "WebDriver found for version $edgeVersion"
$null = $response # get rid of PSSA warning
}
catch
{
throw "WebDriver not found for version $edgeVersion. It may not be published yet."
}
$zipPath = Join-Path -Path $env:TEMP -ChildPath $driverZip
# Download and extract
Write-Verbose ("Downloading Selenium driver for Edge from '{0}'..." -f $driverUrl)
Invoke-WebRequest -Uri $driverUrl -OutFile $zipPath
Write-Verbose "Extracting driver..."
Expand-Archive -Path $zipPath -DestinationPath $script:Destination -Force | Out-Null
Remove-Item -LiteralPath $zipPath -Force
Write-Verbose "Selenium driver for Edge downloaded and extracted to: $script:Destination"
}
$drivers = @{
'edge' = 'msedgedriver.exe'
'chrome' = 'chromedriver.exe'
'firefox' = 'geckodriver.exe'
}
foreach ($browser in $drivers.Keys)
{
Write-Verbose ("Updating Selenium driver '{0}' for browser '{1}'" -f $drivers[$browser], $browser)
$sm = selenium-manager --browser $browser --output JSON | ConvertFrom-JSON
# need to join all lines from selenium-manager's output to account for possible multiple-line output with e.g. WARN
$olddriveronpath = $null
if ($sm.result.code -eq 0)
{
$smdriver = $sm.result.driver_path
$warningitems = @($sm.logs | Where-Object { $_.level -eq 'WARN' })
if ($warningitems.Count -gt 0)
{
$warnings = $warningitems.message -join "`n"
}
else
{
$warnings = ''
}
if ($warnings -match 'it is advised to delete the driver in PATH and retry')
{
Write-Verbose ("selenium-manager has emitted the 'it is advised to delete the driver in PATH and retry' warning, deleting '{0}' and retrying" -f $sm.result.driver_path)
$olddriveronpath = whence -q $drivers[$browser]
if ($null -eq $olddriveronpath)
{
Write-Host -ForegroundColor Magenta ("selenium-manager warning was unexpected: no {0} on PATH" -f $drivers[$browser])
}
else
{
Remove-Item -LiteralPath $olddriveronpath -Force -ErrorAction Stop -Verbose:($PSBoundParameters.ContainsKey('Verbose'))
$sm = selenium-manager --browser $browser --output JSON | ConvertFrom-JSON
if ($sm.result.code -ne 0)
{
if ($browser -eq 'edge')
{
DownloadEdgeDriver
}
else
{
throw ("selenium-manager failed: {0}" -f ($sm.logs -join "`n"))
}
}
}
}
elseif ($warnings -match 'error')
{
Write-Verbose ("selenium-manager has emitted a warning with the word 'error', deleting '{0}' and retrying" -f $sm.result.driver_path)
$olddriveronpath = whence -q $drivers[$browser]
if ($null -eq $olddriveronpath)
{
Write-Host -ForegroundColor Magenta ("selenium-manager warning was unexpected: no {0} on PATH" -f $drivers[$browser])
}
else
{
Remove-Item -LiteralPath $olddriveronpath -Force -ErrorAction Stop -Verbose:($PSBoundParameters.ContainsKey('Verbose'))
$sm = selenium-manager --browser $browser --output JSON | ConvertFrom-JSON
if ($sm.result.code -ne 0)
{
if ($browser -eq 'edge')
{
DownloadEdgeDriver
$smdriver = Join-Path -Path $Destination -ChildPath 'msedgedriver.exe'
}
else
{
throw ("selenium-manager failed: {0}" -f ((ObjectToString -Object $sm) -replace '^\n+'))
}
}
}
}
Write-Verbose ("Selenium driver '{0}' is available" -f $smdriver)
$sdriver = whence -q $drivers[$browser]
if ($null -ne $sdriver)
{
$smdriver_i = Get-Item -LiteralPath $smdriver
$sdriver_i = Get-Item -LiteralPath $sdriver
if (($null -eq $smdriver_i.VersionInfo.FileVersion) -or ($null -eq $sdriver_i.VersionInfo.FileVersion))
{
if ((Get-FileHash $sdriver_i.FullName).Hash -ne (Get-FileHash $smdriver_i.FullName).Hash)
{
Write-Host -ForegroundColor Yellow ("Updating '{0}' from {1} to {2}" -f $drivers[$browser], $sdriver_i.FullName, $smdriver_i.FullName)
Copy-Item -Verbose -LiteralPath $smdriver -Destination $sdriver
}
else
{
Write-Verbose ("'{0}' is already up to date" -f $sdriver)
}
}
else
{
if ($smdriver_i.VersionInfo.FileVersion -gt $sdriver_i.VersionInfo.FileVersion)
{
Write-Host -ForegroundColor Yellow ("Updating '{0}' from {1} to {2}" -f $drivers[$browser], $sdriver_i.VersionInfo.FileVersion, $smdriver_i.VersionInfo.FileVersion)
Copy-Item -Verbose -LiteralPath $smdriver -Destination $sdriver
}
else
{
Write-Verbose ("'{0}' is already up to date: version {1}" -f $sdriver, $sdriver_i.VersionInfo.FileVersion)
}
}
if ($browser -eq 'edge')
{
$mswebdriver = Join-Path -Path $sdriver_i.Directory -ChildPath 'MicrosoftWebDriver.exe'
if (Test-Path -LiteralPath $mswebdriver)
{
if (Get-Process -Name MicrosoftWebDriver -ErrorAction SilentlyContinue)
{
Stop-Process -name MicrosoftWebDriver -ErrorAction SilentlyContinue
}
}
Copy-Item -Verbose -Destination $mswebdriver -LiteralPath $sdriver
}
}
else
{
if ($InstallIfMissing -or ($null -ne $olddriveronpath))
{
if ($null -eq $olddriveronpath)
{
$sdriver = Join-Path -Path $Destination -ChildPath $drivers[$browser]
}
else
{
$sdriver = $olddriveronpath
$Destination = Split-Path -Path $olddriveronpath -Parent
}
Write-Host -ForegroundColor Yellow ("Installing '{0}' as '{1}'" -f $drivers[$browser], $sdriver)
Copy-Item -Verbose -LiteralPath $smdriver -Destination $sdriver
if ($browser -eq 'edge')
{
$mswebdriver = Join-Path -Path $Destination -ChildPath 'MicrosoftWebDriver.exe'
if (Test-Path -LiteralPath $mswebdriver)
{
if (Get-Process -Name MicrosoftWebDriver -ErrorAction SilentlyContinue)
{
Stop-Process -name MicrosoftWebDriver -ErrorAction SilentlyContinue
}
}
Copy-Item -Verbose -Destination $mswebdriver -LiteralPath $sdriver
}
}
else
{
Write-Error ("'{0}' not on PATH" -f $drivers[$browser])
}
}
}
else
{
if ($browser -eq 'edge')
{
DownloadEdgeDriver
}
else
{
Write-Error ("Failed to retrieve Selenium driver for '{0}': selenium-manager returned:`n{1}" -f $browser, ((ObjectToString -Object $sm) -replace '^\n+'))
}
}
}
@sba923
Copy link
Author

sba923 commented Mar 17, 2023

  • Added support for -Verbose
  • remove MicrosoftWebDriver.exe if present alongside msedgedriver.exe

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