Skip to content

[FEATURE] Server Version - Update multiple or all servers in parallel where old version is found #815

Description

@MariusNe87

Which component(s) does this affect?

  • Full Dashboard
  • Lite
  • SQL collection scripts
  • Installer
  • Documentation

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

Activity

  1. erikdarlingdata commented on Apr 9, 2026

    @erikdarlingdata
    Owner

    @MariusNe87 this is a neat idea. Did you want to contribute code for it?

  2. MariusNe87 commented on Apr 9, 2026

    @MariusNe87
    Author

    i wish i could - Haha, I’m not a coder — I’m just the end user doing quality assurance by clicking random buttons 😉

  3. erikdarlingdata commented on Apr 9, 2026

    @erikdarlingdata
    Owner

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

  4. MariusNe87 commented on Apr 9, 2026

    @MariusNe87
    Author

    i used this as a workaround already ;-) a GUI option would be nicer tough

  5. erikdarlingdata commented on Apr 10, 2026

    @erikdarlingdata
    Owner

    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 ManageServersWindow that:

    1. Checks all servers for their installed version (in parallel)
    2. Shows which are outdated
    3. Upgrades all outdated servers in parallel with a progress panel

    This stays in ManageServersWindow rather than AddServerDialog — 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 CheckUpdatesButton at 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 ServersDataGrid binds to ServerConnection objects. 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 ServerVersionInfo wrapper 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_Click in AddServerDialog.xaml.cs (line 563) shows the exact sequence of InstallationService calls needed. Extract that into a reusable helper method or just replicate the call pattern.


    Files to Modify

    File What to Change
    Dashboard/ManageServersWindow.xaml Add version column, "Check All Versions" button, "Upgrade All Outdated" button, progress panel
    Dashboard/ManageServersWindow.xaml.cs Add CheckAllVersions_Click, UpgradeAll_Click, version tracking

    Files to Optionally Create

    File Purpose
    Dashboard/Models/ServerVersionInfo.cs Wrapper 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)
  6. erikdarlingdata commented on Jul 25, 2026

    @erikdarlingdata
    Owner

    Removing the help wanted and good first issue labels, 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 on dev, 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, InstalledVersion is 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.

  7. erikdarlingdata commented on Jul 26, 2026

    @erikdarlingdata
    Owner

    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 to deprecated/ 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) InstalledVersion is 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 wanted and good first issue labels 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions