-
-
Save ScottHutchinson/b22339c3d3688da5c9b477281e258400 to your computer and use it in GitHub Desktop.
# Based on http://nuts4.net/post/automated-download-and-installation-of-visual-studio-extensions-via-powershell | |
param([String] $PackageName) | |
$ErrorActionPreference = "Stop" | |
$baseProtocol = "https:" | |
$baseHostName = "marketplace.visualstudio.com" | |
$Uri = "$($baseProtocol)//$($baseHostName)/items?itemName=$($PackageName)" | |
$VsixLocation = "$($env:Temp)\$([guid]::NewGuid()).vsix" | |
$VSInstallDir = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service" | |
if (-Not $VSInstallDir) { | |
Write-Error "Visual Studio InstallDir registry key missing" | |
Exit 1 | |
} | |
Write-Host "Grabbing VSIX extension at $($Uri)" | |
$HTML = Invoke-WebRequest -Uri $Uri -UseBasicParsing -SessionVariable session | |
Write-Host "Attempting to download $($PackageName)..." | |
$anchor = $HTML.Links | | |
Where-Object { $_.class -eq 'install-button-container' } | | |
Select-Object -ExpandProperty href | |
if (-Not $anchor) { | |
Write-Error "Could not find download anchor tag on the Visual Studio Extensions page" | |
Exit 1 | |
} | |
Write-Host "Anchor is $($anchor)" | |
$href = "$($baseProtocol)//$($baseHostName)$($anchor)" | |
Write-Host "Href is $($href)" | |
Invoke-WebRequest $href -OutFile $VsixLocation -WebSession $session | |
if (-Not (Test-Path $VsixLocation)) { | |
Write-Error "Downloaded VSIX file could not be located" | |
Exit 1 | |
} | |
Write-Host "VSInstallDir is $($VSInstallDir)" | |
Write-Host "VsixLocation is $($VsixLocation)" | |
Write-Host "Installing $($PackageName)..." | |
Start-Process -Filepath "$($VSInstallDir)\VSIXInstaller" -ArgumentList "/q /a $($VsixLocation)" -Wait | |
Write-Host "Cleanup..." | |
rm $VsixLocation | |
Write-Host "Installation of $($PackageName) complete!" |
# This script will download the latest version of each extension | |
# and install it in all supported versions of Visual Studio. | |
# It might take a few minutes to download and install each extension. | |
# To Run this Script: | |
# Optional: Sign in at https://marketplace.visualstudio.com to avoid being blocked | |
# due to Anonymous usage rate limits. | |
# Close Visual Studio before running this script. | |
# Run in PowerShell as Admin. | |
# Example: PS C:\Installers\Visual Studio\VSIX> ./install | |
# Get more Package Names from the Visual Studio Marketplace URL itemName parameter. | |
# Example: https://marketplace.visualstudio.com/items?itemName=TheDan.FindChangesetByComment | |
$DownloadAndInstall= $PSScriptRoot+"\install-vsix.ps1" | |
& $DownloadAndInstall -PackageName "SergeyVlasov.VisualCommander" | |
& $DownloadAndInstall -PackageName "MBulli.SmartCommandlineArguments" | |
& $DownloadAndInstall -PackageName "mayerwin.RenameVisualStudioWindowTitle" | |
& $DownloadAndInstall -PackageName "VisualCppDevLabs.CQuickFixes2017" | |
& $DownloadAndInstall -PackageName "TomasRestrepo.Viasfora" | |
& $DownloadAndInstall -PackageName "MadsKristensen.MarkdownEditor" | |
& $DownloadAndInstall -PackageName "PeterMacej.MultilineSearchandReplace" | |
& $DownloadAndInstall -PackageName "GitHub.GitHubExtensionforVisualStudio" | |
& $DownloadAndInstall -PackageName "TheDan.FindChangesetByComment" | |
& $DownloadAndInstall -PackageName "caphyon.ClangPowerTools" |
Thank you for this! Do you know of any way I can merge this into a single script or if there is a way to push to multiple devices in an Azure environment?
There are a list of extensions that I'd like to be able to push to my dev team using a remote management tool or by uploading a script in Azure to push to specific devices.
Do I have to use Edge or Internet Explorer to sign in, or will any browser (Chrome/Firefox etc) work?
This is in regards to the comment thread about avoiding the rate limits. Thank you.
I note that on line 13 the script sets the $VSInstallDir
variable to C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service
which is correct.
However, on line 16, if this variable refers to the pathname of a folder that does not exist on the computer, it says Visual Studio InstallDir registry key missing
. I am wondering, is the error message inconsistent?
In VS 2022, the VSIXInstaller is by default located at:
C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\
If using the Developer PowerShell prompt, environment variable DevEnvDir
can be used for that path.
This doesn't quite work (running an adapted version of this code):
==> default: Running provisioner: rust_analyzer_vs (shell)...
default: Running: inline PowerShell script
default: Where-Object : The property 'class' cannot be found on this object. Verify that the property exists.
default: At C:\tmp\vagrant-shell.ps1:10 char:3
default: + Where-Object { $_.class -eq "install-button-container" } | `
default: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
default: + CategoryInfo : NotSpecified: (:) [Where-Object], PropertyNotFoundException
default: + FullyQualifiedErrorId : PropertyNotFoundStrict,Microsoft.PowerShell.Commands.WhereObjectCommand
default:
The issue is that not all links on the page have a class. Changing the Where-Object
part to:
Where-Object { $_.PSObject.Properties.Match('class').Count -and `
$_.class -eq "install-button-container" }
seems to work.
Thanks for the fix. I haven't used these scripts for a couple years, since we only use two or three extensions now, and recently we have no Internet access on our developer machines.
@mcj-codificer, Thank you. I updated the script as you suggested.