From 95215747df01bce66639805c1ffdb32c2e336e55 Mon Sep 17 00:00:00 2001 From: Andreas Jordan Date: Thu, 13 Aug 2026 17:04:25 +0200 Subject: [PATCH] Get-DbaDbExtentDiff - Leave the connection of the caller alone The command closed the connection when it was done, no matter whether it had opened it or whether it was handed one. Connect-DbaInstance now reports that through -IsNewConnectionReference, so only a connection the command opened itself is closed. The disconnect was also hiding a second problem. The query for the extents ran in the database that was examined, through the two argument form of $server.Query, and SMO leaves the connection there. Closing the connection made that invisible, because the reconnect went back to the database of the connection string. The query now names the database instead of running in it, which gives the same numbers without touching the connection. See #10554 and #10555 (do Get-DbaDbExtentDiff) Co-Authored-By: Claude Opus 5 (1M context) --- public/Get-DbaDbExtentDiff.ps1 | 24 +++++++++++++++++++----- tests/Get-DbaDbExtentDiff.Tests.ps1 | 29 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/public/Get-DbaDbExtentDiff.ps1 b/public/Get-DbaDbExtentDiff.ps1 index aae5993b8b84..3db5723ff2db 100644 --- a/public/Get-DbaDbExtentDiff.ps1 +++ b/public/Get-DbaDbExtentDiff.ps1 @@ -105,8 +105,17 @@ function Get-DbaDbExtentDiff { process { foreach ($instance in $SqlInstance) { + # Connect-DbaInstance tells us whether it opened a connection for us. We must only close what we opened + # ourselves, because closing a connection of the caller takes their session with it. See #10554. + $isNewConnection = $false + $splatConnect = @{ + SqlInstance = $instance + SqlCredential = $SqlCredential + NonPooledConnection = $true + IsNewConnectionReference = [ref]$isNewConnection + } try { - $server = Connect-DbaInstance -SqlInstance $instance -SqlCredential $SqlCredential -NonPooledConnection + $server = Connect-DbaInstance @splatConnect } catch { Stop-Function -Message "Error occurred while establishing connection to $instance" -Category ConnectionError -ErrorRecord $_ -Target $instance -Continue } @@ -133,14 +142,17 @@ function Get-DbaDbExtentDiff { #Available from 2016 SP2 if ($server.Version -ge [version]'13.0.5026') { foreach ($db in $sourcedbs) { + # The database is named in the query instead of running the query in the database, because + # running it in the database leaves the connection there and it belongs to the caller. See #10555. + $dbNameEscaped = $db.Name.Replace("]", "]]") $DBCCPageQueryDMV = " SELECT SUM(total_page_count) / 8 AS [ExtentsTotal], SUM(modified_extent_page_count) / 8 AS [ExtentsChanged], 100.0 * SUM(modified_extent_page_count)/SUM(total_page_count) AS [ChangedPerc] - FROM sys.dm_db_file_space_usage + FROM [$dbNameEscaped].sys.dm_db_file_space_usage " - $DBCCPageResults = $server.Query($DBCCPageQueryDMV, $db.Name) + $DBCCPageResults = $server.Query($DBCCPageQueryDMV) [PSCustomObject]@{ ComputerName = $server.ComputerName InstanceName = $server.ServiceName @@ -187,8 +199,10 @@ function Get-DbaDbExtentDiff { } } - # Close non-pooled connection as this is not done automatically. If it is a reused Server SMO, connection will be opened again automatically on next request. - $null = $server | Disconnect-DbaInstance + if ($isNewConnection) { + # Close non-pooled connection as this is not done automatically. + $null = $server | Disconnect-DbaInstance + } } } } \ No newline at end of file diff --git a/tests/Get-DbaDbExtentDiff.Tests.ps1 b/tests/Get-DbaDbExtentDiff.Tests.ps1 index ec211388f3a8..1532ee5ad2f9 100644 --- a/tests/Get-DbaDbExtentDiff.Tests.ps1 +++ b/tests/Get-DbaDbExtentDiff.Tests.ps1 @@ -70,6 +70,35 @@ Describe $CommandName -Tag IntegrationTests { } } + Context "The connection of the caller is left alone (#10554)" { + BeforeAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $callerServer = Connect-DbaInstance -SqlInstance $TestConfig.InstanceSingle -NonPooledConnection + $null = $callerServer.ConnectionContext.ExecuteNonQuery("CREATE TABLE #dbatoolsci_marker (id INT)") + + $null = Get-DbaDbExtentDiff -SqlInstance $callerServer -Database $dbname + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + AfterAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $null = $callerServer | Disconnect-DbaInstance + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + It "leaves the connection open, so the session survives" { + { $callerServer.ConnectionContext.ExecuteScalar("SELECT COUNT(*) FROM #dbatoolsci_marker") } | Should -Not -Throw + } + + It "leaves the connection in the database it was on" { + $callerServer.ConnectionContext.ExecuteScalar("SELECT DB_NAME()") | Should -Be "master" + } + } + Context "Gets Changed Extents for Single Database" { BeforeAll { $singleDbResults = Get-DbaDbExtentDiff -SqlInstance $TestConfig.InstanceSingle -Database $dbname