---
title: "Download the right ChromeDriver version & keep it up to date on Windows/Linux/macOS using PowerShell"
excerpt: "Chrome frequently updates automatically causing ChromeDriver versions to mismatch. Using PowerShell you can download the correct version of the ChromeDriver and keep it up-to-date."
publishDate: "2021-02-18T00:00:00"
createDate: "2021-02-18T09:02:11.787"
updateDate: "2023-09-25T06:28:41.557"
category: "powershell"
categoryName: "PowerShell"
tags: ["PowerShell","Chrome","ChromeDriver","Selenium","UI Testing","Windows","Linux","macOS",".NET"]
permalink: "/blog/powershell/download-the-right-chromedriver-on-windows-linux-macos-using-powershell"
canonical: "/blog/powershell/download-the-right-chromedriver-on-windows-linux-macos-using-powershell"
image: {"src":"/media/jvidy4tg/chrome-powershell-long.png"}
imageAlt: "PowerShell logo and Google Chrome logo next to title: Download the right ChromeDriver version using PowerShell"
imageBackgroundColor: "#0c0c0c"
thumbnailImage: {"src":"/media/devc0h3n/chrome-powershell-square.png"}
thumbnailImageAlt: "PowerShell logo and Google Chrome logo"
metaTitle: "Download the right ChromeDriver version & keep it up to date on Windows/Linux/macOS using PowerShell"
metaDescription: "Chrome frequently updates automatically causing ChromeDriver versions to mismatch. Using PowerShell you can download the correct version of the ChromeDriver and keep it up-to-date."
ogTitle: "Download the right ChromeDriver version & keep it up to date on Windows/Linux/macOS using PowerShell"
ogDescription: "Chrome frequently updates automatically causing ChromeDriver versions to mismatch. Using PowerShell you can download the correct version of the ChromeDriver and keep it up-to-date."
ogImage: {"src":"/media/lh3j2hkz/chrome-powershell-social.png"}
ogImageAlt: "PowerShell logo and Google Chrome logo next to title: Download the right ChromeDriver version using PowerShell"
relatedPostKeys: ["dc2fa04139ce4c13a8598000072ac8c1","57d0fdba8b264faf9d2e885ea413d984"]
noIndex: false
noFollow: false
sitemapExclude: false
source: {"nodeId":1454,"contentKey":"1f3a78afdbcf4c519cfd21c1f159cabe","sortOrder":85}
---

<p class="panel panel--warning"><strong>Update (Sep 2023)</strong>: The old script for downloading the ChromeDriver does not work for versions 115 and newer because Chrome changed their process. You can find an <a href="https://gist.github.com/Swimburger/aa5fd64151d84443f395f56f803b0ae2#file-installchromedriver-ps1">updated PowerShell script for newer versions here</a>.</p>




You can run automated UI browser tests using technologies like **Selenium**. The UI testing technology will communicate with a "**webdriver**" which will, in turn, drive around the browser.




<p class="panel panel--info"><strong>An analogy</strong>: Consumers without a driver's license use a taxi to go to a specific location. The consumers don't know how to drive themselves, and instead provide the desired location to the driver. The taxi driver knows how to drive the vehicle towards the instructed location. In this analogy, the consumers are your UI testing code instructing the webdriver, the taxi driver is the webdriver, and the web browser is the vehicle.</p>




**ChromeDriver** is the webdriver implementation for **Google Chrome**. ChromeDriver and Selenium work together very well, but given enough time you will run into the following error:




<pre style="color:#000000;background:#ffffff;">Unhandled exception. System.InvalidOperationException: session not created: This version of ChromeDriver only supports Chrome version 74&#10;  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Windows NT 10.0.19042 x86_64) (SessionNotCreated)&#10;   at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)&#10;   at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)&#10;   at OpenQA.Selenium.Remote.RemoteWebDriver.StartSession(ICapabilities desiredCapabilities)&#10;   at OpenQA.Selenium.Remote.RemoteWebDriver..ctor(ICommandExecutor commandExecutor, ICapabilities desiredCapabilities)&#10;   at OpenQA.Selenium.Chrome.ChromeDriver..ctor(ChromeDriverService service, ChromeOptions options, TimeSpan commandTimeout)&#10;   at OpenQA.Selenium.Chrome.ChromeDriver..ctor(ChromeOptions options)&#10;   at OpenQA.Selenium.Chrome.ChromeDriver..ctor()&#10;   at SeleniumConsole.Program.Main(String[] args) in C:\Users\niels\source\repos\SeleniumConsole\Program.cs:line 10&#10;</pre>




**Google Chrome is very good about updating very frequently, often leaving the ChromeDriver out of date**. When the **ChromeDriver is incompatible with the installed version of Google Chrome**, you will run into the error above.<br>The fix is pretty simple, go back to the [ChromeDriver website](https://chromedriver.chromium.org/downloads) and download the most recent version. But doing this manually every time Chrome updates will quickly become unmanageable.<br>Especially when you run UI tests on multiple servers, on a periodic basis, or inside a continuous integration and deployment pipeline. Even worse, the failure of these tests may be connected to email, SMS, and/or phone alerting systems.




## How to download the correct version of Chrome {#how-to-download-the-correct-version-of-chrome}

Luckily, the ChromeDriver website provides a systematic way of downloading the correct version of the ChromeDriver given a specific version of Google Chrome. <br>Here are [the instructions](https://chromedriver.chromium.org/downloads/version-selection) provided:

<ul>
<li>First, find out <strong>which version of Chrome</strong> you are using. Let's say you have <strong>Chrome 72.0.3626.81</strong>.</li>
<li>Take the Chrome version number, remove the last part, and append the result to URL "<strong>https://chromedriver.storage.googleapis.com/LATEST_RELEASE_</strong>". For example, with Chrome version <strong>72.0.3626<span style="text-decoration: line-through;">.81</span></strong>, you'd get a URL "<strong>https://chromedriver.storage.googleapis.com/LATEST_RELEASE_72.0.3626</strong>".</li>
<li>Use the URL created in the last step to <strong>retrieve a small file containing the version of ChromeDriver</strong> to use. For example, the above URL will get your a file containing "<strong>72.0.3626.69</strong>". (The actual number may change in the future, of course.)</li>
<li>Use the version number retrieved from the previous step to construct the URL to download ChromeDriver. With version 72.0.3626.69, the URL would be "<strong>https://chromedriver.storage.googleapis.com/index.html?path=72.0.3626.69/</strong>".</li>
<li>After the initial download, it is recommended that you occasionally go through the above process again to see if there are any bug fix releases.</li>
</ul>

In the above steps, one small detail has been omitted. You have to download the correct file which will work on the operating system (OS) you're using. You will have the following three options to download on the URL determined in the steps above:


-   chromedriver\_linux64.zip (for Linux)
-   chromedriver\_mac64.zip (for macOS)
-   chromedriver\_win32.zip (for Windows)


It's self-explanatory which file you need to download depending on your OS which is why it was probably omitted from the steps.  But you will need to keep this in account to automate this process.

## Build a PowerShell script to install the correct ChromeDriver {#build-a-powershell-script-to-install-the-correct-chromedriver}




Let's build this PowerShell script step by step based on the instructions provided by Google. **If you just want to use the end result, feel free to <a href="#end-result-enhanced-powershell-script-to-download-chromedriver">scroll to skip this section</a>**.


First, you need to determine the version of Chrome installed on your local machine. This is arguably the hardest step because this is different for every OS installs software differently. There are also multiple ways to determine the version, some more robust than others.

On Windows, you can query the registry for the location of Chrome and then get the version stored inside the `VersionInfo` property.

<pre style="color:#000000;background:#ffffff;">(Get-Item (Get-ItemProperty <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe</span><span style="color:#2a00ff; ">'</span>).<span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">(Default)</span><span style="color:#2a00ff; ">'</span>).VersionInfo.FileVersion&#10;</pre>

To properly handle the scenario where Google Chrome isn't installed, you should surround this line with a **TryCatch** block and also specify `-ErrorAction Stop` to ensure errors will trigger the Catch block.

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">Try</span>{&#10;    (Get-Item (Get-ItemProperty <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe</span><span style="color:#2a00ff; ">'</span> -ErrorAction <span style="color:#2a00ff; ">Stop</span>).<span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">(Default)</span><span style="color:#2a00ff; ">'</span>).VersionInfo.FileVersion;&#10;}<span style="color:#7f0055; font-weight:bold; ">Catch</span>{&#10;    <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome not found in registry</span><span style="color:#2a00ff; ">"</span>;&#10;}&#10;</pre>

Lastly, you only want to run this on Windows, so you should surround this code with the following If-block:

<pre style="color:#000000;background:#ffffff;"><span style="color:#3f7f59; "># $IsWindows will PowerShell Core but not on PowerShell 5 and below, but $Env:OS does</span>&#10;<span style="color:#3f7f59; "># this way you can safely check whether the current machine is running Windows pre and post PowerShell Core</span>&#10;<span style="color:#7f0055; font-weight:bold; ">If</span> ($IsWindows -or $Env:OS) {&#10;&#10;}&#10;</pre>

On Linux, the command `google-chrome` should be globally available when installed. Use the command to get the version using `--product-version` argument.<br>To handle the scenario where Chrome isn't installed, you test the availability of the command before running it like this:

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">Try</span>{&#10;    <span style="color:#3f7f59; "># this will check whether google-chrome command is available</span>&#10;    Get-Command <span style="color:#2a00ff; ">google-chrome</span> -ErrorAction <span style="color:#2a00ff; ">Stop</span> <span style="color:#7f0055; font-weight:bold; ">|</span> Out-Null;&#10;    google-chrome <span style="color:#2a00ff; ">--product-version</span>;&#10;}<span style="color:#7f0055; font-weight:bold; ">Catch</span>{&#10;    <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">'google-chrome' command not found</span><span style="color:#2a00ff; ">"</span>;&#10;}&#10;</pre>

Ensure these commands only run on Linux, using the following ElseIf-block:

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsLinux) {&#10;    &#10;}&#10;</pre>

On macOS, you can test if the application has been install at the expected location. If it is, execute the application with the `--version` argument.<br>In this case, the Chrome application will prefix the version with "Google Chrome ". Remove the prefix using the string replace method.

<pre style="color:#000000;background:#ffffff;">$ChromePath = <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</span><span style="color:#2a00ff; ">'</span>;&#10;<span style="color:#7f0055; font-weight:bold; ">If</span> (Test-Path $ChromePath) {&#10;    $Version = &amp; $ChromePath <span style="color:#2a00ff; ">--version</span>;&#10;    $Version = $Version.Replace(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome </span><span style="color:#2a00ff; ">"</span>, <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">"</span>);&#10;    $Version;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;    <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome not found on your MacOS machine</span><span style="color:#2a00ff; ">"</span>;&#10;}&#10;</pre>

Ensure these commands only run on Linux, using the following ElseIf-block:

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsMacOS) {&#10;&#10;}&#10;</pre>




 PowerShell isn't supported on any other operating systems, but just in case add the following Else-block:




<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;    <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Your operating system is not supported by this script.</span><span style="color:#2a00ff; ">"</span>;&#10;}&#10;</pre>

Put the code together and wrap it in a function like this:

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">Function</span> Get-ChromeVersion {&#10;    <span style="color:#3f7f59; "># $IsWindows will PowerShell Core but not on PowerShell 5 and below, but $Env:OS does</span>&#10;    <span style="color:#3f7f59; "># this way you can safely check whether the current machine is running Windows pre and post PowerShell Core</span>&#10;    <span style="color:#7f0055; font-weight:bold; ">If</span> ($IsWindows -or $Env:OS) {&#10;        <span style="color:#7f0055; font-weight:bold; ">Try</span> {&#10;            (Get-Item (Get-ItemProperty <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe</span><span style="color:#2a00ff; ">'</span> -ErrorAction <span style="color:#2a00ff; ">Stop</span>).<span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">(Default)</span><span style="color:#2a00ff; ">'</span>).VersionInfo.FileVersion;&#10;        }&#10;        <span style="color:#7f0055; font-weight:bold; ">Catch</span> {&#10;            <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome not found in registry</span><span style="color:#2a00ff; ">"</span>;&#10;        }&#10;    }&#10;    <span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsLinux) {&#10;        <span style="color:#7f0055; font-weight:bold; ">Try</span> {&#10;            <span style="color:#3f7f59; "># this will check whether google-chrome command is available</span>&#10;            Get-Command <span style="color:#2a00ff; ">google-chrome</span> -ErrorAction <span style="color:#2a00ff; ">Stop</span> <span style="color:#7f0055; font-weight:bold; ">|</span> Out-Null;&#10;            google-chrome <span style="color:#2a00ff; ">--product-version</span>;&#10;        }&#10;        <span style="color:#7f0055; font-weight:bold; ">Catch</span> {&#10;            <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">'google-chrome' command not found</span><span style="color:#2a00ff; ">"</span>;&#10;        }&#10;    }&#10;    <span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsMacOS) {&#10;        $ChromePath = <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</span><span style="color:#2a00ff; ">'</span>;&#10;        <span style="color:#7f0055; font-weight:bold; ">If</span> (Test-Path $ChromePath) {&#10;            $Version = &amp; $ChromePath <span style="color:#2a00ff; ">--version</span>;&#10;            $Version = $Version.Replace(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome </span><span style="color:#2a00ff; ">"</span>, <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">"</span>);&#10;            $Version;&#10;        }&#10;        <span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;            <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome not found on your MacOS machine</span><span style="color:#2a00ff; ">"</span>;&#10;        }&#10;    }&#10;    <span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;        <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Your operating system is not supported by this script.</span><span style="color:#2a00ff; ">"</span>;&#10;    }&#10;}&#10;</pre>



<p class="panel panel--info">In PowerShell, when a value isn't captured, it is returned to the consumer of the function. (Except when the value is piped to <code>Out-Null</code>).</p>

After the Function declaration, put the following lines of code to invoke the function, capture the chrome version, and print it to the output:

<pre style="color:#000000;background:#ffffff;"><span style="color:#3f7f59; "># Instructions from </span><span style="color:#3f3fbf; ">https://chromedriver.chromium.org/downloads/version-selection</span>&#10;<span style="color:#3f7f59; ">#   First, find out which version of Chrome you are using. Let's say you have Chrome 72.0.3626.81.</span>&#10;$ChromeVersion = Get-ChromeVersion -ErrorAction <span style="color:#2a00ff; ">Stop</span>;&#10;Write-Output <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome version </span><span style="color:#2a00ff; ">$ChromeVersion</span><span style="color:#2a00ff; "> found on machine</span><span style="color:#2a00ff; ">"</span>;&#10;</pre>

(The comments are the steps provided by the ChromeDriver website.)

Remove the last part of the version, query the latest matching release ChromeDriver version from the ChromeDriver website, and print the ChromeDriver version to the output:

<pre style="color:#000000;background:#ffffff;"><span style="color:#3f7f59; ">#   Take the Chrome version number, remove the last part, </span>&#10;$ChromeVersion = $ChromeVersion.Substring(0, $ChromeVersion.LastIndexOf(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.</span><span style="color:#2a00ff; ">"</span>));&#10;<span style="color:#3f7f59; ">#   and append the result to URL "</span><span style="color:#3f3fbf; ">https://chromedriver.storage.googleapis.com/LATEST_RELEASE_</span><span style="color:#3f7f59; ">". </span>&#10;<span style="color:#3f7f59; ">#   For example, with Chrome version 72.0.3626.81, you'd get a URL "</span><span style="color:#3f3fbf; ">https://chromedriver.storage.googleapis.com/LATEST_RELEASE_72.0.3626</span><span style="color:#3f7f59; ">".</span>&#10;$ChromeDriverVersion = (Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/LATEST_RELEASE_</span><span style="color:#2a00ff; ">$ChromeVersion</span><span style="color:#2a00ff; ">"</span>).Content;&#10;Write-Output <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Latest matching version of Chrome Driver is </span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">"</span>;&#10;</pre>




Create a temporary file and store the path in a variable <code>$TempFilePath</code>. Change the tmp-extension to the zip-extension. <br>Lastly, create another variable <code>$TempFileUnzipPath</code> to store the folder path and simply use the temporary file path without extension.<br>You will need to <code>$TempFileUnzipPath</code> to specify where to unzip the ZIP-file later.




<pre style="color:#000000;background:#ffffff;">$TempFilePath = <span style="color:#7f0055; font-weight:bold; ">[System.IO.Path]</span>::GetTempFileName();&#10;$TempZipFilePath = $TempFilePath.Replace(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.tmp</span><span style="color:#2a00ff; ">"</span>, <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.zip</span><span style="color:#2a00ff; ">"</span>);&#10;Rename-Item -Path $TempFilePath -NewName $TempZipFilePath;&#10;$TempFileUnzipPath = $TempFilePath.Replace(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.tmp</span><span style="color:#2a00ff; ">"</span>, <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">"</span>);&#10;</pre>

Depending on the OS, download the correct ZIP-file from the ChromeDriver website, unzip it using `Expand-Archive` and move the driver to the desired location:

<pre style="color:#000000;background:#ffffff;"><span style="color:#3f7f59; ">#   Use the URL created in the last step to retrieve a small file containing the version of ChromeDriver to use. For example, the above URL will get your a file containing "72.0.3626.69". (The actual number may change in the future, of course.)</span>&#10;<span style="color:#3f7f59; ">#   Use the version number retrieved from the previous step to construct the URL to download ChromeDriver. With version 72.0.3626.69, the URL would be "</span><span style="color:#3f3fbf; ">https://chromedriver.storage.googleapis.com/index.html?path=72.0.3626.69/</span><span style="color:#3f7f59; ">".</span>&#10;<span style="color:#7f0055; font-weight:bold; ">If</span> ($IsWindows -or $Env:OS) {&#10;    Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/</span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">/chromedriver_win32.zip</span><span style="color:#2a00ff; ">"</span> -OutFile $TempZipFilePath;&#10;    Expand-Archive $TempZipFilePath -DestinationPath $TempFileUnzipPath;&#10;    Move-Item <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">$TempFileUnzipPath</span><span style="color:#2a00ff; ">/chromedriver.exe</span><span style="color:#2a00ff; ">"</span> -Destination <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">path/to/save/chromedriver.exe</span><span style="color:#2a00ff; ">"</span> -Force;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsLinux) {&#10;    Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/</span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">/chromedriver_linux64.zip</span><span style="color:#2a00ff; ">"</span> -OutFile $TempZipFilePath;&#10;    Expand-Archive $TempZipFilePath -DestinationPath $TempFileUnzipPath;&#10;    Move-Item <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">$TempFileUnzipPath</span><span style="color:#2a00ff; ">/chromedriver</span><span style="color:#2a00ff; ">"</span> -Destination <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">path/to/save/chromedriver</span><span style="color:#2a00ff; ">"</span> -Force;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsMacOS) {&#10;    Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/</span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">/chromedriver_mac64.zip</span><span style="color:#2a00ff; ">"</span> -OutFile $TempZipFilePath;&#10;    Expand-Archive $TempZipFilePath -DestinationPath $TempFileUnzipPath;&#10;    Move-Item <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">$TempFileUnzipPath</span><span style="color:#2a00ff; ">/chromedriver</span><span style="color:#2a00ff; ">"</span> -Destination <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">path/to/save/chromedriver</span><span style="color:#2a00ff; ">"</span> -Force;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;    <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Your operating system is not supported by this script.</span><span style="color:#2a00ff; ">"</span>;&#10;}&#10;</pre>



<p class="panel panel--info"><strong>Note:</strong> You should update the "path/to/save/chromedriver" hardcoded string to the desired location or ideally a variable. See the end result script to accept the desired path as a parameter.</p>

Lastly, clean up by deleting the temporary zip-file and folder:

<pre style="color:#000000;background:#ffffff;"><span style="color:#3f7f59; "># Clean up temp files</span>&#10;Remove-Item $TempZipFilePath;&#10;Remove-Item $TempFileUnzipPath -Recurse;&#10;</pre>




Executing all this code will download the latest ChromeDriver matching the installed instance of Chrome. 




## End result: Enhanced PowerShell script to download ChromeDriver {#end-result-enhanced-powershell-script-to-download-chromedriver}

The code so far has solely focused on executing the instructions provided by Google to keep things easy to digest and streamlined.<br>The end result below will run the same commands, but the adjustments make the script more reusable, flexible, and performant. Here's a list of changes:

<ul>
<li>Add parameters
<ul>
<li>
<div><strong>-ChromeDriverOutputPath</strong>: The path to save the ChromeDriver to</div>
</li>
<li><strong>-ChromeVersion</strong>: Specify the version of Chrome you need a ChromeDriver for. Use this parameter in case you want to download a ChromeDriver for a different version of Chrome than the one installed.<br>You can also use this parameter to specify the correct version yourself instead of letting the script detect the local Chrome installation.</li>
<li><strong>-ForceDownload</strong>: Download the latest ChromeDriver regardless of whether the ChromeDriver at $ChromeDriverOutputPath is the same version.</li>
</ul>
</li>
<li>A check was added to prevent unnecessarily download the ChromeDriver if the same version of ChromeDriver is already present at the path specified using $ChromeDriverOutputPath. You can ignore this check by specifying the -ForceDownload switch.</li>
<li>By default, PowerShell shows a progress bar when downloading files using Invoke-WebRequest. This progress bar can decrease the download performance by a lot.</li>
</ul>

Here's the final result:

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">[CmdletBinding()]</span>&#10;<span style="color:#7f0055; font-weight:bold; ">param</span> (&#10;    <span style="color:#7f0055; font-weight:bold; ">[Parameter(</span><span style="color:#7f0055; font-weight:bold; ">Mandatory</span><span style="color:#7f0055; font-weight:bold; "> </span><span style="color:#7f0055; font-weight:bold; ">=</span><span style="color:#7f0055; font-weight:bold; "> </span><span style="color:#7f0055; font-weight:bold; ">$True</span><span style="color:#7f0055; font-weight:bold; ">)]</span>&#10;    <span style="color:#7f0055; font-weight:bold; ">[string]</span>&#10;    $ChromeDriverOutputPath,    &#10;    <span style="color:#7f0055; font-weight:bold; ">[Parameter(</span><span style="color:#7f0055; font-weight:bold; ">Mandatory</span><span style="color:#7f0055; font-weight:bold; "> </span><span style="color:#7f0055; font-weight:bold; ">=</span><span style="color:#7f0055; font-weight:bold; "> </span><span style="color:#7f0055; font-weight:bold; ">$false</span><span style="color:#7f0055; font-weight:bold; ">)]</span>&#10;    <span style="color:#7f0055; font-weight:bold; ">[string]</span>&#10;    $ChromeVersion, &#10;    <span style="color:#7f0055; font-weight:bold; ">[Parameter(</span><span style="color:#7f0055; font-weight:bold; ">Mandatory</span><span style="color:#7f0055; font-weight:bold; "> </span><span style="color:#7f0055; font-weight:bold; ">=</span><span style="color:#7f0055; font-weight:bold; "> </span><span style="color:#7f0055; font-weight:bold; ">$false</span><span style="color:#7f0055; font-weight:bold; ">)]</span>&#10;    <span style="color:#7f0055; font-weight:bold; ">[Switch]</span>&#10;    $ForceDownload&#10;)&#10;&#10;<span style="color:#3f7f59; "># store original preference to revert back later</span>&#10;$OriginalProgressPreference = $ProgressPreference;&#10;<span style="color:#3f7f59; "># setting progress preference to silently continue will massively increase the performance of downloading the ChromeDriver</span>&#10;$ProgressPreference = <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">SilentlyContinue</span><span style="color:#2a00ff; ">'</span>;&#10;&#10;<span style="color:#7f0055; font-weight:bold; ">Function</span> Get-ChromeVersion {&#10;    <span style="color:#3f7f59; "># $IsWindows will PowerShell Core but not on PowerShell 5 and below, but $Env:OS does</span>&#10;    <span style="color:#3f7f59; "># this way you can safely check whether the current machine is running Windows pre and post PowerShell Core</span>&#10;    <span style="color:#7f0055; font-weight:bold; ">If</span> ($IsWindows -or $Env:OS) {&#10;        <span style="color:#7f0055; font-weight:bold; ">Try</span> {&#10;            (Get-Item (Get-ItemProperty <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe</span><span style="color:#2a00ff; ">'</span> -ErrorAction <span style="color:#2a00ff; ">Stop</span>).<span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">(Default)</span><span style="color:#2a00ff; ">'</span>).VersionInfo.FileVersion;&#10;        }&#10;        <span style="color:#7f0055; font-weight:bold; ">Catch</span> {&#10;            <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome not found in registry</span><span style="color:#2a00ff; ">"</span>;&#10;        }&#10;    }&#10;    <span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsLinux) {&#10;        <span style="color:#7f0055; font-weight:bold; ">Try</span> {&#10;            <span style="color:#3f7f59; "># this will check whether google-chrome command is available</span>&#10;            Get-Command <span style="color:#2a00ff; ">google-chrome</span> -ErrorAction <span style="color:#2a00ff; ">Stop</span> <span style="color:#7f0055; font-weight:bold; ">|</span> Out-Null;&#10;            google-chrome <span style="color:#2a00ff; ">--product-version</span>;&#10;        }&#10;        <span style="color:#7f0055; font-weight:bold; ">Catch</span> {&#10;            <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">'google-chrome' command not found</span><span style="color:#2a00ff; ">"</span>;&#10;        }&#10;    }&#10;    <span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsMacOS) {&#10;        $ChromePath = <span style="color:#2a00ff; ">'</span><span style="color:#2a00ff; ">/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</span><span style="color:#2a00ff; ">'</span>;&#10;        <span style="color:#7f0055; font-weight:bold; ">If</span> (Test-Path $ChromePath) {&#10;            $Version = &amp; $ChromePath <span style="color:#2a00ff; ">--version</span>;&#10;            $Version = $Version.Replace(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome </span><span style="color:#2a00ff; ">"</span>, <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">"</span>);&#10;            $Version;&#10;        }&#10;        <span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;            <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome not found on your MacOS machine</span><span style="color:#2a00ff; ">"</span>;&#10;        }&#10;    }&#10;    <span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;        <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Your operating system is not supported by this script.</span><span style="color:#2a00ff; ">"</span>;&#10;    }&#10;}&#10;&#10;<span style="color:#3f7f59; "># Instructions from </span><span style="color:#3f3fbf; ">https://chromedriver.chromium.org/downloads/version-selection</span>&#10;<span style="color:#3f7f59; ">#   First, find out which version of Chrome you are using. Let's say you have Chrome 72.0.3626.81.</span>&#10;<span style="color:#7f0055; font-weight:bold; ">If</span> (<span style="color:#7f0055; font-weight:bold; ">[string]</span>::IsNullOrEmpty($ChromeVersion)) {&#10;    $ChromeVersion = Get-ChromeVersion -ErrorAction <span style="color:#2a00ff; ">Stop</span>;&#10;    Write-Output <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Google Chrome version </span><span style="color:#2a00ff; ">$ChromeVersion</span><span style="color:#2a00ff; "> found on machine</span><span style="color:#2a00ff; ">"</span>;&#10;}&#10;&#10;<span style="color:#3f7f59; ">#   Take the Chrome version number, remove the last part, </span>&#10;$ChromeVersion = $ChromeVersion.Substring(0, $ChromeVersion.LastIndexOf(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.</span><span style="color:#2a00ff; ">"</span>));&#10;<span style="color:#3f7f59; ">#   and append the result to URL "</span><span style="color:#3f3fbf; ">https://chromedriver.storage.googleapis.com/LATEST_RELEASE_</span><span style="color:#3f7f59; ">". </span>&#10;<span style="color:#3f7f59; ">#   For example, with Chrome version 72.0.3626.81, you'd get a URL "</span><span style="color:#3f3fbf; ">https://chromedriver.storage.googleapis.com/LATEST_RELEASE_72.0.3626</span><span style="color:#3f7f59; ">".</span>&#10;$ChromeDriverVersion = (Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/LATEST_RELEASE_</span><span style="color:#2a00ff; ">$ChromeVersion</span><span style="color:#2a00ff; ">"</span>).Content;&#10;Write-Output <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Latest matching version of Chrome Driver is </span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">"</span>;&#10;&#10;<span style="color:#7f0055; font-weight:bold; ">If</span> (($ForceDownload -eq <span style="color:#7f0055; font-weight:bold; ">$False</span>) -and (Test-path $ChromeDriverOutputPath)) {&#10;    <span style="color:#3f7f59; ">#ChromeDriver 88.0.4324.96 (68dba2d8a0b149a1d3afac56fa74648032bcf46b-refs/branch-heads/4324@{#1784})</span>&#10;    $ExistingChromeDriverVersion = &amp; $ChromeDriverOutputPath <span style="color:#2a00ff; ">--version</span>;&#10;    $ExistingChromeDriverVersion = $ExistingChromeDriverVersion.Split(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; "> </span><span style="color:#2a00ff; ">"</span>)[1];&#10;    <span style="color:#7f0055; font-weight:bold; ">If</span> ($ChromeDriverVersion -eq $ExistingChromeDriverVersion) {&#10;        Write-Output <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Chromedriver on machine is already latest version. Skipping.</span><span style="color:#2a00ff; ">"</span>;&#10;        Write-Output <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Use -ForceDownload to reinstall regardless</span><span style="color:#2a00ff; ">"</span>;&#10;        <span style="color:#7f0055; font-weight:bold; ">Exit</span>;&#10;    }&#10;}&#10;&#10;$TempFilePath = <span style="color:#7f0055; font-weight:bold; ">[System.IO.Path]</span>::GetTempFileName();&#10;$TempZipFilePath = $TempFilePath.Replace(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.tmp</span><span style="color:#2a00ff; ">"</span>, <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.zip</span><span style="color:#2a00ff; ">"</span>);&#10;Rename-Item -Path $TempFilePath -NewName $TempZipFilePath;&#10;$TempFileUnzipPath = $TempFilePath.Replace(<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">.tmp</span><span style="color:#2a00ff; ">"</span>, <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">"</span>);&#10;<span style="color:#3f7f59; ">#   Use the URL created in the last step to retrieve a small file containing the version of ChromeDriver to use. For example, the above URL will get your a file containing "72.0.3626.69". (The actual number may change in the future, of course.)</span>&#10;<span style="color:#3f7f59; ">#   Use the version number retrieved from the previous step to construct the URL to download ChromeDriver. With version 72.0.3626.69, the URL would be "</span><span style="color:#3f3fbf; ">https://chromedriver.storage.googleapis.com/index.html?path=72.0.3626.69/</span><span style="color:#3f7f59; ">".</span>&#10;&#10;<span style="color:#7f0055; font-weight:bold; ">If</span> ($IsWindows -or $Env:OS) {&#10;    Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/</span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">/chromedriver_win32.zip</span><span style="color:#2a00ff; ">"</span> -OutFile $TempZipFilePath;&#10;    Expand-Archive $TempZipFilePath -DestinationPath $TempFileUnzipPath;&#10;    Move-Item <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">$TempFileUnzipPath</span><span style="color:#2a00ff; ">/chromedriver.exe</span><span style="color:#2a00ff; ">"</span> -Destination $ChromeDriverOutputPath -Force;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsLinux) {&#10;    Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/</span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">/chromedriver_linux64.zip</span><span style="color:#2a00ff; ">"</span> -OutFile $TempZipFilePath;&#10;    Expand-Archive $TempZipFilePath -DestinationPath $TempFileUnzipPath;&#10;    Move-Item <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">$TempFileUnzipPath</span><span style="color:#2a00ff; ">/chromedriver</span><span style="color:#2a00ff; ">"</span> -Destination $ChromeDriverOutputPath -Force;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">ElseIf</span> ($IsMacOS) {&#10;    Invoke-WebRequest <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">https://chromedriver.storage.googleapis.com/</span><span style="color:#2a00ff; ">$ChromeDriverVersion</span><span style="color:#2a00ff; ">/chromedriver_mac64.zip</span><span style="color:#2a00ff; ">"</span> -OutFile $TempZipFilePath;&#10;    Expand-Archive $TempZipFilePath -DestinationPath $TempFileUnzipPath;&#10;    Move-Item <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">$TempFileUnzipPath</span><span style="color:#2a00ff; ">/chromedriver</span><span style="color:#2a00ff; ">"</span> -Destination $ChromeDriverOutputPath -Force;&#10;}&#10;<span style="color:#7f0055; font-weight:bold; ">Else</span> {&#10;    <span style="color:#7f0055; font-weight:bold; ">Throw</span> <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">Your operating system is not supported by this script.</span><span style="color:#2a00ff; ">"</span>;&#10;}&#10;&#10;<span style="color:#3f7f59; ">#   After the initial download, it is recommended that you occasionally go through the above process again to see if there are any </span><span style="color:#ffffff; background:#808000; ">bug fix releases.</span>&#10;&#10;<span style="color:#3f7f59; "># Clean up temp files</span>&#10;Remove-Item $TempZipFilePath;&#10;Remove-Item $TempFileUnzipPath -Recurse;&#10;&#10;<span style="color:#3f7f59; "># reset back to original Progress Preference</span>&#10;$ProgressPreference = $OriginalProgressPreference;&#10;</pre>

Save this code to a file named 'InstallChromeDriver.ps1' and invoke the script from PowerShell like this:

<pre style="color:#000000;background:#ffffff;">.\InstallChromeDriver.ps1 -ChromeDriverOutputPath <span style="color:#2a00ff; ">.\chromedriver.exe</span>&#10;</pre>

If you want to specify the version of Chrome yourself, add the `-ChromeVersion` parameter:

<pre style="color:#000000;background:#ffffff;">.\InstallChromeDriver.ps1 -ChromeDriverOutputPath <span style="color:#2a00ff; ">.\chromedriver.exe</span> -ChromeVersion 88.0<span style="color:#2a00ff; ">.4324.182</span>&#10;</pre>

If you want to force the download of the driver even if the same version is already downloaded at the specified location, add the `-ForceDownload` parameter:

<pre style="color:#000000;background:#ffffff;">.\InstallChromeDriver.ps1 -ChromeDriverOutputPath <span style="color:#2a00ff; ">.\chromedriver.exe</span> -ForceDownload&#10;</pre>

I recommend you run this script on a regular basis or right before running your UI tests to keep your ChromeDriver up-to-date. Just make sure that the ChromeDriver isn't being locked by one of your UI tests when you're trying to update it.


If you have any issues, feedback, or suggestions, feel free to reach out to me on [Twitter](https://twitter.com/RealSwimburger) or comment on [this GitHub gist](https://gist.github.com/Swimburger/aa5fd64151d84443f395f56f803b0ae2).
