diff --git a/.github/workflows/xplat-import.yml b/.github/workflows/xplat-import.yml
index ac61736498..dcf8904f0f 100644
--- a/.github/workflows/xplat-import.yml
+++ b/.github/workflows/xplat-import.yml
@@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, windows-latest, macOS-latest]
+ os: [ubuntu-latest, windows-latest, macOS-latest, macOS-14]
steps:
- uses: actions/checkout@v3
diff --git a/appveyor.yml b/appveyor.yml
index fde3c68d75..df77dc5a69 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,7 +8,7 @@ build_script:
- ps: choco install dotnetcore-sdk | Out-String | Out-Null
# - ps: Push-Location bin\projects\dbatools; dotnet build ;Pop-Location
-version: 0.9.{build}
+version: 2.1.{build}
cache:
- C:\ProgramData\chocolatey\bin -> appveyor.yml
@@ -23,7 +23,7 @@ clone_depth: 100
# Set build info
environment:
environment: development
- version: 0.9.$(appveyor_build_number)
+ version: 2.1.$(appveyor_build_number)
appveyor_rdp_password: 2odCuiKmYiem
azurepasswd1:
secure: ZnF3fWSDfHraMCWlHaekvWrXf3sDqY5M28HMK4236PBbNSoqP29wEhsWMQioSSYGomzgIp9vuiwR8Fc9ViNLoqq0bVcErxEojBFTaPMEzOg2ZwO9OnOTiuUEc5JkoLBv6rEBBWef/DvkFfhr1r0K0xQu6OAPYHVTCRajTZbBRNfCTUM2X2o41t+cSa7681rtnJQnB/8cAfVVnPtJ+97s8w==
diff --git a/bin/dbatools-index.json b/bin/dbatools-index.json
index d78d379354..ab6987c2f2 100644
Binary files a/bin/dbatools-index.json and b/bin/dbatools-index.json differ
diff --git a/bin/diagnosticquery/SQLServerDiagnosticQueries_2012.sql b/bin/diagnosticquery/SQLServerDiagnosticQueries_2012.sql
index 8e87e2c58b..dc8d0ce1b7 100644
--- a/bin/diagnosticquery/SQLServerDiagnosticQueries_2012.sql
+++ b/bin/diagnosticquery/SQLServerDiagnosticQueries_2012.sql
@@ -1,7 +1,7 @@
-- SQL Server 2012 Diagnostic Information Queries
-- Glenn Berry
--- Last Modified: May 2, 2024
+-- Last Modified: June 3, 2024
-- https://glennsqlperformance.com/
-- https://sqlserverperformance.wordpress.com/
-- YouTube: https://bit.ly/2PkoAM1
diff --git a/bin/diagnosticquery/SQLServerDiagnosticQueries_2014.sql b/bin/diagnosticquery/SQLServerDiagnosticQueries_2014.sql
index 36f5960379..72c237e65f 100644
--- a/bin/diagnosticquery/SQLServerDiagnosticQueries_2014.sql
+++ b/bin/diagnosticquery/SQLServerDiagnosticQueries_2014.sql
@@ -1,7 +1,7 @@
-- SQL Server 2014 Diagnostic Information Queries
-- Glenn Berry
--- Last Modified: May 2, 2024
+-- Last Modified: June 3, 2024
-- https://glennsqlperformance.com/
-- https://sqlserverperformance.wordpress.com/
-- YouTube: https://bit.ly/2PkoAM1
diff --git a/bin/diagnosticquery/SQLServerDiagnosticQueries_2016.sql b/bin/diagnosticquery/SQLServerDiagnosticQueries_2016.sql
index 445be6a9ac..fb8e02dc53 100644
--- a/bin/diagnosticquery/SQLServerDiagnosticQueries_2016.sql
+++ b/bin/diagnosticquery/SQLServerDiagnosticQueries_2016.sql
@@ -1,7 +1,7 @@
-- SQL Server 2016 Diagnostic Information Queries
-- Glenn Berry
--- Last Modified: May 2, 2024
+-- Last Modified: June 3, 2024
-- https://glennsqlperformance.com/
-- https://sqlserverperformance.wordpress.com/
-- YouTube: https://bit.ly/2PkoAM1
diff --git a/bin/diagnosticquery/SQLServerDiagnosticQueries_2016SP2.sql b/bin/diagnosticquery/SQLServerDiagnosticQueries_2016SP2.sql
index 639d7ad2d8..7232846b1e 100644
--- a/bin/diagnosticquery/SQLServerDiagnosticQueries_2016SP2.sql
+++ b/bin/diagnosticquery/SQLServerDiagnosticQueries_2016SP2.sql
@@ -1,7 +1,7 @@
-- SQL Server 2016 SP2 Diagnostic Information Queries
-- Glenn Berry
--- Last Modified: May 2, 2024
+-- Last Modified: June 3, 2024
-- https://glennsqlperformance.com/
-- https://sqlserverperformance.wordpress.com/
-- YouTube: https://bit.ly/2PkoAM1
diff --git a/bin/diagnosticquery/SQLServerDiagnosticQueries_2017.sql b/bin/diagnosticquery/SQLServerDiagnosticQueries_2017.sql
index 90c9e603c3..23d11e79de 100644
--- a/bin/diagnosticquery/SQLServerDiagnosticQueries_2017.sql
+++ b/bin/diagnosticquery/SQLServerDiagnosticQueries_2017.sql
@@ -1,7 +1,7 @@
-- SQL Server 2017 Diagnostic Information Queries
-- Glenn Berry
--- Last Modified: May 2, 2024
+-- Last Modified: June 3, 2024
-- https://glennsqlperformance.com/
-- https://sqlserverperformance.wordpress.com/
-- YouTube: https://bit.ly/2PkoAM1
diff --git a/bin/diagnosticquery/SQLServerDiagnosticQueries_2019.sql b/bin/diagnosticquery/SQLServerDiagnosticQueries_2019.sql
index f51d37b2d8..c0f55ce5f2 100644
--- a/bin/diagnosticquery/SQLServerDiagnosticQueries_2019.sql
+++ b/bin/diagnosticquery/SQLServerDiagnosticQueries_2019.sql
@@ -1,7 +1,7 @@
-- SQL Server 2019 Diagnostic Information Queries
-- Glenn Berry
--- Last Modified: May 2, 2024
+-- Last Modified: June 3, 2024
-- https://glennsqlperformance.com/
-- https://sqlserverperformance.wordpress.com/
-- YouTube: https://bit.ly/2PkoAM1
diff --git a/bin/diagnosticquery/SQLServerDiagnosticQueries_2022.sql b/bin/diagnosticquery/SQLServerDiagnosticQueries_2022.sql
index d2397de12f..4336b70506 100644
--- a/bin/diagnosticquery/SQLServerDiagnosticQueries_2022.sql
+++ b/bin/diagnosticquery/SQLServerDiagnosticQueries_2022.sql
@@ -1,7 +1,7 @@
-- SQL Server 2022 Diagnostic Information Queries
-- Glenn Berry
--- Last Modified: May 17, 2024
+-- Last Modified: June 3, 2024
-- https://glennsqlperformance.com/
-- https://sqlserverperformance.wordpress.com/
-- YouTube: https://bit.ly/2PkoAM1
diff --git a/code_of_conduct.md b/code_of_conduct.md
index 943bda882e..a487f99ee1 100644
--- a/code_of_conduct.md
+++ b/code_of_conduct.md
@@ -27,6 +27,28 @@ Use your best judgement. If it will possibly make others uncomfortable, do not p
If you believe someone is violating the code of conduct, we ask that you report it by contacting [Chrissy LeMaire](https://twitter.com/cl) or [Shawn Melton](https://twitter.com/wsmelton).
+# Standard Enforcement
+
+All reports of unacceptable behavior will be reviewed and investigated promptly and fairly. The Data Platform Community Organization and the dbatools team are committed to ensuring enforcement is consistent and transparent.
+
+### Enforcement Process:
+1. **Report Submission:** Reports can be submitted to [Chrissy LeMaire](https://twitter.com/cl) or [Shawn Melton](https://twitter.com/wsmelton). Reports should include details of the incident, including dates, times, and any witnesses, if available.
+
+2. **Review and Investigation:** Upon receiving a report, an initial review will be conducted to determine its validity. If deemed valid, a thorough investigation will follow, maintaining the confidentiality of the reporter.
+
+3. **Decision and Action:** Based on the investigation findings, appropriate actions will be taken. This may range from a warning to the offender to expulsion from the community or event, depending on the severity of the behavior.
+
+4. **Notification:** The reporter will be informed of the outcome of the investigation and any actions taken, while respecting the privacy of all parties involved.
+
+5. **Appeal Process:** The accused party has the right to appeal the decision by providing additional information or context. Appeals will be reviewed by a separate committee to ensure impartiality.
+
+### Consequences:
+- **Warning:** For minor violations, a private warning may be issued to the offender.
+- **Temporary Ban:** For repeated or more severe violations, a temporary ban from the community or event may be imposed.
+- **Permanent Ban:** For the most severe violations, a permanent ban from the community or all future events may be enforced.
+
+The Data Platform Community Organization and the dbatools team reserve the right to take any other actions deemed necessary to uphold the principles of the Code of Conduct.
+
# Credit
Portions of this Code of Conduct are based on the [example anti-harassment policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy) from the Geek Feminism wiki, created by the Ada Initiative and other volunteers, under a Creative Commons Zero license.
\ No newline at end of file
diff --git a/dbatools.psd1 b/dbatools.psd1
index b77e63d024..a8999f1027 100644
--- a/dbatools.psd1
+++ b/dbatools.psd1
@@ -11,7 +11,7 @@
RootModule = 'dbatools.psm1'
# Version number of this module.
- ModuleVersion = '2.1.16'
+ ModuleVersion = '2.1.17'
# ID used to uniquely identify this module
GUID = '9d139310-ce45-41ce-8e8b-d76335aa1789'
diff --git a/private/functions/Get-DbaHelp.ps1 b/private/functions/Get-DbaHelp.ps1
index 000a1027e2..1f7320202e 100644
--- a/private/functions/Get-DbaHelp.ps1
+++ b/private/functions/Get-DbaHelp.ps1
@@ -62,6 +62,7 @@ function Get-DbaHelp {
$availability = 'Windows, Linux, macOS'
function Get-DbaDocsMD($doc_to_render) {
+
$rtn = New-Object -TypeName "System.Collections.ArrayList"
$null = $rtn.Add("# $($doc_to_render.CommandName)" )
if ($doc_to_render.Author -or $doc_to_render.Availability) {
@@ -81,11 +82,16 @@ function Get-DbaHelp {
$null = $rtn.Add('*Aliases : ' + $doc_to_render.Alias + '*')
$null = $rtn.Add('')
}
+ $null = $rtn.Add('Want to see the source code for this command? Check out [' + $doc_to_render.CommandName + '](https://github.com/dataplat/dbatools/blob/master/public/' + $doc_to_render.CommandName + '.ps1) on GitHub.')
+ $null = $rtn.Add("
")
+ $null = $rtn.Add('Want to see the Bill Of Health for this command? Check out [' + $doc_to_render.CommandName + '](https://dataplat.github.io/boh#' + $doc_to_render.CommandName + ').')
$null = $rtn.Add('## Synopsis')
- $null = $rtn.Add($doc_to_render.Synopsis)
+ $null = $rtn.Add($doc_to_render.Synopsis.Replace("`n", " `n"))
$null = $rtn.Add('')
$null = $rtn.Add('## Description')
- $null = $rtn.Add($doc_to_render.Description)
+ if ($doc_to_render.Description) {
+ $null = $rtn.Add($doc_to_render.Description.Replace("`n", " `n"))
+ }
$null = $rtn.Add('')
if ($doc_to_render.Syntax) {
$null = $rtn.Add('## Syntax')
@@ -102,7 +108,15 @@ function Get-DbaHelp {
if ($x -eq 0) {
$null = $rtn.Add($val)
} else {
- $null = $rtn.Add(' [' + $val.replace("`n", '').replace("`n", ''))
+ $xx = 0
+ foreach ($subparam in ($val -split ' -')) {
+ if ($xx -eq 0) {
+ $null = $rtn.Add(' [' + $subparam.replace("`n", '').replace("`n", ''))
+ } else {
+ $null = $rtn.Add(' -' + $subparam.replace("`n", '').replace("`n", ''))
+ }
+ $xx += 1
+ }
}
$x += 1
}
@@ -133,7 +147,7 @@ function Get-DbaHelp {
$inside = 0
$null = $rtn.Add('```')
}
- $null = $rtn.Add("$row
")
+ $null = $rtn.Add("$($row.Replace("`n", " `n"))
")
}
}
if ($inside -eq 1) {
@@ -155,7 +169,7 @@ function Get-DbaHelp {
$null = $rtn.Add('### Required Parameters')
}
$null = $rtn.Add('##### -' + $el[0])
- $null = $rtn.Add($el[1] + '
')
+ $null = $rtn.Add($el[1].Replace("`r", "").Replace("`n", " `n") + '
')
$null = $rtn.Add('')
$null = $rtn.Add('| | |')
$null = $rtn.Add('| - | - |')
@@ -182,7 +196,7 @@ function Get-DbaHelp {
}
$null = $rtn.Add('##### -' + $el[0])
- $null = $rtn.Add($el[1] + '
')
+ $null = $rtn.Add($el[1].Replace("`r", "").Replace("`n", " `n") + '
')
$null = $rtn.Add('')
$null = $rtn.Add('| | |')
$null = $rtn.Add('| - | - |')
@@ -196,11 +210,9 @@ function Get-DbaHelp {
$null = $rtn.Add('')
}
}
+
$null = $rtn.Add('')
$null = $rtn.Add("`n" + ' ' + "`n")
- $null = $rtn.Add('Want to see the source code for this command? Check out [' + $doc_to_render.CommandName + '](https://github.com/dataplat/dbatools/blob/master/public/' + $doc_to_render.CommandName + '.ps1) on GitHub.')
- $null = $rtn.Add("
")
- $null = $rtn.Add('Want to see the Bill Of Health for this command? Check out [' + $doc_to_render.CommandName + '](https://dataplat.github.io/boh#' + $doc_to_render.CommandName + ').')
$null = $rtn.Add('')
return $rtn
@@ -370,7 +382,7 @@ function Get-DbaHelp {
[-ModuleExport] [-PassThru] [-AllowDelete] []'
}
if ($OutputAs -eq "PSObject") {
- [pscustomobject]$thebase
+ [PSCustomObject]$thebase
} elseif ($OutputAs -eq "MDString") {
Get-DbaDocsMD -doc_to_render $thebase
}
diff --git a/public/Connect-DbaInstance.ps1 b/public/Connect-DbaInstance.ps1
index 27a9837627..048e3266e7 100644
--- a/public/Connect-DbaInstance.ps1
+++ b/public/Connect-DbaInstance.ps1
@@ -327,18 +327,6 @@ function Connect-DbaInstance {
[switch]$DisableException
)
begin {
- function Test-Azure {
- Param (
- [DbaInstanceParameter]$SqlInstance
- )
- if ($SqlInstance.ComputerName -match $AzureDomain -or $instance.InputObject.ComputerName -match $AzureDomain) {
- Write-Message -Level Debug -Message "Test for Azure is positive"
- return $true
- } else {
- Write-Message -Level Debug -Message "Test for Azure is negative"
- return $false
- }
- }
function Invoke-TEPPCacheUpdate {
[CmdletBinding()]
param (
@@ -438,6 +426,8 @@ function Connect-DbaInstance {
Write-Message -Level Debug -Message "Starting process block"
foreach ($instance in $SqlInstance) {
+ Write-Message -Level Verbose -Message "Starting loop for '$instance': ComputerName = '$($instance.ComputerName)', InstanceName = '$($instance.InstanceName)', IsLocalHost = '$($instance.IsLocalHost)', Type = '$($instance.Type)'"
+
if ($tryconnstring) {
$azureserver = $instance.InputObject
if ($Database) {
@@ -448,13 +438,13 @@ function Connect-DbaInstance {
}
Write-Message -Level Debug -Message "Immediately checking for Azure"
- if ((Test-Azure -SqlInstance $instance)) {
+ if ($instance.ComputerName -match $AzureDomain -or $instance.InputObject.ComputerName -match $AzureDomain) {
Write-Message -Level Verbose -Message "Azure detected"
- $IsAzure = $true
+ $isAzure = $true
} else {
- $IsAzure = $false
+ $isAzure = $false
}
- Write-Message -Level Debug -Message "Starting loop for '$instance': ComputerName = '$($instance.ComputerName)', InstanceName = '$($instance.InstanceName)', IsLocalHost = '$($instance.IsLocalHost)', Type = '$($instance.Type)'"
+
<#
Best practice:
* Create a smo server object by submitting the name of the instance as a string to SqlInstance and additional parameters to configure the connection
@@ -541,25 +531,30 @@ function Connect-DbaInstance {
if ($instance.Type -like 'Server') {
Write-Message -Level Verbose -Message "Server object passed in, will do some checks and then return the original object"
$inputObjectType = 'Server'
+ $isNewConnection = $false
$inputObject = $instance.InputObject
} elseif ($instance.Type -like 'SqlConnection') {
Write-Message -Level Verbose -Message "SqlConnection object passed in, will build server object from instance.InputObject, do some checks and then return the server object"
$inputObjectType = 'SqlConnection'
+ $isNewConnection = $false
$inputObject = $instance.InputObject
} elseif ($instance.Type -like 'RegisteredServer') {
Write-Message -Level Verbose -Message "RegisteredServer object passed in, will build empty server object, set connection string from instance.InputObject.ConnectionString, do some checks and then return the server object"
$inputObjectType = 'RegisteredServer'
+ $isNewConnection = $true
$inputObject = $instance.InputObject
$serverName = $instance.FullSmoName
$connectionString = $instance.InputObject.ConnectionString
} elseif ($instance.IsConnectionString) {
Write-Message -Level Verbose -Message "Connection string is passed in, will build empty server object, set connection string from instance.InputObject, do some checks and then return the server object"
$inputObjectType = 'ConnectionString'
+ $isNewConnection = $true
$serverName = $instance.FullSmoName
$connectionString = $instance.InputObject | Convert-ConnectionString
} else {
Write-Message -Level Verbose -Message "String is passed in, will build server object from instance object and other parameters, do some checks and then return the server object"
$inputObjectType = 'String'
+ $isNewConnection = $true
$serverName = $instance.FullSmoName
}
@@ -624,6 +619,7 @@ function Connect-DbaInstance {
$copyContext = $true
}
if ($copyContext) {
+ $isNewConnection = $true
$connContext = $inputObject.ConnectionContext.Copy()
if ($ApplicationIntent) {
$connContext.ApplicationIntent = $ApplicationIntent
@@ -686,7 +682,7 @@ function Connect-DbaInstance {
$server = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $serverConnection
} elseif ($inputObjectType -eq 'String') {
# Identify authentication method
- if (Test-Azure -SqlInstance $instance) {
+ if ($isAzure) {
$authType = 'azure '
} else {
$authType = 'local '
@@ -942,11 +938,8 @@ function Connect-DbaInstance {
$server.ConnectionContext.StatementTimeout = $StatementTimeout
}
- # we skip showing the masked string for DAC to prevent DAC from making a call to the server
- if (-not $DedicatedAdminConnection) {
- $maskedConnString = Hide-ConnectionString $server.ConnectionContext.ConnectionString
- Write-Message -Level Debug -Message "The masked server.ConnectionContext.ConnectionString is $maskedConnString"
- }
+ $maskedConnString = Hide-ConnectionString $server.ConnectionContext.ConnectionString
+ Write-Message -Level Debug -Message "The masked server.ConnectionContext.ConnectionString is $maskedConnString"
# It doesn't matter which input we have, we pass this line and have a server SMO in $server to work with
# It might be a brand new one or an already used one.
@@ -965,11 +958,17 @@ function Connect-DbaInstance {
}
if ($AzureUnsupported -and $server.DatabaseEngineType -eq "SqlAzureDatabase") {
+ if ($isNewConnection) {
+ $server.ConnectionContext.Disconnect()
+ }
Stop-Function -Target $instance -Message "Azure SQL Database not supported" -Continue
}
if ($MinimumVersion -and $server.VersionMajor) {
if ($server.VersionMajor -lt $MinimumVersion) {
+ if ($isNewConnection) {
+ $server.ConnectionContext.Disconnect()
+ }
Stop-Function -Target $instance -Message "SQL Server version $MinimumVersion required - $server not supported." -Continue
}
}
@@ -1000,34 +999,27 @@ function Connect-DbaInstance {
Write-Message -Level Debug -Message "No value found for ComputerName, so will use the default"
}
}
-
-
- if ($DedicatedAdminConnection) {
- $computerName = $instance.ComputerName
- } else {
- if (-not $computerName) {
- if ($server.DatabaseEngineType -eq "SqlAzureDatabase") {
- Write-Message -Level Debug -Message "We are on Azure, so server.ComputerName will be set to instance.ComputerName"
- $computerName = $instance.ComputerName
- } elseif ($server.HostPlatform -eq 'Linux') {
- Write-Message -Level Debug -Message "We are on Linux what is often on docker and the internal name is not useful, so server.ComputerName will be set to instance.ComputerName"
- $computerName = $instance.ComputerName
- } elseif ($server.NetName) {
- Write-Message -Level Debug -Message "We will set server.ComputerName to server.NetName"
- $computerName = $server.NetName
- } else {
- Write-Message -Level Debug -Message "We will set server.ComputerName to instance.ComputerName as server.NetName is empty"
- $computerName = $instance.ComputerName
- }
- Write-Message -Level Debug -Message "ComputerName will be set to $computerName"
+ if (-not $computerName) {
+ if ($server.DatabaseEngineType -eq "SqlAzureDatabase") {
+ Write-Message -Level Debug -Message "We are on Azure, so server.ComputerName will be set to instance.ComputerName"
+ $computerName = $instance.ComputerName
+ } elseif ($server.HostPlatform -eq 'Linux') {
+ Write-Message -Level Debug -Message "We are on Linux what is often on docker and the internal name is not useful, so server.ComputerName will be set to instance.ComputerName"
+ $computerName = $instance.ComputerName
+ } elseif ($server.NetName) {
+ Write-Message -Level Debug -Message "We will set server.ComputerName to server.NetName"
+ $computerName = $server.NetName
+ } else {
+ Write-Message -Level Debug -Message "We will set server.ComputerName to instance.ComputerName as server.NetName is empty"
+ $computerName = $instance.ComputerName
}
+ Write-Message -Level Debug -Message "ComputerName will be set to $computerName"
}
Add-Member -InputObject $server -NotePropertyName ComputerName -NotePropertyValue $computerName -Force
}
- if (-not $server.IsAzure -and -not $DedicatedAdminConnection) {
- # so many things in this block make DAC complain, skip it
- Add-Member -InputObject $server -NotePropertyName IsAzure -NotePropertyValue (Test-Azure -SqlInstance $instance) -Force
+ if (-not $server.IsAzure) {
+ Add-Member -InputObject $server -NotePropertyName IsAzure -NotePropertyValue $isAzure -Force
Add-Member -InputObject $server -NotePropertyName DbaInstanceName -NotePropertyValue $instance.InstanceName -Force
Add-Member -InputObject $server -NotePropertyName NetPort -NotePropertyValue $instance.Port -Force
Add-Member -InputObject $server -NotePropertyName ConnectedAs -NotePropertyValue $server.ConnectionContext.TrueLogin -Force
@@ -1035,65 +1027,60 @@ function Connect-DbaInstance {
}
Write-Message -Level Debug -Message "We return the server object"
- if ($DedicatedAdminConnection) {
- # return DAC connections sooner rather than later because they serve
- # a different purpose but also, otherwise, there are complaints in the event log
- Add-Member -InputObject $server -NotePropertyName IsAzure -NotePropertyValue $false -Force
- return $server
- } else {
- $server
- }
+ $server
- # Register the connected instance, so that the TEPP updater knows it's been connected to and starts building the cache
- [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::SetInstance($instance.FullSmoName.ToLowerInvariant(), $server.ConnectionContext.Copy(), ($server.ConnectionContext.FixedServerRoles -match "SysAdmin"))
+ if ($isNewConnection -and -not $DedicatedAdminConnection) {
+ # Register the connected instance, so that the TEPP updater knows it's been connected to and starts building the cache
+ [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::SetInstance($instance.FullSmoName.ToLowerInvariant(), $server.ConnectionContext.Copy(), ($server.ConnectionContext.FixedServerRoles -match "SysAdmin"))
- # Update cache for instance names
- if ([Dataplat.Dbatools.TabExpansion.TabExpansionHost]::Cache["sqlinstance"] -notcontains $instance.FullSmoName.ToLowerInvariant()) {
- [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::Cache["sqlinstance"] += $instance.FullSmoName.ToLowerInvariant()
- }
+ # Update cache for instance names
+ if ([Dataplat.Dbatools.TabExpansion.TabExpansionHost]::Cache["sqlinstance"] -notcontains $instance.FullSmoName.ToLowerInvariant()) {
+ [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::Cache["sqlinstance"] += $instance.FullSmoName.ToLowerInvariant()
+ }
- # Update lots of registered stuff
- # Default for [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppSyncDisabled is $true, so will not run by default
- # Must be explicitly activated with [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppSyncDisabled = $false to run
- if (-not [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppSyncDisabled) {
- # Variable $FullSmoName is used inside the script blocks, so we have to set
- $FullSmoName = $instance.FullSmoName.ToLowerInvariant()
- Write-Message -Level Debug -Message "Will run Invoke-TEPPCacheUpdate for FullSmoName = $FullSmoName"
- foreach ($scriptBlock in ([Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppGatherScriptsFast)) {
- Invoke-TEPPCacheUpdate -ScriptBlock $scriptBlock
+ # Update lots of registered stuff
+ # Default for [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppSyncDisabled is $true, so will not run by default
+ # Must be explicitly activated with [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppSyncDisabled = $false to run
+ if (-not [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppSyncDisabled) {
+ # Variable $FullSmoName is used inside the script blocks, so we have to set
+ $FullSmoName = $instance.FullSmoName.ToLowerInvariant()
+ Write-Message -Level Debug -Message "Will run Invoke-TEPPCacheUpdate for FullSmoName = $FullSmoName"
+ foreach ($scriptBlock in ([Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppGatherScriptsFast)) {
+ Invoke-TEPPCacheUpdate -ScriptBlock $scriptBlock
+ }
}
- }
- # By default, SMO initializes several properties. We push it to the limit and gather a bit more
- # this slows down the connect a smidge but drastically improves overall performance
- # especially when dealing with a multitude of servers
- if ($loadedSmoVersion -ge 11 -and -not $isAzure) {
- try {
- Write-Message -Level Debug -Message "SetDefaultInitFields will be used"
- $initFieldsDb = New-Object System.Collections.Specialized.StringCollection
- $initFieldsLogin = New-Object System.Collections.Specialized.StringCollection
- $initFieldsJob = New-Object System.Collections.Specialized.StringCollection
- if ($server.VersionMajor -eq 8) {
- # 2000
- [void]$initFieldsDb.AddRange($Fields2000_Db)
- [void]$initFieldsLogin.AddRange($Fields2000_Login)
- } elseif ($server.VersionMajor -eq 9 -or $server.VersionMajor -eq 10) {
- # 2005 and 2008
- [void]$initFieldsDb.AddRange($Fields200x_Db)
- [void]$initFieldsLogin.AddRange($Fields200x_Login)
- } else {
- # 2012 and above
- [void]$initFieldsDb.AddRange($Fields201x_Db)
- [void]$initFieldsLogin.AddRange($Fields201x_Login)
+ # By default, SMO initializes several properties. We push it to the limit and gather a bit more
+ # this slows down the connect a smidge but drastically improves overall performance
+ # especially when dealing with a multitude of servers
+ if ($loadedSmoVersion -ge 11 -and -not $isAzure) {
+ try {
+ Write-Message -Level Debug -Message "SetDefaultInitFields will be used"
+ $initFieldsDb = New-Object System.Collections.Specialized.StringCollection
+ $initFieldsLogin = New-Object System.Collections.Specialized.StringCollection
+ $initFieldsJob = New-Object System.Collections.Specialized.StringCollection
+ if ($server.VersionMajor -eq 8) {
+ # 2000
+ [void]$initFieldsDb.AddRange($Fields2000_Db)
+ [void]$initFieldsLogin.AddRange($Fields2000_Login)
+ } elseif ($server.VersionMajor -eq 9 -or $server.VersionMajor -eq 10) {
+ # 2005 and 2008
+ [void]$initFieldsDb.AddRange($Fields200x_Db)
+ [void]$initFieldsLogin.AddRange($Fields200x_Login)
+ } else {
+ # 2012 and above
+ [void]$initFieldsDb.AddRange($Fields201x_Db)
+ [void]$initFieldsLogin.AddRange($Fields201x_Login)
+ }
+ $server.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Database], $initFieldsDb)
+ $server.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Login], $initFieldsLogin)
+ #see 7753
+ [void]$initFieldsJob.AddRange($Fields_Job)
+ $server.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Agent.Job], $initFieldsJob)
+ } catch {
+ Write-Message -Level Debug -Message "SetDefaultInitFields failed with $_"
+ # perhaps a DLL issue, continue going
}
- $server.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Database], $initFieldsDb)
- $server.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Login], $initFieldsLogin)
- #see 7753
- [void]$initFieldsJob.AddRange($Fields_Job)
- $server.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Agent.Job], $initFieldsJob)
- } catch {
- Write-Message -Level Debug -Message "SetDefaultInitFields failed with $_"
- # perhaps a DLL issue, continue going
}
}
diff --git a/public/ConvertTo-DbaDataTable.ps1 b/public/ConvertTo-DbaDataTable.ps1
index c09613162c..5af518e7c9 100644
--- a/public/ConvertTo-DbaDataTable.ps1
+++ b/public/ConvertTo-DbaDataTable.ps1
@@ -228,7 +228,7 @@ function ConvertTo-DbaDataTable {
return [System.DateTime]$Value.DateTime
}
'String' {
- return ($Value | Foreach-Object { $_.ToString() }) -join ', '
+ return ($Value | Foreach-Object { $_.ToString() }) -Join ', '
}
}
}
diff --git a/public/Get-DbaProcess.ps1 b/public/Get-DbaProcess.ps1
index fe04deecb7..ad63aeeaed 100644
--- a/public/Get-DbaProcess.ps1
+++ b/public/Get-DbaProcess.ps1
@@ -121,7 +121,7 @@ function Get-DbaProcess {
on c.session_id = s.session_id
JOIN sys.endpoints e
ON c.endpoint_id = e.endpoint_id
- CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t"
+ OUTER APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t"
if ($server.VersionMajor -gt 8) {
$results = $server.Query($sql)
diff --git a/public/Install-DbaFirstResponderKit.ps1 b/public/Install-DbaFirstResponderKit.ps1
index d366559752..7958cdd924 100644
--- a/public/Install-DbaFirstResponderKit.ps1
+++ b/public/Install-DbaFirstResponderKit.ps1
@@ -103,9 +103,14 @@ function Install-DbaFirstResponderKit {
Installs only the procedures sp_Blitz and sp_BlitzWho and the table SqlServerVersions by running the corresponding scripts.
.EXAMPLE
- PS C:\> Install-DbaFirstResponderKit -SqlInstance sql2016 -OnlyScript Install-Core-Blitz-No-Query-Store.sql
+ PS C:\> Install-DbaFirstResponderKit -SqlInstance sql2016 -OnlyScript Install-All-Scripts.sql
- Installs only part of the First Responder Kit by running the official install script.
+ Installs the First Responder Kit using the official install script.
+
+ .EXAMPLE
+ PS C:\> Install-DbaFirstResponderKit -SqlInstance sql-server-001.database.windows.net -OnlyScript Install-Azure.sql
+
+ Installs the First Responder Kit using the official install script for Azure SQL Database.
.EXAMPLE
PS C:\> Install-DbaFirstResponderKit -SqlInstance sql2016 -OnlyScript Uninstall.sql
@@ -121,10 +126,10 @@ function Install-DbaFirstResponderKit {
[string]$Branch = "main",
[object]$Database = "master",
[string]$LocalFile,
- [ValidateSet('Install-All-Scripts.sql', 'Install-Core-Blitz-No-Query-Store.sql', 'Install-Core-Blitz-With-Query-Store.sql',
- 'sp_Blitz.sql', 'sp_BlitzFirst.sql', 'sp_BlitzIndex.sql', 'sp_BlitzCache.sql', 'sp_BlitzWho.sql', 'sp_BlitzQueryStore.sql',
- 'sp_BlitzAnalysis.sql', 'sp_BlitzBackups.sql', 'sp_BlitzInMemoryOLTP.sql', 'sp_BlitzLock.sql',
- 'sp_AllNightLog.sql', 'sp_AllNightLog_Setup.sql', 'sp_DatabaseRestore.sql', 'sp_ineachdb.sql',
+ [ValidateSet('Install-All-Scripts.sql', 'Install-Azure.sql',
+ 'sp_Blitz.sql', 'sp_BlitzFirst.sql', 'sp_BlitzIndex.sql', 'sp_BlitzCache.sql', 'sp_BlitzWho.sql',
+ 'sp_BlitzAnalysis.sql', 'sp_BlitzBackups.sql', 'sp_BlitzLock.sql',
+ 'sp_DatabaseRestore.sql', 'sp_ineachdb.sql',
'SqlServerVersions.sql', 'Uninstall.sql')]
[string[]]$OnlyScript,
[switch]$Force,
diff --git a/public/New-DbaAgentJobStep.ps1 b/public/New-DbaAgentJobStep.ps1
index 5b4af31974..0cd60e3a19 100644
--- a/public/New-DbaAgentJobStep.ps1
+++ b/public/New-DbaAgentJobStep.ps1
@@ -171,7 +171,7 @@ function New-DbaAgentJobStep {
[ValidateSet('QuitWithSuccess', 'QuitWithFailure', 'GoToNextStep', 'GoToStep')]
[string]$OnFailAction = 'QuitWithFailure',
[int]$OnFailStepId = 0,
- [object]$Database,
+ [string]$Database,
[string]$DatabaseUser,
[int]$RetryAttempts,
[int]$RetryInterval,
@@ -341,14 +341,14 @@ function New-DbaAgentJobStep {
}
}
- if ($DatabaseUser -and $DatabaseName) {
+ if ($DatabaseUser -and $Database) {
# Check if the username is present in the database
- if ($Server.Databases[$DatabaseName].Users.Name -contains $DatabaseUser) {
+ if ($Server.Databases[$Database].Users.Name -contains $DatabaseUser) {
Write-Message -Message "Setting job step database username to $DatabaseUser" -Level Verbose
$jobStep.DatabaseUserName = $DatabaseUser
} else {
- Stop-Function -Message "The database user is not present in the database $DatabaseName on instance $instance." -Target $instance -Continue
+ Stop-Function -Message "The database user is not present in the database $Database on instance $instance." -Target $instance -Continue
}
}
diff --git a/public/New-DbaAgentSchedule.ps1 b/public/New-DbaAgentSchedule.ps1
index 0fb7be48c7..16f7f917a0 100644
--- a/public/New-DbaAgentSchedule.ps1
+++ b/public/New-DbaAgentSchedule.ps1
@@ -99,6 +99,9 @@ function New-DbaAgentSchedule {
If force is used the start time will be '23:59:59'
+ .PARAMETER Owner
+ Login to own the job, defaults to login running the command.
+
.PARAMETER WhatIf
Shows what would happen if the command were to run. No actions are actually performed.
@@ -167,6 +170,7 @@ function New-DbaAgentSchedule {
[string]$EndDate,
[string]$StartTime,
[string]$EndTime,
+ [string]$Owner,
[switch]$Force,
[switch]$EnableException
)
@@ -523,6 +527,10 @@ function New-DbaAgentSchedule {
$jobschedule.ActiveEndTimeOfDay = $EndTime
}
+ if ($Owner) {
+ $jobschedule.OwnerLoginName = $Owner
+ }
+
$jobschedule.Create()
Write-Message -Message "Job schedule created with UID $($jobschedule.ScheduleUid)" -Level Verbose
diff --git a/tests/Connect-DbaInstance.Tests.ps1 b/tests/Connect-DbaInstance.Tests.ps1
index 6688db6077..4d45c5ce6a 100644
--- a/tests/Connect-DbaInstance.Tests.ps1
+++ b/tests/Connect-DbaInstance.Tests.ps1
@@ -52,155 +52,182 @@ Describe "$commandname Integration Tests" -Tags "IntegrationTests" {
}
}
- Context "connection is properly made" {
- $server = Connect-DbaInstance -SqlInstance $script:instance1 -ApplicationIntent ReadOnly
+ Context "connection is properly made using a string" {
+ BeforeAll {
+ $params = @{
+ 'BatchSeparator' = 'GO'
+ 'ConnectTimeout' = 1
+ 'Database' = 'tempdb'
+ 'LockTimeout' = 1
+ 'MaxPoolSize' = 20
+ 'MinPoolSize' = 1
+ 'NetworkProtocol' = 'TcpIp'
+ 'PacketSize' = 4096
+ 'PooledConnectionLifetime' = 600
+ 'WorkstationId' = 'MadeUpServer'
+ 'SqlExecutionModes' = 'ExecuteSql'
+ 'StatementTimeout' = 0
+ 'ApplicationIntent' = 'ReadOnly'
+ }
+ $server = Connect-DbaInstance -SqlInstance $script:instance1 @params
+ }
It "returns the proper name" {
- $server.Name -eq $script:instance1 | Should Be $true
+ $server.Name | Should -Be $script:instance1
+ }
+
+ It "sets connectioncontext parameters that are provided" {
+ foreach ($param in $params.GetEnumerator()) {
+ if ($param.Key -eq 'Database') {
+ $propName = 'DatabaseName'
+ } else {
+ $propName = $param.Key
+ }
+ $server.ConnectionContext.$propName | Should -Be $param.Value
+ }
}
It "returns more than one database" {
- $server.Databases.Name.Count -gt 0 | Should Be $true
+ $server.Databases.Name.Count | Should -BeGreaterThan 1
}
It "returns the connection with ApplicationIntent of ReadOnly" {
- $server.ConnectionContext.ConnectionString -match "Intent=ReadOnly" | Should Be $true
+ $server.ConnectionContext.ConnectionString | Should -Match "Intent=ReadOnly"
}
It "keeps the same database context" {
$null = $server.Databases['msdb'].Tables.Count
- $server.ConnectionContext.ExecuteScalar("select db_name()") | Should -Be 'master'
+ $server.ConnectionContext.ExecuteScalar("select db_name()") | Should -Be 'tempdb'
}
It "sets StatementTimeout to 0" {
- $server = Connect-DbaInstance -SqlInstance $script:instance1 -StatementTimeout 0
-
- $server.ConnectionContext.StatementTimeout | Should Be 0
+ $server.ConnectionContext.StatementTimeout | Should -Be 0
}
+ }
- It "connects using a connection string" {
+ Context "connection is properly made using a connection string" {
+ BeforeAll {
$server = Connect-DbaInstance -SqlInstance "Data Source=$script:instance1;Initial Catalog=tempdb;Integrated Security=True"
- $server.Databases.Name.Count -gt 0 | Should Be $true
}
- It "keeps the same database context when connected using a connection string" {
- $server = Connect-DbaInstance -SqlInstance "Data Source=$script:instance1;Initial Catalog=tempdb;Integrated Security=True"
+ It "returns the proper name" {
+ $server.Name | Should -Be $script:instance1
+ }
+
+ It "returns more than one database" {
+ $server.Databases.Name.Count | Should -BeGreaterThan 1
+ }
+
+ It "keeps the same database context" {
# Before #8962 this changed the context to msdb
$null = $server.Databases['msdb'].Tables.Count
$server.ConnectionContext.ExecuteScalar("select db_name()") | Should -Be 'tempdb'
}
+ }
+
+ if ($script:instance1 -match 'localhost') {
+ Context "connection is properly made using a dot" {
+ BeforeAll {
+ $newinstance = $script:instance1.Replace("localhost", ".")
+ $server = Connect-DbaInstance -SqlInstance $newinstance
+ }
+
+ It "returns the proper name" {
+ $server.Name | Should -Be "NP:$newinstance"
+ }
+
+ It "returns more than one database" {
+ $server.Databases.Name.Count | Should -BeGreaterThan 1
+ }
- It "connects using a dot" {
- $newinstance = $script:instance1.Replace("localhost", ".")
- Write-Warning "Connecting to $newinstance"
- $server = Connect-DbaInstance -SqlInstance $newinstance
- $server.Databases.Name.Count -gt 0 | Should Be $true
+ It "keeps the same database context" {
+ $null = $server.Databases['msdb'].Tables.Count
+ # This currently fails!
+ #$server.ConnectionContext.ExecuteScalar("select db_name()") | Should -Be 'tempdb'
+ }
}
+ }
- It "connects using a connection object" {
+ Context "connection is properly made using a connection object" {
+ BeforeAll {
Set-DbatoolsConfig -FullName commands.connect-dbainstance.smo.computername.source -Value 'instance.ComputerName'
[Microsoft.Data.SqlClient.SqlConnection]$sqlconnection = "Data Source=$script:instance1;Initial Catalog=tempdb;Integrated Security=True;Encrypt=False;Trust Server Certificate=True"
$server = Connect-DbaInstance -SqlInstance $sqlconnection
- $server.ComputerName | Should Be ([DbaInstance]$script:instance1).ComputerName
- $server.Databases.Name.Count -gt 0 | Should Be $true
Set-DbatoolsConfig -FullName commands.connect-dbainstance.smo.computername.source -Value $null
}
- It "connects - instance2" {
- $server = Connect-DbaInstance -SqlInstance $script:instance2
- $server.Databases.Name.Count -gt 0 | Should Be $true
+ It "returns the proper name" {
+ $server.Name | Should -Be $script:instance1
}
- It "connects using a connection string - instance2" {
- $server = Connect-DbaInstance -SqlInstance "Data Source=$script:instance2;Initial Catalog=tempdb;Integrated Security=True"
- $server.Databases.Name.Count -gt 0 | Should Be $true
+ It "returns more than one database" {
+ $server.Databases.Name.Count | Should -BeGreaterThan 1
}
- It "connects using a connection object - instance2" {
- Set-DbatoolsConfig -FullName commands.connect-dbainstance.smo.computername.source -Value 'instance.ComputerName'
- [Microsoft.Data.SqlClient.SqlConnection]$sqlconnection = "Data Source=$script:instance2;Initial Catalog=tempdb;Integrated Security=True;Encrypt=False;Trust Server Certificate=True"
- $server = Connect-DbaInstance -SqlInstance $sqlconnection
- $server.ComputerName | Should Be ([DbaInstance]$script:instance2).ComputerName
- $server.Databases.Name.Count -gt 0 | Should Be $true
- Set-DbatoolsConfig -FullName commands.connect-dbainstance.smo.computername.source -Value $null
+ It "keeps the same database context" {
+ $null = $server.Databases['msdb'].Tables.Count
+ # This currently fails!
+ #$server.ConnectionContext.ExecuteScalar("select db_name()") | Should -Be 'tempdb'
}
+ }
- It "sets connectioncontext parameters that are provided" {
- $params = @{
- 'BatchSeparator' = 'GO'
- 'ConnectTimeout' = 1
- 'Database' = 'master'
- 'LockTimeout' = 1
- 'MaxPoolSize' = 20
- 'MinPoolSize' = 1
- 'NetworkProtocol' = 'TcpIp'
- 'PacketSize' = 4096
- 'PooledConnectionLifetime' = 600
- 'WorkstationId' = 'MadeUpServer'
- 'SqlExecutionModes' = 'ExecuteSql'
- 'StatementTimeout' = 0
- }
-
- $server = Connect-DbaInstance -SqlInstance $script:instance1 @params
-
- foreach ($param in $params.GetEnumerator()) {
- if ($param.Key -eq 'Database') {
- $propName = 'DatabaseName'
- } else {
- $propName = $param.Key
- }
+ Context "connection is properly cloned from an existing connection" {
+ BeforeAll {
+ $server = Connect-DbaInstance -SqlInstance $script:instance1
+ }
- $server.ConnectionContext.$propName | Should Be $param.Value
- }
+ It "clones when using parameter Database" {
+ $serverClone = Connect-DbaInstance -SqlInstance $server -Database tempdb
+ $server.ConnectionContext.ExecuteScalar("select db_name()") | Should -Be 'master'
+ $serverClone.ConnectionContext.ExecuteScalar("select db_name()") | Should -Be 'tempdb'
}
- }
-}
-Describe "$commandname Integration Tests (moved here from Connect-SqlInstance)" -Tags "IntegrationTests" {
- $password = 'MyV3ry$ecur3P@ssw0rd'
- $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
- $server = Connect-DbaInstance -SqlInstance $script:instance1
- $login = "csitester"
+ It "clones when using parameter ApplicationIntent" {
+ $serverClone = Connect-DbaInstance -SqlInstance $server -ApplicationIntent ReadOnly
+ $server.ConnectionContext.ApplicationIntent | Should -BeNullOrEmpty
+ $serverClone.ConnectionContext.ApplicationIntent | Should -Be 'ReadOnly'
+ }
- #Cleanup
+ It "clones when using parameter NonPooledConnection" {
+ $serverClone = Connect-DbaInstance -SqlInstance $server -NonPooledConnection
+ $server.ConnectionContext.NonPooledConnection | Should -Be $false
+ $serverClone.ConnectionContext.NonPooledConnection | Should -Be $true
+ }
- $results = Invoke-DbaQuery -SqlInstance $script:instance1 -Query "IF EXISTS (SELECT * FROM sys.server_principals WHERE name = '$login') EXEC sp_who '$login'"
- foreach ($spid in $results.spid) {
- Invoke-DbaQuery -SqlInstance $script:instance1 -Query "kill $spid"
- }
+ It "clones when using parameter StatementTimeout" {
+ $serverClone = Connect-DbaInstance -SqlInstance $server -StatementTimeout 0
+ $server.ConnectionContext.StatementTimeout | Should -Be (Get-DbatoolsConfigValue -FullName 'sql.execution.timeout')
+ $serverClone.ConnectionContext.StatementTimeout | Should -Be 0
+ }
- if ($l = $server.logins[$login]) {
- if ($c = $l.EnumCredentials()) {
- $l.DropCredential($c)
+ It "clones when using parameter DedicatedAdminConnection" {
+ $serverClone = Connect-DbaInstance -SqlInstance $server -DedicatedAdminConnection
+ $server.ConnectionContext.ServerInstance | Should -Not -Match '^ADMIN:'
+ $serverClone.ConnectionContext.ServerInstance | Should -Match '^ADMIN:'
+ $serverClone | Disconnect-DbaInstance
}
- $l.Drop()
}
- #Create login
- $newLogin = New-Object Microsoft.SqlServer.Management.Smo.Login($server, $login)
- $newLogin.LoginType = "SqlLogin"
- $newLogin.Create($password)
-
- Context "Connect with a new login" {
- It "Should login with newly created Sql Login (also tests credential login) and get instance name" {
- $cred = New-Object System.Management.Automation.PSCredential ($login, $securePassword)
- $s = Connect-DbaInstance -SqlInstance $script:instance1 -SqlCredential $cred
- $s.Name | Should Be $script:instance1
- }
- It "Should return existing process running under the new login and kill it" {
- $results = Invoke-DbaQuery -SqlInstance $script:instance1 -Query "IF EXISTS (SELECT * FROM sys.server_principals WHERE name = '$login') EXEC sp_who '$login'"
- $results | Should Not BeNullOrEmpty
- foreach ($spid in $results.spid) {
- { Invoke-DbaQuery -SqlInstance $script:instance1 -Query "kill $spid" -ErrorAction Stop} | Should Not Throw
- }
+ Context "multiple connections are properly made using strings" {
+ It "returns the proper names" {
+ $server = Connect-DbaInstance -SqlInstance $script:instance1, $script:instance2
+ $server[0].Name | Should -Be $script:instance1
+ $server[1].Name | Should -Be $script:instance2
}
}
- #Cleanup
- if ($l = $server.logins[$login]) {
- if ($c = $l.EnumCredentials()) {
- $l.DropCredential($c)
+ Context "multiple dedicated admin connections are properly made using strings" {
+ # This might fail if a parallel test uses DAC - how can we ensure that this is the only test that is run?
+ It "opens and closes the connections" {
+ $server = Connect-DbaInstance -SqlInstance $script:instance1, $script:instance2 -DedicatedAdminConnection
+ $server[0].Name | Should -Be "ADMIN:$script:instance1"
+ $server[1].Name | Should -Be "ADMIN:$script:instance2"
+ $null = $server | Disconnect-DbaInstance
+ # DAC is not reopened in the background
+ Start-Sleep -Seconds 10
+ $server = Connect-DbaInstance -SqlInstance $script:instance1, $script:instance2 -DedicatedAdminConnection
+ $server.Count | Should -Be 2
+ $null = $server | Disconnect-DbaInstance
}
- $l.Drop()
}
}
\ No newline at end of file
diff --git a/tests/ConvertTo-DbaDataTable.Tests.ps1 b/tests/ConvertTo-DbaDataTable.Tests.ps1
index c152adb932..9c396c2a38 100644
--- a/tests/ConvertTo-DbaDataTable.Tests.ps1
+++ b/tests/ConvertTo-DbaDataTable.Tests.ps1
@@ -8,7 +8,7 @@ Describe "$CommandName Unit Tests" -Tag 'UnitTests' {
[object[]]$knownParameters = 'InputObject', 'TimeSpanType', 'SizeType', 'IgnoreNull', 'Raw', 'EnableException'
$knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters
It "Should only contain our specific parameters" {
- (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0
+ (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should -Be 0
}
}
}
@@ -26,6 +26,8 @@ Describe "Testing data table output when using a complex object" {
UInt64 = [System.UInt64]123456
dbadatetime = [dbadatetime[]]$(Get-Date -Year 2024 -Month 05 -Day 19 -Hour 5 -Minute 52 -Second 0 -Millisecond 0)
dbadatetimeArray = [dbadatetime[]]($(Get-Date -Year 2024 -Month 05 -Day 19 -Hour 5 -Minute 52 -Second 0 -Millisecond 0), $(Get-Date -Year 2024 -Month 05 -Day 19 -Hour 5 -Minute 52 -Second 0 -Millisecond 0).AddHours(1))
+ inlining = [pscustomobject]@{Mission = 'Keep Hank alive'}
+ inlining2 = [psobject]@{Mission = 'Keep Hank alive'}
}
$innedobj = New-Object -TypeName psobject -Property @{
@@ -35,15 +37,23 @@ Describe "Testing data table output when using a complex object" {
Add-Member -Force -InputObject $obj -MemberType NoteProperty -Name myObject -Value $innedobj
$result = ConvertTo-DbaDataTable -InputObject $obj
+ $firstRow = $result[0].Rows[0]
+ Context "Lengths" {
+ It 'Count of the Rows' {
+ $result.Rows.Count | Should -Be 1
+ }
+ }
+
+
Context "Property: guid" {
It 'Has a column called "guid"' {
$result.Columns.ColumnName | Should -Contain 'guid'
}
It 'Has a [guid] data type on the column "guid"' {
- $result.guid | Should -BeOfType [System.guid]
+ $firstRow.guid | Should -BeOfType [System.guid]
}
It 'Has the following guid: "32ccd4c4-282a-4c0d-997c-7b5deb97f9e0"' {
- $result.guid | Should Be '32ccd4c4-282a-4c0d-997c-7b5deb97f9e0'
+ $firstRow.guid | Should -Be '32ccd4c4-282a-4c0d-997c-7b5deb97f9e0'
}
}
@@ -52,11 +62,11 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'timespan'
}
It 'Has a [long] data type on the column "timespan"' {
- $result.timespan | Should -BeOfType [System.Int64]
+ $firstRow.timespan | Should -BeOfType [System.Int64]
}
It "Has the following timespan: 15724800000" {
- $result.timespan | Should Be 15724800000
+ $firstRow.timespan | Should -Be 15724800000
}
}
@@ -65,11 +75,11 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'datetime'
}
It 'Has a [datetime] data type on the column "datetime"' {
- $result.datetime | Should -BeOfType [System.DateTime]
+ $firstRow.datetime | Should -BeOfType [System.DateTime]
}
It "Has the following datetime: 2016-10-30 05:52:00.000" {
$date = Get-Date -Year 2016 -Month 10 -Day 30 -Hour 5 -Minute 52 -Second 0 -Millisecond 0
- $result.datetime -eq $date | Should Be $true
+ $firstRow.datetime -eq $date | Should -Be $true
}
}
@@ -78,10 +88,10 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'char'
}
It 'Has a [char] data type on the column "char"' {
- $result.char | Should -BeOfType [System.Char]
+ $firstRow.char | Should -BeOfType [System.Char]
}
It "Has the following char: T" {
- $result.char | Should Be "T"
+ $firstRow.char | Should -Be "T"
}
}
@@ -90,10 +100,10 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'true'
}
It 'Has a [bool] data type on the column "true"' {
- $result.true | Should -BeOfType [System.Boolean]
+ $firstRow.true | Should -BeOfType [System.Boolean]
}
It "Has the following bool: true" {
- $result.true | Should Be $true
+ $firstRow.true | Should -Be $true
}
}
@@ -102,10 +112,10 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'false'
}
It 'Has a [bool] data type on the column "false"' {
- $result.false | Should -BeOfType [System.Boolean]
+ $firstRow.false | Should -BeOfType [System.Boolean]
}
It "Has the following bool: false" {
- $result.false | Should Be $false
+ $firstRow.false | Should -Be $false
}
}
@@ -114,10 +124,10 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'null'
}
It 'Has a [null] data type on the column "null"' {
- $result.null | Should -BeOfType [System.DBNull]
+ $firstRow.null | Should -BeOfType [System.DBNull]
}
It "Has no value" {
- $result.null | Should -BeNullOrEmpty
+ $firstRow.null | Should -BeNullOrEmpty
}
}
@@ -126,10 +136,10 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'string'
}
It 'Has a [string] data type on the column "string"' {
- $result.string | Should -BeOfType [System.String]
+ $firstRow.string | Should -BeOfType [System.String]
}
It "Has the following string: it's a boy." {
- $result.string | Should Be "it's a boy."
+ $firstRow.string | Should -Be "it's a boy."
}
}
@@ -138,10 +148,10 @@ Describe "Testing data table output when using a complex object" {
$result.Columns.ColumnName | Should -Contain 'UInt64'
}
It 'Has a [UInt64] data type on the column "UInt64"' {
- $result.UInt64 | Should -BeOfType [System.UInt64]
+ $firstRow.UInt64 | Should -BeOfType [System.UInt64]
}
It "Has the following number: 123456" {
- $result.UInt64 | Should Be 123456
+ $firstRow.UInt64 | Should -Be 123456
}
}
@@ -149,21 +159,18 @@ Describe "Testing data table output when using a complex object" {
It 'Has a column called "myObject"' {
$result.Columns.ColumnName | Should -Contain 'myObject'
}
- It 'Has a [string] data type on the column "myObject"' {
- $result.myObject | Should -BeOfType [System.String]
- }
}
Context "Property: dbadatetime" {
It 'Has a column called "dbadatetime"' {
$result.Columns.ColumnName | Should -Contain 'dbadatetime'
}
- It 'Has a [dbadatetime] data type on the column "myObject"' {
- $result.dbadatetime | Should -BeOfType [System.String]
+ It 'Has a [System.String] data type on the column "myObject"' {
+ $firstRow.dbadatetime | Should -BeOfType [System.String]
}
It "Has the following dbadatetime: 2024-05-19 05:52:00.000" {
$date = Get-Date -Year 2024 -Month 5 -Day 19 -Hour 5 -Minute 52 -Second 0 -Millisecond 0
- [datetime]$result.dbadatetime -eq $date | Should Be $true
+ [datetime]$result.dbadatetime -eq $date | Should -Be $true
}
}
@@ -171,12 +178,12 @@ Describe "Testing data table output when using a complex object" {
It 'Has a column called "dbadatetimeArray"' {
$result.Columns.ColumnName | Should -Contain 'dbadatetimeArray'
}
- It 'Has a [dbadatetimeArray] data type on the column "myObject"' {
- $result.dbadatetimeArray | Should -BeOfType [System.String]
+ It 'Has a [System.String] data type on the column "myObject"' {
+ $firstRow.dbadatetimeArray | Should -BeOfType [System.String]
}
It "Has the following dbadatetimeArray converted to strings: 2024-05-19 05:52:00.000, 2024-05-19 06:52:00.000" {
$string = '2024-05-19 05:52:00.000, 2024-05-19 06:52:00.000'
- $result.dbadatetimeArray -eq $string | Should Be $true
+ $firstRow.dbadatetimeArray -eq $string | Should -Be $true
}
}
}
@@ -188,25 +195,25 @@ Describe "Testing input parameters" {
Context "Verifying TimeSpanType" {
It "Should return '1.00:00:00' when String is used" {
- (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType String).Timespan | Should Be '1.00:00:00'
+ (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType String).Timespan | Should -Be '1.00:00:00'
}
It "Should return 864000000000 when Ticks is used" {
- (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType Ticks).Timespan | Should Be 864000000000
+ (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType Ticks).Timespan | Should -Be 864000000000
}
It "Should return 1 when TotalDays is used" {
- (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalDays).Timespan | Should Be 1
+ (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalDays).Timespan | Should -Be 1
}
It "Should return 24 when TotalHours is used" {
- (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalHours).Timespan | Should Be 24
+ (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalHours).Timespan | Should -Be 24
}
It "Should return 86400000 when TotalMilliseconds is used" {
- (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalMilliseconds).Timespan | Should Be 86400000
+ (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalMilliseconds).Timespan | Should -Be 86400000
}
It "Should return 1440 when TotalMinutes is used" {
- (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalMinutes).Timespan | Should Be 1440
+ (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalMinutes).Timespan | Should -Be 1440
}
It "Should return 86400 when TotalSeconds is used" {
- (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalSeconds).Timespan | Should Be 86400
+ (ConvertTo-DbaDataTable -InputObject $obj -TimeSpanType TotalSeconds).Timespan | Should -Be 86400
}
}
@@ -228,26 +235,26 @@ Describe "Testing input parameters" {
It "Does not create row if null is in array when IgnoreNull is set" {
$result = ConvertTo-DbaDataTable -InputObject (returnnull) -IgnoreNull -WarningAction SilentlyContinue
- $result.Rows.Count | Should Be 2
+ $result.Rows.Count | Should -Be 2
}
It "Does not create row if null is in pipeline when IgnoreNull is set" {
$result = returnnull | ConvertTo-DbaDataTable -IgnoreNull -WarningAction SilentlyContinue
- $result.Rows.Count | Should Be 2
+ $result.Rows.Count | Should -Be 2
}
It "Returns empty row when null value is provided (without IgnoreNull)" {
$result = ConvertTo-DbaDataTable -InputObject (returnnull)
- $result.Name[0] | Should Be 1
- $result.Name[1].GetType().FullName | Should Be 'System.DBNull'
- $result.Name[2] | Should Be 3
+ $result.Name[0] | Should -Be 1
+ $result.Name[1].GetType().FullName | Should -Be 'System.DBNull'
+ $result.Name[2] | Should -Be 3
}
It "Returns empty row when null value is passed in pipe (without IgnoreNull)" {
$result = returnnull | ConvertTo-DbaDataTable
- $result.Name[0] | Should Be 1
- $result.Name[1].GetType().FullName | Should Be 'System.DBNull'
- $result.Name[2] | Should Be 3
+ $result.Name[0] | Should -Be 1
+ $result.Name[1].GetType().FullName | Should -Be 'System.DBNull'
+ $result.Name[2] | Should -Be 3
}
}
@@ -261,7 +268,7 @@ Describe "Testing input parameters" {
It "Suppresses warning messages when Silent is used" {
$null = ConvertTo-DbaDataTable -InputObject (returnnull) -IgnoreNull -EnableException -WarningVariable warn -WarningAction SilentlyContinue
- $warn.message -eq $null | Should Be $true
+ $warn.message -eq $null | Should -Be $true
}
}
@@ -271,7 +278,7 @@ Describe "Testing input parameters" {
$myobj = New-Object -TypeName psobject -Property @{ Name = 'Test' }
$myobj | Add-Member -Force -MemberType ScriptProperty -Name ScriptNothing -Value { $null }
$r = ConvertTo-DbaDataTable -InputObject $myobj
- ($r.Columns | Where-Object ColumnName -eq ScriptNothing | Select-Object -ExpandProperty DataType).ToString() | Should Be 'System.String'
+ ($r.Columns | Where-Object ColumnName -eq ScriptNothing | Select-Object -ExpandProperty DataType).ToString() | Should -Be 'System.String'
}
}
diff --git a/tests/New-DbaAgentSchedule.Tests.ps1 b/tests/New-DbaAgentSchedule.Tests.ps1
index a781f34f19..74bb1c468c 100644
--- a/tests/New-DbaAgentSchedule.Tests.ps1
+++ b/tests/New-DbaAgentSchedule.Tests.ps1
@@ -6,7 +6,7 @@ Describe "$CommandName Unit Tests" -Tag 'UnitTests' {
Context "Validate parameters" {
It "Should only contain our specific parameters" {
[object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object { $_ -notin ('whatif', 'confirm') }
- [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Job', 'Schedule', 'Disabled', 'FrequencyType', 'FrequencyInterval', 'FrequencySubdayType', 'FrequencySubdayInterval', 'FrequencyRelativeInterval', 'FrequencyRecurrenceFactor', 'StartDate', 'EndDate', 'StartTime', 'EndTime', 'Force', 'EnableException'
+ [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Job', 'Schedule', 'Disabled', 'FrequencyType', 'FrequencyInterval', 'FrequencySubdayType', 'FrequencySubdayInterval', 'FrequencyRelativeInterval', 'FrequencyRecurrenceFactor', 'StartDate', 'EndDate', 'StartTime', 'EndTime', 'Owner', 'Force', 'EnableException'
$knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters
(@(Compare-Object -ReferenceObject ($knownParameters | Where-Object { $_ }) -DifferenceObject $params).Count ) | Should -Be 0
}
diff --git a/tests/appveyor.pester.ps1 b/tests/appveyor.pester.ps1
index fb79ff1ccc..b1ced2ba5b 100644
--- a/tests/appveyor.pester.ps1
+++ b/tests/appveyor.pester.ps1
@@ -189,6 +189,7 @@ if (-not $Finalize) {
#Make things faster by removing most output
if (-not $Finalize) {
Import-Module Pester
+ Write-Host -Object "appveyor.pester: Running with Pester Version $((Get-Command Invoke-Pester -ErrorAction SilentlyContinue).Version)" -ForegroundColor DarkGreen
Set-Variable ProgressPreference -Value SilentlyContinue
if ($AllScenarioTests.Count -eq 0) {
Write-Host -ForegroundColor DarkGreen "Nothing to do in this scenario"
diff --git a/tests/manual.pester.ps1 b/tests/manual.pester.ps1
index 493e3a5ae7..89d774c4e5 100644
--- a/tests/manual.pester.ps1
+++ b/tests/manual.pester.ps1
@@ -98,9 +98,15 @@ param (
$ScriptAnalyzer
)
+<#
+Remove-Module -Name Pester
+Import-Module -name Pester -MaximumVersion 4.*
+#>
+
$invokeFormatterVersion = (Get-Command Invoke-Formatter -ErrorAction SilentlyContinue).Version
$HasScriptAnalyzer = $null -ne $invokeFormatterVersion
$MinimumPesterVersion = [Version] '3.4.5.0' # Because this is when -Show was introduced
+$MaximumPesterVersion = [Version] '5.0.0.0' # Because our tests (and runners) are only compatible with 4.*
$PesterVersion = (Get-Command Invoke-Pester -ErrorAction SilentlyContinue).Version
$HasPester = $null -ne $PesterVersion
$ScriptAnalyzerCorrectVersion = '1.18.2'
@@ -127,11 +133,16 @@ if (!($HasPester)) {
}
if ($PesterVersion -lt $MinimumPesterVersion) {
Write-Warning "Please update Pester to at least 3.4.5"
- Write-Warning " Install-Module -Name Pester -Force -SkipPublisherCheck"
+ Write-Warning " Install-Module -Name Pester -MaximumVersion '4.10' -Force -SkipPublisherCheck"
+ Write-Warning " or go to https://github.com/pester/Pester"
+}
+if ($PesterVersion -gt $MaximumPesterVersion) {
+ Write-Warning "Please get Pester to the 4.* release"
+ Write-Warning " Install-Module -Name Pester -MaximumVersion '4.10' -Force -SkipPublisherCheck"
Write-Warning " or go to https://github.com/pester/Pester"
}
-if (($HasPester -and $HasScriptAnalyzer -and ($PesterVersion -ge $MinimumPesterVersion) -and ($invokeFormatterVersion -eq $ScriptAnalyzerCorrectVersion)) -eq $false) {
+if (($HasPester -and $HasScriptAnalyzer -and ($PesterVersion -ge $MinimumPesterVersion) -and ($PesterVersion -lt $MaximumPesterVersion) -and ($invokeFormatterVersion -eq $ScriptAnalyzerCorrectVersion)) -eq $false) {
Write-Warning "Exiting..."
return
}