dataplat / dbatools

🚀 SQL Server automation and instance migrations have never been safer, faster or freer

Home Page:https://dbatools.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Restore-DbaDatabase fails when using server-SMO as SqlInstance

andreasjordan opened this issue · comments

Verified issue does not already exist?

I have searched and found no existing issue

What error did you receive?

Failure | Login failed for user 'labdom\User'.

Steps to Reproduce

# This needs to fail to test that the current user can not connect to the SQL Server:
$null = Connect-DbaInstance -SqlInstance SQL01
# We need a sysadmin login (I tested with a windows login, should also work with a sql login)
$sqlAdminCredential = Get-Credential -Message 'sysadmin'
# We open a connection (a pooled connection this time):
$serverPooled = Connect-DbaInstance -SqlInstance SQL01 -SqlCredential $sqlAdminCredential
# We try the restore that failes with "Failure | Login failed for user 'labdom\User'.":
$null = Restore-DbaDatabase -SqlInstance $serverPooled -Path \\fs\Software\SQLServer\SampleDatabases\AdventureWorks2022.bak -DatabaseName AW1 -ReplaceDbNameInFile
# We open a new connection (a non pooled connection this time):)
$serverNonPooled = Connect-DbaInstance -SqlInstance SQL01 -SqlCredential $sqlAdminCredential -NonPooledConnection
# We can now run the restore successfully:
$null = Restore-DbaDatabase -SqlInstance $serverNonPooled -Path \\fs\Software\SQLServer\SampleDatabases\AdventureWorks2022.bak -DatabaseName AW1 -ReplaceDbNameInFile
# But a second restore failes with "Failure | Login failed for user 'labdom\User'.":
$null = Restore-DbaDatabase -SqlInstance $serverNonPooled -Path \\fs\Software\SQLServer\SampleDatabases\AdventureWorks2022.bak -DatabaseName AW2 -ReplaceDbNameInFile

Please confirm that you are running the most recent version of dbatools

Yes.

Other details or mentions

I will open a PR to fix the issue shortly.

What PowerShell host was used when producing this error

Windows PowerShell ISE (powershell_ise.exe)

PowerShell Host Version

PS5.1

SQL Server Edition and Build number

SQL 2022

.NET Framework Version

Maybe some other users can try to reproduce this:

$serverPooled = Connect-DbaInstance -SqlInstance SQL01 -SqlCredential $sqlAdminCredential
$serverPooled.ConnectionContext.CurrentDatabase   # returns $null
$serverPooled.ConnectionContext.ProcessID         # returns the spid without issung a query against the sql server
$serverPooled.ConnectionContext.CurrentDatabase   # returns "master"

As we need ConnectionContext.CurrentDatabase insinde of Connect-DbaInstance to test if the database context changes, it should not be null.

How is it related to this issue: In the first case, the database context is copied as ConnectionContext.CurrentDatabase is not "master" as needed for Restore-DbaDatabase. Copying the context does not work for windows logins (as I use in the demo).

How to fix it: we should get the spid right after opening the connection. I'll open a PR for Connect-DbaInstance...

Getting the spid after opening the connection does not help as the pooled connection will be closed immediatly after. We have to get the spid to open a connection just before using ConnectionContext.CurrentDatabase.

The pull request #9308 seems to fix both parts of the issue, so it now works with pooled and non pooled connections.