Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions public/Install-DbaMaintenanceSolution.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,17 @@ function Install-DbaMaintenanceSolution {
}

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
}
Expand Down Expand Up @@ -558,7 +567,9 @@ function Install-DbaMaintenanceSolution {

if ($Pscmdlet.ShouldProcess($instance, "Dropping all objects created by Ola's Maintenance Solution")) {
Write-ProgressHelper -ExcludePercent -Message "Dropping objects created by Ola's Maintenance Solution"
$null = $db.Invoke($cleanupQuery)
# Invoke-DbaQuery names the database instead of running on the connection of the caller, which
# $db.Invoke() would leave in that database. This is how the installation below runs as well.
$null = Invoke-DbaQuery -SqlInstance $server -Database $Database -Query $cleanupQuery -EnableException
}

# Remove Ola's Jobs
Expand Down Expand Up @@ -891,8 +902,10 @@ function Install-DbaMaintenanceSolution {
}
}

# 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
}
}

Write-ProgressHelper -ExcludePercent -Message "Installation complete"
Expand Down
37 changes: 37 additions & 0 deletions tests/Install-DbaMaintenanceSolution.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,43 @@ Describe $CommandName -Tag IntegrationTests {
}
}

Context "The connection of the caller is left alone (#10554)" {
BeforeAll {
$PSDefaultParameterValues["*-Dba*:EnableException"] = $true

$callerServer = Connect-DbaInstance -SqlInstance $TestConfig.InstanceMulti1 -NonPooledConnection
$null = $callerServer.ConnectionContext.ExecuteNonQuery("CREATE TABLE #dbatoolsci_marker (id INT)")

# ReplaceExisting takes the code path that drops the existing objects, jobs are left out so that no
# SQL Agent command touches the connection - those are separate commands, see #10555.
$splatInstall = @{
SqlInstance = $callerServer
Database = "tempdb"
BackupLocation = "NUL"
ReplaceExisting = $true
}
$null = Install-DbaMaintenanceSolution @splatInstall

$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 "Additional backup parameters all enabled" {
AfterEach {
Invoke-DbaQuery -SqlInstance $TestConfig.InstanceMulti2 -Query $jobStep.Command -NoExec -EnableException
Expand Down