Skip to content

Instantly share code, notes, and snippets.

@sba923
Last active March 22, 2026 19:25
Show Gist options
  • Select an option

  • Save sba923/d5406e7fded598b9c1131ddf9f099564 to your computer and use it in GitHub Desktop.

Select an option

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
# cSpell: ignore Stéphane BARIZIEN's PSSA edgedriver
$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://raw.githubusercontent.com/SeleniumHQ/selenium/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 DownloadEdgeDriverDriver
{
$smCode = if ($null -ne $sm -and $null -ne $sm.result) { $sm.result.code } else { $null }
$smMessage = if ($null -ne $sm -and $null -ne $sm.result) { $sm.result.message } else { '' }
Write-Verbose("Using direct Edge WebDriver download fallback for '{0}' (selenium-manager code={1}, message='{2}')" -f $browser, $smCode, $smMessage)
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
}
$baseUrls = @(
"https://msedgedriver.microsoft.com/"
"https://msedgeDriver.microsoft.com/"
)
Write-Verbose("Retrieving the Selenium driver for Edge from {0}" -f ($baseUrls -join ', '))
# 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
$driverZips = @(
"edgedriver_win64.zip"
"edgeDriver_win64.zip"
)
$driverZip = $driverZips[0]
$majorVersion = ($edgeVersion -split '\.')[0]
$driverVersionsToTry = @($edgeVersion)
if ($majorVersion)
{
try
{
$latestForMajor = $null
foreach ($latestBaseUrl in $baseUrls)
{
try
{
$latestResponseContent = (Invoke-WebRequest -Uri ("{0}LATEST_RELEASE_{1}" -f $latestBaseUrl, $majorVersion) -ErrorAction Stop).Content
if ($latestResponseContent -is [byte[]])
{
$memoryStream = New-Object System.IO.MemoryStream(,$latestResponseContent)
$streamReader = New-Object System.IO.StreamReader($memoryStream, $true)
try
{
$latestForMajor = $streamReader.ReadToEnd().Trim()
}
finally
{
$streamReader.Dispose()
$memoryStream.Dispose()
}
}
else
{
$latestForMajor = [string]$latestResponseContent
$latestForMajor = $latestForMajor.Trim()
}
$latestForMajorMatch = [regex]::Match($latestForMajor, '\d+\.\d+\.\d+\.\d+')
if ($latestForMajorMatch.Success)
{
$latestForMajor = $latestForMajorMatch.Value
}
else
{
$latestForMajor = ''
}
if ($latestForMajor -ne '')
{
break
}
}
catch
{
Write-Verbose ("Could not retrieve LATEST_RELEASE_{0} from '{1}': {2}" -f $majorVersion, $latestBaseUrl, $_.Exception.Message)
}
}
if (($null -ne $latestForMajor) -and ($latestForMajor -ne '') -and ($driverVersionsToTry -notcontains $latestForMajor))
{
Write-Verbose ("Detected latest published Edge WebDriver for major version {0}: {1}" -f $majorVersion, $latestForMajor)
$driverVersionsToTry += $latestForMajor
}
}
catch
{
Write-Verbose ("Could not resolve a fallback driver version for major {0}: {1}" -f $majorVersion, $_.Exception.Message)
}
}
$driverUrl = $null
$resolvedDriverVersion = $null
foreach ($candidateVersion in $driverVersionsToTry)
{
foreach ($candidateBaseUrl in $baseUrls)
{
foreach ($candidateZip in $driverZips)
{
$candidateUrl = "{0}{1}/{2}" -f $candidateBaseUrl, $candidateVersion, $candidateZip
try
{
$response = Invoke-WebRequest -Uri $candidateUrl -Method Head -ErrorAction Stop
$null = $response # get rid of PSSA warning
$driverUrl = $candidateUrl
$driverZip = $candidateZip
$resolvedDriverVersion = $candidateVersion
Write-Verbose ("WebDriver found for version {0}" -f $resolvedDriverVersion)
break
}
catch
{
Write-Verbose ("WebDriver not found at '{0}'" -f $candidateUrl)
}
}
if ($null -ne $driverUrl)
{
break
}
}
if ($null -ne $driverUrl)
{
break
}
}
if ($null -eq $driverUrl)
{
throw "WebDriver not found for Edge version $edgeVersion (and no compatible published fallback was found)."
}
$zipPath = Join-Path -Path $env:TEMP -ChildPath $driverZip
# Download and extract
Write-Verbose ("Downloading Selenium driver for Edge version '{0}' from '{1}'..." -f $resolvedDriverVersion, $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')
{
DownloadEdgeDriverDriver
}
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 ($browser -eq 'edge')
{
$useFallback = ($sm.result.code -ne 0)
if (!$useFallback)
{
$smDriverCandidate = $sm.result.driver_path
$edgePath = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
$edgeVersion = if (Test-Path -LiteralPath $edgePath) { (Get-Item -LiteralPath $edgePath).VersionInfo.ProductVersion } else { '' }
$edgeMajor = if ($edgeVersion -ne '') { ($edgeVersion -split '\.')[0] } else { '' }
if (($smDriverCandidate -eq '') -or !(Test-Path -LiteralPath $smDriverCandidate))
{
$useFallback = $true
}
elseif ($edgeMajor -ne '')
{
$smDriverVersion = (Get-Item -LiteralPath $smDriverCandidate).VersionInfo.FileVersion
$smDriverMajor = if ($smDriverVersion) { ($smDriverVersion -split '\.')[0] } else { '' }
if (($null -eq $smDriverVersion) -or ($smDriverMajor -ne $edgeMajor))
{
Write-Verbose ("selenium-manager returned Edge driver version '{0}', but installed Edge major version is '{1}'; using direct download fallback" -f $smDriverVersion, $edgeMajor)
$useFallback = $true
}
}
}
if ($useFallback)
{
DownloadEdgeDriverDriver
$smDriver = Join-Path -Path $Destination -ChildPath 'msedgeDriver.exe'
}
}
elseif ($sm.result.code -ne 0)
{
throw ("selenium-manager failed: {0}" -f ((ObjectToString -Object $sm) -replace '^\n+'))
}
}
}
if (($null -eq $smDriver) -or ($smDriver -eq ''))
{
$smDriver = $sm.result.driver_path
}
if (($smDriver -eq '') -or !(Test-Path -LiteralPath $smDriver))
{
if ($browser -eq 'edge')
{
Write-Verbose ("selenium-manager reported driver path '{0}', but it does not exist; falling back to direct Edge WebDriver download" -f $smDriver)
DownloadEdgeDriverDriver
$smDriver = Join-Path -Path $Destination -ChildPath 'msedgeDriver.exe'
}
else
{
throw ("selenium-manager returned a non-existent driver path for '{0}': '{1}'" -f $browser, $smDriver)
}
}
if ($browser -eq 'edge')
{
$edgePath = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
$edgeVersion = if (Test-Path -LiteralPath $edgePath) { (Get-Item -LiteralPath $edgePath).VersionInfo.ProductVersion } else { '' }
$edgeMajor = if ($edgeVersion -ne '') { ($edgeVersion -split '\.')[0] } else { '' }
if ($edgeMajor -ne '')
{
$smDriverVersion = (Get-Item -LiteralPath $smDriver).VersionInfo.FileVersion
$smDriverMajor = if ($smDriverVersion) { ($smDriverVersion -split '\.')[0] } else { '' }
if (($null -eq $smDriverVersion) -or ($smDriverMajor -ne $edgeMajor))
{
Write-Verbose ("Resolved Edge driver version '{0}' is not compatible with installed Edge major version '{1}'; using direct download fallback" -f $smDriverVersion, $edgeMajor)
DownloadEdgeDriverDriver
$smDriver = Join-Path -Path $Destination -ChildPath 'msedgeDriver.exe'
}
}
}
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')
{
DownloadEdgeDriverDriver
}
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