Last active
March 6, 2025 22:06
-
-
Save jschlackman/dfd06a69250606edfa080aae503aecfc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Starts automatic update for all installed Visual Studio instances. | |
.DESCRIPTION | |
Gets details of all current Visual Studio installs on this machine and attempts to run the updater for each installation found. | |
This script can be run using Task Scheduler or an RMM to periodicially check for and apply Visual Studio updates. | |
Author: James Schlackman <[email protected]> | |
Last Modified: March 6 2025 | |
.PARAMETER ForceUpdate | |
Whether to forcibly close any running processes if they need updating. | |
.LINK | |
https://learn.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances | |
.LINK | |
https://learn.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio | |
#> | |
#Requires -RunAsAdministrator | |
Param( | |
[Parameter()] [Switch] $ForceUpdate | |
) | |
# Set update param according to whether forced update flag is set | |
If ($ForceUpdate) { | |
Write-Warning 'Forced update is enabled. Any running instances of Visual Studio will be closed without prompting.' | |
$updateParam = '--force' | |
} Else { | |
$updateParam = '--norestart' | |
} | |
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" | |
# If vswhere command was found, run it and parse the output | |
If (Test-Path $vsWhere) { | |
$vsInstalls = (. $vsWhere -prerelease -format json) | ConvertFrom-Json | |
} Else { | |
$vsInstalls = $null | |
Write-Warning 'vswhere.exe not found.' | |
} | |
# If vshwere reports at least one installed instance | |
If ($vsInstalls) { | |
$installFields = 'displayName', 'installationName', 'installationVersion', 'isRebootRequired' | |
Write-Host ('Installs found: {0}' -f $vsInstalls.Count) | |
Write-Host ($vsInstalls | Select $installFields | Out-String) | |
# Now run the updater for each installation | |
$vsInstalls | Where-Object {$_} | ForEach-Object { | |
Write-Host ("`nStarting update for {0}, version {1} (last updated {2})`n" -f $_.displayName, $_.installationVersion, (Get-Date($_.updateDate)).ToShortDateString()) -ForegroundColor Cyan | |
$updateTask = Start-Process -PassThru -Wait -FilePath $_.properties.setupEngineFilePath -ArgumentList ('update --quiet {0} --installPath "{1}"' -f $updateParam, $_.installationPath) | |
Write-Host | |
$resultText = "Updater exited with code {0} (Start Time: {1}, End Time: {2})`n" -f $updateTask.ExitCode, $updateTask.StartTime, $updateTask.ExitTime | |
# Output update task summary | |
If ($updateTask.ExitCode -eq 0) { | |
Write-Host $resultText -ForegroundColor Green | |
} Else { | |
Write-Warning $resultText | |
} | |
} | |
# Now get installed version info again | |
$vsInstalls = (. $vsWhere -prerelease -format json) | ConvertFrom-Json | |
Write-Host 'Update results:' -ForegroundColor Cyan | |
Write-Host ($vsInstalls | Select $installFields | Out-String) | |
If ($vsInstalls.isRebootRequired -contains $true) { | |
Write-Warning 'A reboot is required but has been suppressed' | |
} | |
} Else { | |
Write-Host 'No instances of Visual Studio found.' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment