Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save vavavr00m/c74f2039a9b97a0003eb4e1b694a05f9 to your computer and use it in GitHub Desktop.
Save vavavr00m/c74f2039a9b97a0003eb4e1b694a05f9 to your computer and use it in GitHub Desktop.

Revisions

  1. vavavr00m revised this gist Apr 19, 2025. 1 changed file with 84 additions and 1 deletion.
    85 changes: 84 additions & 1 deletion download-selenium-drivers.ps1
    Original file line number Diff line number Diff line change
    @@ -233,8 +233,89 @@ function Flatten-DriversDirectory {
    }
    }

    function Replace-SeleniumAssembliesExe {
    $sourceDir = $driversDirName
    $seleniumModulesPath = 'C:\Program Files\WindowsPowerShell\Modules\Selenium'

    try {
    if (-not (Test-Path $sourceDir)) {
    throw "Source directory not found: $sourceDir"
    }

    if (-not (Test-Path $seleniumModulesPath)) {
    throw "Selenium modules path not found: $seleniumModulesPath"
    }

    $exeSources = Get-ChildItem -Path $sourceDir -Filter *.exe -File -ErrorAction Stop
    if ($exeSources.Count -eq 0) {
    Write-Host "No .exe files found in $sourceDir" -ForegroundColor Yellow
    return
    }

    $assembliesDirs = Get-ChildItem -Path "$seleniumModulesPath\*\assemblies" -Directory -ErrorAction Stop
    if ($assembliesDirs.Count -eq 0) {
    throw "No assemblies directories found under $seleniumModulesPath"
    }

    foreach ($dir in $assembliesDirs) {
    try {
    $existingExes = Get-ChildItem -Path $dir.FullName -Filter *.exe -File -ErrorAction Stop
    foreach ($exe in $existingExes) {
    try {
    Remove-Item $exe.FullName -Force -ErrorAction Stop
    Write-Host "Deleted: $($exe.FullName)" -ForegroundColor DarkGray
    } catch {
    Write-Host "ERROR:" -ForegroundColor Red -NoNewline
    Write-Host " Failed to delete $($exe.FullName): $_"
    }
    }
    } catch {
    Write-Host "ERROR:" -ForegroundColor Red -NoNewline
    Write-Host " Error while scanning $($dir.FullName) for existing .exe files: $_"
    continue
    }

    foreach ($exe in $exeSources) {
    $targetPath = Join-Path $dir.FullName $exe.Name
    try {
    Move-Item -Path $exe.FullName -Destination $targetPath -Force -ErrorAction Stop
    Write-Host "Moved: $($exe.Name)$($dir.FullName)" -ForegroundColor Cyan
    } catch {
    Write-Host "ERROR:" -ForegroundColor Red -NoNewline
    Write-Host " Failed to move $($exe.Name) to $($dir.FullName): $_"
    }
    }
    }

    } catch {
    Write-Host "ERROR:" -ForegroundColor Red -NoNewline
    Write-Host " Fatal error in Replace-SeleniumAssembliesExe: $_"
    }
    }

    function Ensure-Admin {
    if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
    [Security.Principal.WindowsBuiltInRole] "Administrator")) {

    Write-Host "Elevation required. Relaunching as administrator..." -ForegroundColor Yellow

    $psi = New-Object System.Diagnostics.ProcessStartInfo
    $psi.FileName = "powershell"
    $psi.Arguments = "-ExecutionPolicy Bypass -File `"$PSCommandPath`""
    $psi.Verb = "runas"
    try {
    [System.Diagnostics.Process]::Start($psi) | Out-Null
    } catch {
    Write-Host "User canceled the UAC prompt or access was denied." -ForegroundColor Red
    }
    exit
    }
    }

    New-Item -Force -ItemType directory -Path $driversDirName > $null;

    Ensure-Admin

    Get-ChromeInstalledVersion
    Get-ChromeDriverLatestVersion
    Ensure-Chrome-Driver;
    @@ -250,4 +331,6 @@ Ensure-MSEdge-Driver;

    Ensure-Edge-Driver;

    Flatten-DriversDirectory
    Flatten-DriversDirectory

    Replace-SeleniumAssembliesExe
  2. vavavr00m revised this gist Apr 19, 2025. 1 changed file with 207 additions and 13 deletions.
    220 changes: 207 additions & 13 deletions download-selenium-drivers.ps1
    Original file line number Diff line number Diff line change
    @@ -5,11 +5,158 @@ $driversDirName = Join-Path $currentDir ".drivers";
    $isWindows = [System.Boolean](Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue);
    $webClient = New-Object System.Net.WebClient;

    function Ensure-Driver-Exists($browserName, $exeName, $download, $zipName) {
    function Get-ChromeInstalledVersion {
    $chromeRegistryKey = "HKCU:Software\Google\Chrome\BLBeacon"

    try {
    # Try to get the registry property for Chrome version
    $global:latest_chrome = (Get-ItemProperty -Path $chromeRegistryKey -ErrorAction Stop).version

    # Output the result
    if (-not [string]::IsNullOrWhiteSpace($global:latest_chrome)) {
    Write-Host "Chrome installed version: $global:latest_chrome"
    } else {
    Write-Error "Failed to retrieve a valid version."
    $global:latest_chrome = $null
    }
    } catch {
    Write-Error "Failed to retrieve Chrome version: $_"
    $global:latest_chrome = $null
    }
    }

    function Get-ChromeDriverLatestVersion {
    try {
    $jsonUrl = "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json"
    $response = Invoke-RestMethod -Uri $jsonUrl -UseBasicParsing
    $global:latest_chromedriver = $response.channels.stable.version

    # Output the result
    if (-not [string]::IsNullOrWhiteSpace($global:latest_chrome)) {
    Write-Host "Latest ChromeDriver version: $global:latest_chromedriver"
    } else {
    Write-Error "Failed to retrieve a valid version."
    $global:latest_chromedriver = $null
    }
    } catch {
    Write-Error "Failed to get latest stable ChromeDriver version: $_"
    $global:latest_chromedriver = $null
    }
    }

    function Get-GeckoDriverLatestVersion {
    param ()

    $url = "https://api.github.com/repos/mozilla/geckodriver/releases/latest"
    try {
    $response = Invoke-RestMethod -Uri $url -UseBasicParsing
    $global:latest_geckodriver = $response.tag_name

    # Output the result
    if (-not [string]::IsNullOrWhiteSpace($global:latest_geckodriver)) {
    Write-Host "Latest GeckoDriver version: $global:latest_geckodriver"
    } else {
    Write-Error "Failed to retrieve a valid version."
    $global:latest_geckodriver = $null
    }
    } catch {
    Write-Error "Failed to retrieve latest Geckodriver version: $_"
    $global:latest_geckodriver = $null
    }
    }

    Function Clean-NormalizeVersion {
    param (
    [string]$versionString
    )

    # Remove unwanted BOM or special characters (like "ÿþ") and any spaces
    $cleanedVersion = $versionString -replace '[^\d\.]', '' # Only keep digits and periods

    # Normalize multiple spaces (if any) between version numbers (though spaces should be mostly removed)
    $normalizedVersion = $cleanedVersion -replace '\s+', '.' # Replace any internal spaces with dots

    # Trim leading/trailing spaces
    $normalizedVersion = $normalizedVersion.Trim()

    # Return the cleaned and normalized version
    return $normalizedVersion
    }

    Function Get-MSEdgeDriverLatestVersion {
    param ()

    $url = "https://msedgedriver.azureedge.net/LATEST_STABLE"
    try {
    # Retrieve the latest stable version from the URL
    $latestVersion = Invoke-RestMethod -Uri $url

    # Clean and normalize the retrieved version string
    $global:latest_msedge = Clean-NormalizeVersion -versionString $latestVersion

    # Ensure the version is cleaned and output the result
    if (-not [string]::IsNullOrWhiteSpace($global:latest_msedge)) {
    Write-Host "Latest MSEdgeDriver version: $global:latest_msedge"
    } else {
    Write-Error "Failed to retrieve a valid version."
    $global:latest_msedge = $null
    }
    } catch {
    Write-Error "Failed to retrieve the latest MSEdgeDriver version: $_"
    $global:latest_msedge = $null
    }
    }

    function Get-IEDriverServerLatestVersion {
    param (
    [string]$RepoApiUrl = "https://api.github.com/repos/SeleniumHQ/selenium/releases",
    [string]$AssetPattern = "^IEDriverServer_Win32_(?<version>[\d\.]+)\.zip$"
    )

    $headers = @{ 'User-Agent' = 'PowerShell' }
    $global:latest_iedriver = $null

    try {
    $releases = Invoke-RestMethod -Uri $RepoApiUrl -Headers $headers

    foreach ($release in $releases) {
    foreach ($asset in $release.assets) {
    if ($asset.name -match $AssetPattern) {
    $version = $Matches['version']
    $global:latest_iedriver = $version

    $result = [PSCustomObject]@{
    Name = $asset.name
    Version = $version
    Url = $asset.browser_download_url
    PublishedAt = $release.published_at
    }
    Write-Host "Latest IEDriverServer version: $global:latest_iedriver"
    return $result | Out-Null; return $result
    }
    }
    }

    Write-Warning "No matching IEDriver asset found."
    return $null
    } catch {
    Write-Error "Error fetching IEDriver version: $_"
    return $null
    }
    }

    function Ensure-Driver-Updates($browserName, $exeName, $download, $zipName) {
    $localExeName = Join-Path $driversDirName $exeName;
    if (Test-Path $localExeName) {
    Write-Host "${browserName}: driver already located at $localExeName." -f DarkGray;
    return;
    Write-Host "${browserName}: driver already located at $localExeName." -f DarkGray
    Remove-Item $localExeName -Force

    if (-not (Test-Path $localExeName)) {
    Write-Host "${browserName}: existing driver deleted." -f DarkGray
    } else {
    Write-Warning "${browserName}: failed to delete $localExeName!"
    return
    }
    }

    if ($zipName -eq $null) {
    @@ -19,41 +166,88 @@ function Ensure-Driver-Exists($browserName, $exeName, $download, $zipName) {
    $localDownloadLocation = Join-Path $driversDirName $zipName;
    }

    Write-Host "${browserName}: downloading driver from $download..." -f DarkGray;
    Write-Host "${browserName}: downloading driver from $download." -f DarkGray;
    $webClient.downloadFile($download, $localDownloadLocation);

    if (!($zipName -eq $null)) {
    Write-Host "${browserName}: extracting driver from $localDownloadLocation..." -f DarkGray;
    Expand-Archive -DestinationPath $driversDirName -Path $localDownloadLocation;
    Write-Host "${browserName}: extracting driver from $localDownloadLocation." -f DarkGray;
    Expand-Archive -DestinationPath $driversDirName -Path $localDownloadLocation -Force;
    Remove-Item $localDownloadLocation;
    }

    Write-Host "${browserName}: driver placed in $localExeName." -f DarkGray;
    }

    function Ensure-Chrome-Driver() {
    Ensure-Driver-Exists "Chrome" "chromedriver.exe" "http://chromedriver.storage.googleapis.com/2.38" "chromedriver_win32.zip"
    Ensure-Driver-Updates "Chrome" "chromedriver.exe" "https://storage.googleapis.com/chrome-for-testing-public/$($global:latest_chromedriver)/win32" "chromedriver-win32.zip"
    }

    function Ensure-Gecko-Driver() {
    Ensure-Driver-Exists "Gecko (Firefox)" "geckodriver.exe" "https://github.com/mozilla/geckodriver/releases/download/v0.20.1" "geckodriver-v0.20.1-win64.zip";
    Ensure-Driver-Updates "Gecko (Firefox)" "geckodriver.exe" "https://github.com/mozilla/geckodriver/releases/download/$($global:latest_geckodriver)" "geckodriver-$($global:latest_geckodriver)-win32.zip";
    }

    function Ensure-Edge-Driver() {
    function Ensure-Internet-Explorer-Driver() {
    if ($isWindows) {
    Ensure-Driver-Exists "Edge" "MicrosoftWebDriver.exe" "https://download.microsoft.com/download/F/8/A/F8AF50AB-3C3A-4BC4-8773-DC27B32988DD/MicrosoftWebDriver.exe"
    Ensure-Driver-Updates "Internet Explorer" "IEDriverServer.exe" "https://github.com/SeleniumHQ/selenium/releases/download/selenium-$($global:latest_iedriver)" "IEDriverServer_Win32_$($global:latest_iedriver).zip"
    }
    }

    function Ensure-Internet-Explorer-Driver() {
    function Ensure-MSEdge-Driver() {
    if ($isWindows) {
    Ensure-Driver-Exists "Internet Explorer" "IEDriverServer.exe" "http://selenium-release.storage.googleapis.com/3.9" "IEDriverServer_Win32_3.9.0.zip"
    Ensure-Driver-Updates "MSEdge" "msedgedriver.exe" "https://msedgedriver.azureedge.net/$($global:latest_msedge)" "edgedriver_win32.zip"
    }
    }

    function Ensure-Edge-Driver() {
    if ($isWindows) {
    Ensure-Driver-Updates "Edge" "MicrosoftWebDriver.exe" "https://download.microsoft.com/download/F/8/A/F8AF50AB-3C3A-4BC4-8773-DC27B32988DD/MicrosoftWebDriver.exe"
    }
    }

    function Flatten-DriversDirectory {
    if (-not (Test-Path $driversDirName)) {
    Write-Error "Path does not exist: $driversDirName"
    return
    }

    $rootPath = (Get-Item $driversDirName).FullName

    # Move only files not already in root, overwriting any duplicates
    Get-ChildItem -Path $driversDirName -Recurse -File | Where-Object {
    $_.Directory.FullName -ne $rootPath
    } | ForEach-Object {
    $destination = Join-Path -Path $rootPath -ChildPath $_.Name

    if (Test-Path $destination) {
    Remove-Item $destination -Force
    }

    Move-Item -Path $_.FullName -Destination $destination -Force
    }

    # Remove all empty directories
    Get-ChildItem -Path $driversDirName -Recurse -Directory | Sort-Object FullName -Descending | ForEach-Object {
    if (-not (Get-ChildItem -Path $_.FullName -Force)) {
    Remove-Item -Path $_.FullName -Force
    }
    }
    }

    New-Item -Force -ItemType directory -Path $driversDirName > $null;

    Get-ChromeInstalledVersion
    Get-ChromeDriverLatestVersion
    Ensure-Chrome-Driver;

    Get-IEDriverServerLatestVersion
    Ensure-Internet-Explorer-Driver;

    Get-GeckoDriverLatestVersion
    Ensure-Gecko-Driver;

    Get-MSEdgeDriverLatestVersion
    Ensure-MSEdge-Driver;

    Ensure-Edge-Driver;
    Ensure-Internet-Explorer-Driver;

    Flatten-DriversDirectory
  3. Josh Goldberg revised this gist May 16, 2018. 1 changed file with 31 additions and 31 deletions.
    62 changes: 31 additions & 31 deletions download-selenium-drivers.ps1
    Original file line number Diff line number Diff line change
    @@ -6,49 +6,49 @@ $isWindows = [System.Boolean](Get-CimInstance -ClassName Win32_OperatingSystem -
    $webClient = New-Object System.Net.WebClient;

    function Ensure-Driver-Exists($browserName, $exeName, $download, $zipName) {
    $localExeName = Join-Path $driversDirName $exeName;
    if (Test-Path $localExeName) {
    Write-Host "${browserName}: driver already located at $localExeName." -f DarkGray;
    return;
    }

    if ($zipName -eq $null) {
    $localDownloadLocation = Join-Path $driversDirName $exeName;
    } else {
    $download = "$download/$zipName";
    $localDownloadLocation = Join-Path $driversDirName $zipName;
    }

    Write-Host "${browserName}: downloading driver from $download..." -f DarkGray;
    $webClient.downloadFile($download, $localDownloadLocation);

    if (!($zipName -eq $null)) {
    Write-Host "${browserName}: extracting driver from $localDownloadLocation..." -f DarkGray;
    Expand-Archive -DestinationPath $driversDirName -Path $localDownloadLocation;
    Remove-Item $localDownloadLocation;
    }

    Write-Host "${browserName}: driver placed in $localExeName." -f DarkGray;
    $localExeName = Join-Path $driversDirName $exeName;
    if (Test-Path $localExeName) {
    Write-Host "${browserName}: driver already located at $localExeName." -f DarkGray;
    return;
    }

    if ($zipName -eq $null) {
    $localDownloadLocation = Join-Path $driversDirName $exeName;
    } else {
    $download = "$download/$zipName";
    $localDownloadLocation = Join-Path $driversDirName $zipName;
    }

    Write-Host "${browserName}: downloading driver from $download..." -f DarkGray;
    $webClient.downloadFile($download, $localDownloadLocation);

    if (!($zipName -eq $null)) {
    Write-Host "${browserName}: extracting driver from $localDownloadLocation..." -f DarkGray;
    Expand-Archive -DestinationPath $driversDirName -Path $localDownloadLocation;
    Remove-Item $localDownloadLocation;
    }

    Write-Host "${browserName}: driver placed in $localExeName." -f DarkGray;
    }

    function Ensure-Chrome-Driver() {
    Ensure-Driver-Exists "Chrome" "chromedriver.exe" "http://chromedriver.storage.googleapis.com/2.38" "chromedriver_win32.zip"
    Ensure-Driver-Exists "Chrome" "chromedriver.exe" "http://chromedriver.storage.googleapis.com/2.38" "chromedriver_win32.zip"
    }

    function Ensure-Gecko-Driver() {
    Ensure-Driver-Exists "Gecko (Firefox)" "geckodriver.exe" "https://github.com/mozilla/geckodriver/releases/download/v0.20.1" "geckodriver-v0.20.1-win64.zip";
    Ensure-Driver-Exists "Gecko (Firefox)" "geckodriver.exe" "https://github.com/mozilla/geckodriver/releases/download/v0.20.1" "geckodriver-v0.20.1-win64.zip";
    }

    function Ensure-Edge-Driver() {
    if ($isWindows) {
    Ensure-Driver-Exists "Edge" "MicrosoftWebDriver.exe" "https://download.microsoft.com/download/F/8/A/F8AF50AB-3C3A-4BC4-8773-DC27B32988DD/MicrosoftWebDriver.exe"
    }
    if ($isWindows) {
    Ensure-Driver-Exists "Edge" "MicrosoftWebDriver.exe" "https://download.microsoft.com/download/F/8/A/F8AF50AB-3C3A-4BC4-8773-DC27B32988DD/MicrosoftWebDriver.exe"
    }
    }

    function Ensure-Internet-Explorer-Driver() {
    if ($isWindows) {
    Ensure-Driver-Exists "Internet Explorer" "IEDriverServer.exe" "http://selenium-release.storage.googleapis.com/3.9" "IEDriverServer_Win32_3.9.0.zip"
    }
    if ($isWindows) {
    Ensure-Driver-Exists "Internet Explorer" "IEDriverServer.exe" "http://selenium-release.storage.googleapis.com/3.9" "IEDriverServer_Win32_3.9.0.zip"
    }
    }

    New-Item -Force -ItemType directory -Path $driversDirName > $null;
  4. Josh Goldberg created this gist May 16, 2018.
    59 changes: 59 additions & 0 deletions download-selenium-drivers.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    [Net.ServicePointManager]::SecurityProtocol = "Ssl3, Tls, Tls11, Tls12";

    $currentDir = (Get-Item -Path "./").FullName;
    $driversDirName = Join-Path $currentDir ".drivers";
    $isWindows = [System.Boolean](Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue);
    $webClient = New-Object System.Net.WebClient;

    function Ensure-Driver-Exists($browserName, $exeName, $download, $zipName) {
    $localExeName = Join-Path $driversDirName $exeName;
    if (Test-Path $localExeName) {
    Write-Host "${browserName}: driver already located at $localExeName." -f DarkGray;
    return;
    }

    if ($zipName -eq $null) {
    $localDownloadLocation = Join-Path $driversDirName $exeName;
    } else {
    $download = "$download/$zipName";
    $localDownloadLocation = Join-Path $driversDirName $zipName;
    }

    Write-Host "${browserName}: downloading driver from $download..." -f DarkGray;
    $webClient.downloadFile($download, $localDownloadLocation);

    if (!($zipName -eq $null)) {
    Write-Host "${browserName}: extracting driver from $localDownloadLocation..." -f DarkGray;
    Expand-Archive -DestinationPath $driversDirName -Path $localDownloadLocation;
    Remove-Item $localDownloadLocation;
    }

    Write-Host "${browserName}: driver placed in $localExeName." -f DarkGray;
    }

    function Ensure-Chrome-Driver() {
    Ensure-Driver-Exists "Chrome" "chromedriver.exe" "http://chromedriver.storage.googleapis.com/2.38" "chromedriver_win32.zip"
    }

    function Ensure-Gecko-Driver() {
    Ensure-Driver-Exists "Gecko (Firefox)" "geckodriver.exe" "https://github.com/mozilla/geckodriver/releases/download/v0.20.1" "geckodriver-v0.20.1-win64.zip";
    }

    function Ensure-Edge-Driver() {
    if ($isWindows) {
    Ensure-Driver-Exists "Edge" "MicrosoftWebDriver.exe" "https://download.microsoft.com/download/F/8/A/F8AF50AB-3C3A-4BC4-8773-DC27B32988DD/MicrosoftWebDriver.exe"
    }
    }

    function Ensure-Internet-Explorer-Driver() {
    if ($isWindows) {
    Ensure-Driver-Exists "Internet Explorer" "IEDriverServer.exe" "http://selenium-release.storage.googleapis.com/3.9" "IEDriverServer_Win32_3.9.0.zip"
    }
    }

    New-Item -Force -ItemType directory -Path $driversDirName > $null;

    Ensure-Chrome-Driver;
    Ensure-Gecko-Driver;
    Ensure-Edge-Driver;
    Ensure-Internet-Explorer-Driver;