-
-
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" |
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.
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.