Import-DbaSpConfigure - Leave the connection of the caller alone and make the migration work again - #10575
Open
andreasjordan wants to merge 3 commits into
Open
Conversation
The command closed every connection it used in its end block, no matter who opened it. On a session-scoped connection that takes the session of the caller with it. Both connections are now reported by Connect-DbaInstance through IsNewConnectionReference, and only a connection opened here is closed. While in there: the file import set show advanced options on the Configuration collection without ever calling Alter(), so it never reached the instance but left a pending change on the server object of the caller. The file written by Export-DbaSpConfigure sets the option itself, so the two lines are gone. (do Import-DbaSpConfigure) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three things the CI run found that the lab instance could not: - The file import warns once per line the edition does not allow to be set, so the warning about the restart is the last one, not the only one. - Every AfterAll has to remove EnableException again. The hashtable is shared by the whole file, so the next context inherited it and the command threw where the test expected a warning. - The copy fails on SQL Server 2022 and newer before it is finished, because the command assigns every property of the destination even when the value does not change and Configuration.Alter() then rejects an option of that edition. That is a separate defect. The connections of the caller have to survive it either way, so the test catches the failure and asserts that. The last context now imports the file by instance name instead of copying by instance name, which is the path where the command owns the connection. (do Import-DbaSpConfigure) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… again
The migration was broken on SQL Server 2022 and newer, even when copying an
instance onto itself:
Alter failed.
Changes to server configuration option 'suppress recovery model errors'
are not supported in this edition of SQL Server.
Four things behind that, all fixed here:
- Every option of the destination was assigned, even when the value was the
one already set. That marks the property as changed, and Alter() then sends
the whole configuration in one batch, which fails as a whole as soon as one
option is not supported by the edition. Only options that really differ are
touched now, and each one is altered on its own so a failure stays with it.
- The Alter that was meant to switch 'show advanced options' on at the
destination was run against the source, so the option never got there.
- The failure of the batch Alter was swallowed as "needs restart". Whether a
restart is needed is now read from IsDynamic of the option that changed, and
a failure is reported as the warning it always claimed to be.
- 'show advanced options' was left at 0 on both instances instead of being put
back the way it was found. It is restored in a finally block, so an option
that cannot be set does not leave it switched on either.
Also, the two Stop-Function calls of the copy path passed an undefined $server
as their target, and the .OUTPUTS block described a boolean the command has
never returned.
(do Import-DbaSpConfigure)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of Change
Purpose
Two things, in the same command, because splitting them would have left one half merged and the other not.
1. The command closed connections it did not own. Sixth command of the inventory in #10554:
Verified with
Connect-DbaInstance -NonPooledConnectionand a temp table as the session marker: the file import and the server copy each closed the connection of the caller and took the session with it.2. The migration between two instances was broken on SQL Server 2022 and newer, even copying an instance onto itself. Reproduced on Developer Edition 16.0.4255.1:
Approach
Connection ownership
All three connect calls request
IsNewConnectionReference, and theendblock only closes what the command opened itself. The variables default to$false, so a path that never connects cannot close anything.The migration
Four separate defects, all of them in the copy loop:
Configuration.Alter()then sends the whole configuration in one batch - which fails as a whole as soon as one option is not supported by the edition. Only options that really differ are touched now, and each is altered on its own, so a failure stays with that option instead of poisoning everything after it. The property is refreshed after a failure, because a pending change survives a failedAlter()and fails again with the next one.:182altered the source where it meant the destination, soshow advanced optionsnever reached the destination.Alter()was swallowed as$needsrestart = $true. Whether a restart is needed is now read fromIsDynamicof the option that actually changed, and a failure is reported as the warning it always claimed to be.show advanced optionswas left at 0 on both instances instead of being put back the way it was found -Export-DbaSpConfiguredoes restore it. It is restored in afinally, so an option that cannot be set does not leave it switched on either.The file import
show advanced optionswas set on the Configuration collection without ever callingAlter(), so it never reached the instance - the file written byExport-DbaSpConfiguresets it itself. What the two lines did do was leave a pending change on the server object of the caller, which their nextAlter()would have applied:Both lines are gone.
While in there
The two
Stop-Functioncalls of the copy path passed an undefined$serveras their target, and the.OUTPUTSblock described a boolean this command has never returned.Commands to test
A real migration, SQL 2025 to SQL 2022, which threw before this change:
Exactly the one option the two instances disagreed about, the restart warning because
scan for startup procsis not dynamic, andshow advanced optionsleft as it was on both sides.Tests
tests\Import-DbaSpConfigure.Tests.ps1had no integration tests at all. Four contexts were added, all onInstanceSingle:show advanced optionsas it found it, does not warn for a dynamic option, and leaves both connections and both sessions aloneThe copy test needs two server objects that disagree without needing two instances: the source is connected while the option still holds the value to be copied, the instance is then changed, and only then is the destination connected. SMO reads the configuration once per server object, so each keeps the value it saw. Nothing but that one option can change, and it is restored afterwards.
14 tests, all passing on SQL 2019 and on SQL 2022. Reverting the command shows what they are worth:
🤖 Generated with Claude Code