Created
September 7, 2021 09:27
-
-
Save michael-baker/4a6b9815d8aeb63bed66d1810123f9ed to your computer and use it in GitHub Desktop.
TFS Build Agent - Update Visual Studio 2019 Installation
This file contains 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
# This script queries the default agent pool, gets all agents in that pool | |
# and executes setup.exe (Visual Studio Installer) and begins a silent update of Visual Studio 2019 | |
# For TFS 2018 | |
# Get all pools | |
$pools = Invoke-RestMethod -UseDefaultCredentials -Method Get -Uri "https://tfs.com/tfs/_apis/distributedtask/pools" -UseBasicParsing | |
# Find the ID of the pool we want | |
$id = $pools.value | Where-Object { $_.name -eq "Default" } | Select-Object -ExpandProperty id -Unique | |
$agents = Invoke-RestMethod -UseDefaultCredentials -Method Get -Uri "https://tfs.com/tfs/_apis/distributedtask/pools/$id/agents?includeCapabilities=false&includeAssignedRequest=true" | |
$hosts = $agents.value | Select-Object -ExpandProperty name | % { $_.Split('_')[0] } | |
foreach ($hostComputer in $hosts) { | |
Invoke-Command -ComputerName $hostComputer -ScriptBlock { | |
function Start-Process($filePath, $argumentList) { | |
Write-information "Starting $filePath $argumentList" | |
$psi = [System.Diagnostics.ProcessStartInfo]::new() | |
$psi.CreateNoWindow = $true | |
$psi.UseShellExecute = $false | |
$psi.RedirectStandardOutput = $true | |
$psi.RedirectStandardError = $true | |
$psi.FileName = $filePath | |
$psi.Arguments = $argumentList | |
$process = [System.Diagnostics.Process]::new() | |
# Adding event handers for stdout and stderr. | |
$scripBlock = { | |
if (![String]::IsNullOrEmpty($EventArgs.Data)) | |
{ | |
Write-Host $EventArgs.Data | |
} | |
} | |
$stdOutEvent = Register-ObjectEvent ` | |
-InputObject $process ` | |
-Action $scripBlock ` | |
-EventName 'OutputDataReceived' | |
$stdErrEvent = Register-ObjectEvent ` | |
-InputObject $process ` | |
-Action $scripBlock ` | |
-EventName 'ErrorDataReceived' | |
$process.StartInfo = $psi | |
try { | |
[void]$process.Start() | |
$process.BeginOutputReadLine() | |
$process.BeginErrorReadLine() | |
while (-not $process.WaitForExit(100)) { | |
# Allow interrupts like CTRL + C by doing a non-blocking wait | |
} | |
$process.WaitForExit() | |
} finally { | |
Unregister-Event -SourceIdentifier $stdOutEvent.Name | |
Unregister-Event -SourceIdentifier $stdErrEvent.Name | |
$Global:LASTEXITCODE = $process.ExitCode | |
$process.Dispose() | |
} | |
return $process | |
} | |
$isAdmin = [Security.Principal.WindowsPrincipal]::new( | |
[Security.Principal.WindowsIdentity]::GetCurrent() | |
).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) | |
if (-not $isAdmin) { | |
throw "Not an administrator" | |
return | |
} | |
$InformationPreference = 'Continue' | |
$instance = Get-CimInstance MSFT_VSInstance | Where-Object { $_.Version -ge 16 } | Select-Object -First 1 | |
$installer = [System.IO.Path]::Combine($instance.InstallLocation, "..\..\Installer\setup.exe") | |
Write-Information "Update Visual Studio" | |
$vsUpdateProcess = Start-Process -FilePath "$installer" -ArgumentList @( | |
"update", | |
"--installPath `"$($instance.InstallLocation)`"", | |
"--force", | |
"--quiet" | |
) | |
Write-Information "vs_installer.exe exited with code: $LASTEXITCODE" | |
Write-Information "Remove Components" | |
$vsUpdateProcess = Start-Process -FilePath "$installer" -ArgumentList @( | |
"modify", | |
"--installPath `"$($instance.InstallLocation)`"", | |
"--force", | |
"--quiet", | |
"--remove Component.IncredibuildMenu", | |
"--remove Component.IncredibuildMenu" | |
) | |
Write-Information "vs_installer.exe exited with code: $LASTEXITCODE" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment