Skip to content

Commit

Permalink
Connect-SQL: Add Wait for Online SMO Status (#1916)
Browse files Browse the repository at this point in the history
- SqlServerDsc.Common:
  - `Connect-SQL` - Function will now wait for the SMO Status property to be
    'Online' or throw an exception if time exceeds the statement timeout.
  • Loading branch information
Kreby authored Apr 25, 2023
1 parent 43a080e commit 8106945
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- SqlSetup
- Update to support checking non-supported features using the command
`SqlDscIsSupportedFeature` ([issue #1872](https://github.com/dsccommunity/SqlServerDsc/issues/1872)).
- Update SqlServerDsc.Common Module:
- `Connect-SQL` - Function will now wait for the SMO Status property to be
'Online' or throw an exception if time exceeds the statement timeout.
- SqlRS
- Now uses the command `Invoke-SqlDscQuery` instead of `Invoke-SqlCmd`
([issue #1917](https://github.com/dsccommunity/SqlServerDsc/issues/1917)).
Expand Down
46 changes: 35 additions & 11 deletions source/Modules/SqlServerDsc.Common/SqlServerDsc.Common.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ function Connect-SQL
$sqlConnectionContext = $sqlServerObject.ConnectionContext
$sqlConnectionContext.ServerInstance = $databaseEngineInstance
$sqlConnectionContext.StatementTimeout = $StatementTimeout
$sqlConnectionContext.ConnectTimeout = $StatementTimeout
$sqlConnectionContext.ApplicationName = 'SqlServerDsc'

if ($Encrypt.IsPresent)
Expand Down Expand Up @@ -563,15 +564,42 @@ function Connect-SQL

try
{
$onlineStatus = 'Online'
$connectTimer = [System.Diagnostics.StopWatch]::StartNew()
$sqlConnectionContext.Connect()

$instanceStatus = $sqlServerObject.Status

if ($instanceStatus)
<#
The addition of the ConnetTimeout property to the ConnectionContext will force the
Connect() method to block until successful. THe SMO object's Status property may not
report 'Online' immediately eventhough the Connect() was successful. The loop is to
ensure the SMO's Status property was been updated.
#>
$sleepInSeconds = 2
do
{
# Property Status is of type Enum ServerStatus, we return the string equivalent.
$instanceStatus = $instanceStatus.ToString()
}
$instanceStatus = $sqlServerObject.Status
if ([System.String]::IsNullOrEmpty($instanceStatus))
{
$instanceStatus = 'Unknown'
}
else
{
# Property Status is of type Enum ServerStatus, we return the string equivalent.
$instanceStatus = $instanceStatus.ToString()
}

if ($instanceStatus -eq $onlineStatus)
{
break
}

Write-Debug -Message (
$script:localizedData.WaitForDatabaseEngineInstanceStatus -f $instanceStatus, $onlineStatus, $sleepInSeconds
)

Start-Sleep -Seconds $sleepInSeconds
$sqlServerObject.Refresh()
} while ($connectTimer.Elapsed.TotalSeconds -lt $StatementTimeout)

if ($instanceStatus -match '^Online$')
{
Expand All @@ -583,11 +611,6 @@ function Connect-SQL
}
else
{
if ([System.String]::IsNullOrEmpty($instanceStatus))
{
$instanceStatus = 'Unknown'
}

$errorMessage = $script:localizedData.DatabaseEngineInstanceNotOnline -f @(
$databaseEngineInstance,
$instanceStatus
Expand Down Expand Up @@ -632,6 +655,7 @@ function Connect-SQL
}
finally
{
$connectTimer.Stop()
<#
Connect will ensure we actually can connect, but we need to disconnect
from the session so we don't have anything hanging. If we need run a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ ConvertFrom-StringData @'
FailedToLoadAssembly = Failed to load the assembly '{0}'. (SQLCOMMON0069)
FailedToObtainServerInstance = Failed to obtain a SQL Server instance with name '{0}' on server '{1}'. Ensure the SQL Server instance exists on the server and that the 'SQLServer' module references a version of the 'Microsoft.SqlServer.Management.Smo.Wmi' library that supports the version of the SQL Server instance. (SQLCOMMON0070)
DatabaseEngineInstanceNotOnline = The SQL instance '{0}' was expected to have the status 'Online', but had status '{1}'. (SQLCOMMON0071)
WaitForDatabaseEngineInstanceStatus = The SQL instance status is '{0}' expected '{1}', waiting {2} seconds. (SQLCOMMON0072)
'@
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ ConvertFrom-StringData @'
FailedToLoadAssembly = Failed to load the assembly '{0}'. (SQLCOMMON0069)
FailedToObtainServerInstance = Failed to obtain a SQL Server instance with name '{0}' on server '{1}'. Ensure the SQL Server instance exists on the server and that the 'SQLServer' module references a version of the 'Microsoft.SqlServer.Management.Smo.Wmi' library that supports the version of the SQL Server instance. (SQLCOMMON0070)
DatabaseEngineInstanceNotOnline = The SQL instance '{0}' was expected to have the status 'Online', but had status '{1}'. (SQLCOMMON0071)
WaitForDatabaseEngineInstanceStatus = The SQL instance status is '{0}' expected '{1}', waiting {2} seconds. (SQLCOMMON0072)
'@
3 changes: 3 additions & 0 deletions tests/Unit/SqlServerDsc.Common.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2364,6 +2364,7 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' {
Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru |
Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru |
Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru |
Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru |
Add-Member -MemberType NoteProperty -Name EncryptConnection -Value $false -PassThru |
Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru |
Add-Member -MemberType ScriptMethod -Name Disconnect -Value {
Expand Down Expand Up @@ -2642,6 +2643,7 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' {
Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru |
Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru |
Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru |
Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru |
Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru |
Add-Member -MemberType ScriptMethod -Name Disconnect -Value {
return $true
Expand Down Expand Up @@ -2688,6 +2690,7 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' {
Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru |
Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru |
Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru |
Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru |
Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru |
Add-Member -MemberType ScriptMethod -Name Disconnect -Value {
return $true
Expand Down

0 comments on commit 8106945

Please sign in to comment.