Repository navigation
[FEATURE] Server Version - Update multiple or all servers in parallel where old version is found #815
Description
Activity
@MariusNe87 this is a neat idea. Did you want to contribute code for it?
i wish i could - Haha, I’m not a coder — I’m just the end user doing quality assurance by clicking random buttons 😉
@MariusNe87 you may want to look at using the CLI installer to do this, as it can be called in a script with a list of server names.
i used this as a workaround already ;-) a GUI option would be nicer tough
Implementation Guide: Bulk Server Upgrades
The current flow is: select one server in Manage Servers, click "Check Server Version", confirm the dialog, wait, repeat. This feature adds a "Check All Versions" / "Upgrade All" flow that runs in parallel.
The good news:
InstallationService.ExecuteAllUpgradesAsync()is already fully async and each server's upgrade is independent — parallel execution is safe. The main work is UI.Note: If you have Claude Code (the CLI tool), you can hand it this guide and it will implement most of this for you.
Approach
Add an "Upgrade All Outdated" button to
ManageServersWindowthat:- Checks all servers for their installed version (in parallel)
- Shows which are outdated
- Upgrades all outdated servers in parallel with a progress panel
This stays in
ManageServersWindowrather thanAddServerDialog— the edit dialog is a single-server workflow.
1. UI Changes — ManageServersWindow.xaml
Add a version column to
ServersDataGrid(after the "Last Connected" column at line 76):<DataGridTextColumn Header="Monitor Version" Binding="{Binding InstalledVersion}" Width="110"/>
Add buttons to the button bar (after
CheckUpdatesButtonat line 93):<Button x:Name="CheckAllVersionsButton" Content="Check All Versions" Width="130" Height="30" Margin="0,0,8,0" Click="CheckAllVersions_Click"/> <Button x:Name="UpgradeAllButton" Content="Upgrade All Outdated" Width="140" Height="30" Margin="0,0,8,0" Click="UpgradeAll_Click" Visibility="Collapsed"/>
Add a progress panel below the DataGrid (new row in the grid, between the server list and buttons):
<Border x:Name="UpgradeProgressPanel" Grid.Row="2" Visibility="Collapsed" Background="{DynamicResource BackgroundLightBrush}" CornerRadius="4" Padding="12" Margin="0,8,0,0"> <StackPanel> <TextBlock x:Name="UpgradeProgressText" TextWrapping="Wrap" Foreground="{DynamicResource ForegroundBrush}" Margin="0,0,0,6"/> <ProgressBar x:Name="UpgradeProgressBar" Height="6" Margin="0,0,0,6" Foreground="{DynamicResource AccentBrush}" Background="{DynamicResource BackgroundLighterBrush}"/> <TextBox x:Name="UpgradeLogTextBox" FontFamily="Consolas" FontSize="11" MaxHeight="150" IsReadOnly="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Background="{DynamicResource BackgroundDarkBrush}" Foreground="{DynamicResource ForegroundBrush}" Margin="0,0,0,6"/> </StackPanel> </Border>
Adjust the Grid.RowDefinitions to add a row for this panel.
Move the button bar to Grid.Row="3".2. Data Model — Add InstalledVersion to Display
The
ServersDataGridbinds toServerConnectionobjects. Add a display property to track the detected version.Option A (simple): Add a
Dictionary<string, string?>in the code-behind to map server IDs to versions, and use a value converter or manual column update.Option B (cleaner): Create a
ServerVersionInfowrapper class:public class ServerVersionInfo { public ServerConnection Server { get; set; } public string? InstalledVersion { get; set; } public bool NeedsUpgrade { get; set; } public string VersionDisplay => InstalledVersion ?? "—"; }
Bind the DataGrid to
List<ServerVersionInfo>instead of the raw server list.3. Check All Versions — ManageServersWindow.xaml.cs
private async void CheckAllVersions_Click(object sender, RoutedEventArgs e) { CheckAllVersionsButton.IsEnabled = false; CheckAllVersionsButton.Content = "Checking..."; try { string appVersion = GetAppVersion(); // extract the existing version logic into a helper // Check all servers in parallel var tasks = _serverManager.Servers.Select(async server => { try { var installed = await _serverManager.GetInstalledVersionAsync(server); bool needsUpgrade = false; if (installed != null && Version.TryParse(Normalize(installed), out var installedVer) && Version.TryParse(Normalize(appVersion), out var appVer)) { needsUpgrade = installedVer < appVer; } return new ServerVersionInfo { Server = server, InstalledVersion = installed != null ? Normalize(installed) : null, NeedsUpgrade = needsUpgrade }; } catch { return new ServerVersionInfo { Server = server, InstalledVersion = null, NeedsUpgrade = false }; } }); var results = await Task.WhenAll(tasks); // Update the grid with version info // Show/hide UpgradeAllButton based on whether any need upgrades int outdatedCount = results.Count(r => r.NeedsUpgrade); if (outdatedCount > 0) { UpgradeAllButton.Visibility = Visibility.Visible; UpgradeAllButton.Content = $"Upgrade {outdatedCount} Server{(outdatedCount > 1 ? "s" : "")}"; } } finally { CheckAllVersionsButton.IsEnabled = true; CheckAllVersionsButton.Content = "Check All Versions"; } }
4. Upgrade All — ManageServersWindow.xaml.cs
private async void UpgradeAll_Click(object sender, RoutedEventArgs e) { // Confirm with the user var confirm = MessageBox.Show( $"Upgrade {outdatedCount} server(s) to v{appVersion}?\n\n" + "All servers will be upgraded in parallel.", "Confirm Bulk Upgrade", MessageBoxButton.YesNo, MessageBoxImage.Question); if (confirm != MessageBoxResult.Yes) return; UpgradeProgressPanel.Visibility = Visibility.Visible; UpgradeAllButton.IsEnabled = false; // Run upgrades in parallel using InstallationService directly // For each outdated server: // 1. Build connection string (from ServerConnection) // 2. Call InstallationService.ExecuteAllUpgradesAsync() // 3. Then call InstallationService.ExecuteInstallationAsync() // 4. Report progress per-server to the log textbox // // Use Task.WhenAll() — each server is independent // Update progress bar: completed / total // Append per-server results to UpgradeLogTextBox // After all complete: show summary UpgradeProgressText.Text = $"Complete: {successCount} succeeded, {failCount} failed"; }
The key insight: the existing
InstallOrUpgrade_ClickinAddServerDialog.xaml.cs(line 563) shows the exact sequence ofInstallationServicecalls needed. Extract that into a reusable helper method or just replicate the call pattern.
Files to Modify
File What to Change Dashboard/ManageServersWindow.xamlAdd version column, "Check All Versions" button, "Upgrade All Outdated" button, progress panel Dashboard/ManageServersWindow.xaml.csAdd CheckAllVersions_Click,UpgradeAll_Click, version trackingFiles to Optionally Create
File Purpose Dashboard/Models/ServerVersionInfo.csWrapper class for server + version display (if using Option B) This is a UI-only change — no new SQL scripts, no new collectors, no install changes. All the upgrade infrastructure already exists.
Testing Checklist
- Check All Versions: Click the button, verify all servers are checked in parallel and versions appear in the grid
- Mixed states: Some servers current, some outdated, some unreachable — verify all three states display correctly
- Upgrade All: Click upgrade, verify all outdated servers upgrade in parallel
- Progress reporting: Verify per-server progress appears in the log panel
- Partial failure: One server is unreachable during upgrade — verify others still complete and the failure is reported
- Cancellation: Close the window during upgrades — verify no orphaned tasks or half-upgraded servers
- Post-upgrade: After upgrading, "Check All Versions" again — all should show current
- Single server still works: Verify the existing single-server "Check Server Version" button still works as before
- No outdated servers: Click "Check All Versions" when all are current — "Upgrade All" button should not appear
- Authentication types: Test with Windows Auth, SQL Auth, and Entra MFA servers in the mix
- Azure SQL DB: Servers without SQL Agent should upgrade cleanly (the collector skip logic is in the SQL scripts)
- addedhelp wantedExtra attention is neededExtra attention is neededgood first issueGood for newcomersGood for newcomers
on Apr 10, 2026 - removedhelp wantedExtra attention is neededExtra attention is neededgood first issueGood for newcomersGood for newcomers
on Jul 25, 2026 Removing the
help wantedandgood first issuelabels, and flagging this for a product decision.Why the labels had to come off: this feature targets the Full Dashboard's ManageServers window and the CLI Installer, both of which were retired to
deprecated/in #1612. PR #963 was a complete implementation of exactly what was asked for, built from a fork correctly based ondev, and it went through several rounds of review before being closed unmerged on 2026-07-24 because the paths it builds on are frozen and the branch can no longer merge against the current layout.Leaving it advertised as a good first issue after that means the next contributor can repeat that work and hit the same wall. That already cost @mas-mark-y a full implementation plus review cycles, and it should not happen twice.
There is a case that the request is now moot rather than merely unbuilt. The per-server SQL install-and-version concept only ever existed in
deprecated/Installer.Core/InstallationService.cs. In both shipping apps,InstalledVersionis just the app's own version stamped onto each grid row (Lite/Windows/ManageServersWindow.xaml.cs:43,Darling/PerformanceMonitor.Darling.Viewer/ManageServersWindow.xaml.cs:83) — there is no server-side install left to bulk-upgrade.Worth stating explicitly since the two get conflated: #1549 "Add Multiple Servers" does not satisfy this. That is bulk onboarding; this is bulk upgrading of servers already added. Different features.
Erik's call on whether to close as obsolete or re-scope it for the Lite/Darling world.
Closing as obsolete rather than unbuilt, because the thing it targets no longer exists.
@MariusNe87 — the request was sound and @mas-mark-y built it properly as PR #963, from a fork correctly based on
dev, and took several rounds of review. It was closed unmerged on 2026-07-24 because the Full Dashboard's ManageServers window and the CLI Installer it builds on were retired todeprecated/in #1612, so the branch can no longer merge against the current layout. That outcome is on the project's timing, not the contribution.Why it is now moot rather than merely unbuilt: the per-server SQL install-and-version concept only ever existed in the CLI Installer. In both shipping apps (Lite and the Darling viewer)
InstalledVersionis just the app's own version stamped onto each grid row — there is no server-side install left to bulk-upgrade. So there is nothing for a "upgrade all servers where an old version is found" feature to act on.Worth stating plainly since the two get conflated: #1549 "Add Multiple Servers" does not supersede this. That is bulk onboarding; this was bulk upgrading of servers already added. Different features.
The
help wantedandgood first issuelabels were removed earlier so nobody else repeats that work and hits the same wall.If bulk anything against the Lite/Darling fleet becomes useful later, it is worth a fresh issue scoped to those apps rather than reviving this one.
Which component(s) does this affect?
Problem Statement
upgrading 1 by 1 is taking much time.
Proposed Solution
Would be nice to be able to select / upgrade multiple servers at once , as upgrading 1 by 1 is taking much time.
Use Case
i guess its self explaining
Alternatives Considered
No response
Additional Context
No response