diff --git a/CHANGELOG.md b/CHANGELOG.md index a438ad67c..ec265df54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,11 @@ forced to be reimported into the session. This is to support that a never version of SQL Server was installed side-by-side so that SQLPS module should be used instead. + - Added new parameters to allow to define the startup types for the Sql Engine + service, the Agent service, the Analysis service and the Integration Service. + The new optional parameters are respectively SqlSvcStartupType, AgtSvcStartupType, + AsSvcStartupType, IsSvcStartupType and RsSvcStartupType. ([issue #1165](https://github.com/PowerShell/SqlServerDsc/issues/1165). + [Maxime Daniou (@mdaniou)](https://github.com/mdaniou) ## 11.3.0.0 diff --git a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 index 9cdbec2a3..c44cc376e 100644 --- a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 +++ b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 @@ -12,7 +12,7 @@ $script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlSetup' .PARAMETER Action The action to be performed. Default value is 'Install'. - Possible values are 'Install', 'InstallFailoverCluster', 'AddNode', 'PrepareFailoverCluster', and 'CompleteFailoverCluster' + Possible values are 'Install', 'InstallFailoverCluster', 'AddNode', 'PrepareFailoverCluster', and 'CompleteFailoverCluster'. .PARAMETER SourcePath The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. @@ -30,7 +30,7 @@ $script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlSetup' Name of the SQL instance to be installed. .PARAMETER FailoverClusterNetworkName - Host name to be assigned to the clustered SQL Server instance + Host name to be assigned to the clustered SQL Server instance. #> function Get-TargetResource { @@ -125,9 +125,15 @@ function Get-TargetResource Write-Verbose -Message $script:localizedData.DatabaseEngineFeatureFound $features += 'SQLENGINE,' + + $sqlServiceCimInstance = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$databaseServiceName'") + $agentServiceCimInstance = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$agentServiceName'") - $sqlServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$databaseServiceName'").StartName - $agentServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$agentServiceName'").StartName + $sqlServiceAccountUsername = $sqlServiceCimInstance.StartName + $agentServiceAccountUsername = $agentServiceCimInstance.StartName + + $SqlSvcStartupType = ConvertTo-StartupType -StartMode $sqlServiceCimInstance.StartMode + $AgtSvcStartupType = ConvertTo-StartupType -StartMode $agentServiceCimInstance.StartMode $fullInstanceId = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' -Name $InstanceName).$InstanceName @@ -269,7 +275,9 @@ function Get-TargetResource Write-Verbose -Message $script:localizedData.ReportingServicesFeatureFound $features += 'RS,' - $reportingServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$reportServiceName'").StartName + $reportingServiceCimInstance = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$reportServiceName'") + $reportingServiceAccountUsername = $reportingServiceCimInstance.StartName + $RsSvcStartupType = ConvertTo-StartupType -StartMode $reportingServiceCimInstance.StartMode } else { @@ -283,7 +291,9 @@ function Get-TargetResource Write-Verbose -Message $script:localizedData.AnalysisServicesFeatureFound $features += 'AS,' - $analysisServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$analysisServiceName'").StartName + $analysisServiceCimInstance = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$analysisServiceName'") + $analysisServiceAccountUsername = $analysisServiceCimInstance.StartName + $AsSvcStartupType = ConvertTo-StartupType -StartMode $analysisServiceCimInstance.StartMode $analysisServer = Connect-SQLAnalysis -SQLServer $sqlHostName -SQLInstanceName $InstanceName @@ -320,7 +330,9 @@ function Get-TargetResource Write-Verbose -Message $script:localizedData.IntegrationServicesFeatureFound $features += 'IS,' - $integrationServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$integrationServiceName'").StartName + $integrationServiceCimInstance = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$integrationServiceName'") + $integrationServiceAccountUsername = $integrationServiceCimInstance.StartName + $IsSvcStartupType = ConvertTo-StartupType -StartMode $integrationServiceCimInstance.StartMode } else { @@ -478,7 +490,9 @@ function Get-TargetResource InstallSharedWOWDir = $installSharedWOWDir InstanceDir = $instanceDirectory SQLSvcAccountUsername = $sqlServiceAccountUsername + SqlSvcStartupType = $SqlSvcStartupType AgtSvcAccountUsername = $agentServiceAccountUsername + AgtSvcStartupType = $AgtSvcStartupType SQLCollation = $sqlCollation SQLSysAdminAccounts = $sqlSystemAdminAccounts SecurityMode = $securityMode @@ -490,7 +504,9 @@ function Get-TargetResource SQLBackupDir = $sqlBackupDirectory FTSvcAccountUsername = $fullTextServiceAccountUsername RSSvcAccountUsername = $reportingServiceAccountUsername + RsSvcStartupType = $RsSvcStartupType ASSvcAccountUsername = $analysisServiceAccountUsername + AsSvcStartupType = $AsSvcStartupType ASCollation = $analysisCollation ASSysAdminAccounts = $analysisSystemAdminAccounts ASDataDir = $analysisDataDirectory @@ -500,6 +516,7 @@ function Get-TargetResource ASConfigDir = $analysisConfigDirectory ASServerMode = $analysisServerMode ISSvcAccountUsername = $integrationServiceAccountUsername + IsSvcStartupType = $IsSvcStartupType FailoverClusterGroupName = $clusteredSqlGroupName FailoverClusterNetworkName = $clusteredSqlHostname FailoverClusterIPAddress = $clusteredSqlIPAddress @@ -512,7 +529,7 @@ function Get-TargetResource .PARAMETER Action The action to be performed. Default value is 'Install'. - Possible values are 'Install', 'InstallFailoverCluster', 'AddNode', 'PrepareFailoverCluster', and 'CompleteFailoverCluster' + Possible values are 'Install', 'InstallFailoverCluster', 'AddNode', 'PrepareFailoverCluster', and 'CompleteFailoverCluster'. .PARAMETER SourcePath The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. @@ -644,17 +661,32 @@ function Get-TargetResource .PARAMETER ISSvcAccount Service account for Integration Services service. + .PARAMETER SqlSvcStartupType + Specifies the startup mode for SQL Server Engine service. + + .PARAMETER AgtSvcStartupType + Specifies the startup mode for SQL Server Agent service. + + .PARAMETER AsSvcStartupType + Specifies the startup mode for SQL Server Analysis service. + + .PARAMETER IsSvcStartupType + Specifies the startup mode for SQL Server Integration service. + + .PARAMETER RsSvcStartupType + Specifies the startup mode for SQL Server Report service. + .PARAMETER BrowserSvcStartupType - Specifies the startup mode for SQL Server Browser service + Specifies the startup mode for SQL Server Browser service. .PARAMETER FailoverClusterGroupName The name of the resource group to create for the clustered SQL Server instance. Default is 'SQL Server (InstanceName)'. .PARAMETER FailoverClusterIPAddress - Array of IP Addresses to be assigned to the clustered SQL Server instance + Array of IP Addresses to be assigned to the clustered SQL Server instance. .PARAMETER FailoverClusterNetworkName - Host name to be assigned to the clustered SQL Server instance + Host name to be assigned to the clustered SQL Server instance. .PARAMETER SetupProcessTimeout The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown. @@ -837,6 +869,31 @@ function Set-TargetResource [System.Management.Automation.PSCredential] $ISSvcAccount, + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $SqlSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $AgtSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $IsSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $AsSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $RsSvcStartupType, + [Parameter()] [System.String] [ValidateSet('Automatic', 'Disabled', 'Manual')] @@ -1248,7 +1305,19 @@ function Set-TargetResource if ($Action -in @('Install')) { - $setupArguments += @{ AgtSvcStartupType = 'Automatic' } + if ($PSBoundParameters.ContainsKey('AgtSvcStartupType')) + { + $setupArguments.AgtSvcStartupType = $AgtSvcStartupType + } + else + { + $setupArguments += @{ AgtSvcStartupType = 'Automatic' } + } + + if ($PSBoundParameters.ContainsKey('SqlSvcStartupType')) + { + $setupArguments += @{ SqlSvcStartupType = $SqlSvcStartupType} + } } } @@ -1266,6 +1335,10 @@ function Set-TargetResource { $setupArguments += (Get-ServiceAccountParameters -ServiceAccount $RSSvcAccount -ServiceType 'RS') } + if ($PSBoundParameters.ContainsKey('RsSvcStartupType')) + { + $setupArguments += @{ RsSvcStartupType = $RsSvcStartupType} + } } if ($Features.Contains('AS')) @@ -1307,6 +1380,11 @@ function Set-TargetResource $setupArguments['ASSysAdminAccounts'] += $ASSysAdminAccounts } } + + if ($PSBoundParameters.ContainsKey('AsSvcStartupType')) + { + $setupArguments += @{ AsSvcStartupType = $AsSvcStartupType} + } } if ($Features.Contains('IS')) @@ -1315,6 +1393,11 @@ function Set-TargetResource { $setupArguments += (Get-ServiceAccountParameters -ServiceAccount $ISSvcAccount -ServiceType 'IS') } + + if ($PSBoundParameters.ContainsKey('IsSvcStartupType')) + { + $setupArguments += @{ IsSvcStartupType = $IsSvcStartupType} + } } # Automatically include any additional arguments @@ -1485,7 +1568,7 @@ function Set-TargetResource .PARAMETER Action The action to be performed. Default value is 'Install'. - Possible values are 'Install', 'InstallFailoverCluster', 'AddNode', 'PrepareFailoverCluster', and 'CompleteFailoverCluster' + Possible values are 'Install', 'InstallFailoverCluster', 'AddNode', 'PrepareFailoverCluster', and 'CompleteFailoverCluster'. .PARAMETER SourcePath The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. @@ -1617,17 +1700,32 @@ function Set-TargetResource .PARAMETER ISSvcAccount Service account for Integration Services service. + .PARAMETER SqlSvcStartupType + Specifies the startup mode for SQL Server Engine service. + + .PARAMETER AgtSvcStartupType + Specifies the startup mode for SQL Server Agent service. + + .PARAMETER IsSvcStartupType + Specifies the startup mode for SQL Server Integration service. + + .PARAMETER AsSvcStartupType + Specifies the startup mode for SQL Server Analysis service. + + .PARAMETER RsSvcStartupType + Specifies the startup mode for SQL Server Report service. + .PARAMETER BrowserSvcStartupType - Specifies the startup mode for SQL Server Browser service + Specifies the startup mode for SQL Server Browser service. .PARAMETER FailoverClusterGroupName The name of the resource group to create for the clustered SQL Server instance. Default is 'SQL Server (InstanceName)'. .PARAMETER FailoverClusterIPAddress - Array of IP Addresses to be assigned to the clustered SQL Server instance + Array of IP Addresses to be assigned to the clustered SQL Server instance. .PARAMETER FailoverClusterNetworkName - Host name to be assigned to the clustered SQL Server instance + Host name to be assigned to the clustered SQL Server instance. .PARAMETER SetupProcessTimeout The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown. @@ -1801,6 +1899,31 @@ function Test-TargetResource [System.Management.Automation.PSCredential] $ISSvcAccount, + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $SqlSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $AgtSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $IsSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $AsSvcStartupType, + + [Parameter()] + [System.String] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + $RsSvcStartupType, + [Parameter()] [System.String] [ValidateSet('Automatic', 'Disabled', 'Manual')] @@ -2035,10 +2158,10 @@ function Get-TemporaryFolder <# .SYNOPSIS - Returns the decimal representation of an IP Addresses + Returns the decimal representation of an IP Addresses. .PARAMETER IPAddress - The IP Address to be converted + The IP Address to be converted. #> function ConvertTo-Decimal { @@ -2063,16 +2186,16 @@ function ConvertTo-Decimal <# .SYNOPSIS - Determines whether an IP Address is valid for a given network / subnet + Determines whether an IP Address is valid for a given network / subnet. .PARAMETER IPAddress - IP Address to be checked + IP Address to be checked. .PARAMETER NetworkID - IP Address of the network identifier + IP Address of the network identifier. .PARAMETER SubnetMask - Subnet mask of the network to be checked + Subnet mask of the network to be checked. #> function Test-IPAddress { @@ -2103,13 +2226,13 @@ function Test-IPAddress <# .SYNOPSIS - Builds service account parameters for setup + Builds service account parameters for setup. .PARAMETER ServiceAccount - Credential for the service account + Credential for the service account. .PARAMETER ServiceType - Type of service account + Type of service account. #> function Get-ServiceAccountParameters { @@ -2168,7 +2291,7 @@ function Get-ServiceAccountParameters <# .SYNOPSIS - Starts the SQL setup process- + Starts the SQL setup process. .PARAMETER FilePath String containing the path to setup.exe. @@ -2210,4 +2333,28 @@ function Start-SqlSetupProcess return $sqlSetupProcess.ExitCode } +<# + .SYNOPSIS + Converts the start mode property returned by a Win32_Service CIM object to the resource properties *StartupType equivalent + + .PARAMETER StartMode + The StartMode to convert. +#> +function ConvertTo-StartupType +{ + param + ( + [Parameter()] + [System.String] + $StartMode + ) + + If ($StartMode -eq 'Auto') + { + $StartMode = 'Automatic' + } + + return $StartMode +} + Export-ModuleMember -Function *-TargetResource diff --git a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof index c486ac153..88610edea 100644 --- a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof +++ b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof @@ -47,6 +47,11 @@ class MSFT_SqlSetup : OMI_BaseResource [Write, Description("The server mode for SQL Server Analysis Services instance. The default is to install in Multidimensional mode. Valid values in a cluster scenario are MULTIDIMENSIONAL or TABULAR. Parameter ASServerMode is case-sensitive. All values must be expressed in upper case."), ValueMap{"MULTIDIMENSIONAL", "TABULAR", "POWERPIVOT"}, Values{"MULTIDIMENSIONAL", "TABULAR", "POWERPIVOT"}] String ASServerMode; [Write, EmbeddedInstance("MSFT_Credential"), Description("Service account for Integration Services service.")] String ISSvcAccount; [Read, Description("Output username for the Integration Services service.")] String ISSvcAccountUsername; + [Write, Description("Specifies the startup mode for SQL Server Sql Engine service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String SqlSvcStartupType; + [Write, Description("Specifies the startup mode for SQL Server Sql Agent service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String AgtSvcStartupType; + [Write, Description("Specifies the startup mode for SQL Server Integration service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String IsSvcStartupType; + [Write, Description("Specifies the startup mode for SQL Server Analysis service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String AsSvcStartupType; + [Write, Description("Specifies the startup mode for SQL Server Report service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String RSSVCStartupType; [Write, Description("Specifies the startup mode for SQL Server Browser service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String BrowserSvcStartupType; [Write, Description("The name of the resource group to create for the clustered SQL Server instance. Default is 'SQL Server (InstanceName)'.")] String FailoverClusterGroupName; [Write, Description("Array of IP Addresses to be assigned to the clustered SQL Server instance.")] String FailoverClusterIPAddress[]; diff --git a/Examples/Resources/SqlSetup/6-InstallNamedInstanceSingleServerWithAgtSvcStartupTypeDisabled.ps1 b/Examples/Resources/SqlSetup/6-InstallNamedInstanceSingleServerWithAgtSvcStartupTypeDisabled.ps1 new file mode 100644 index 000000000..b412aa9e9 --- /dev/null +++ b/Examples/Resources/SqlSetup/6-InstallNamedInstanceSingleServerWithAgtSvcStartupTypeDisabled.ps1 @@ -0,0 +1,94 @@ +<# + .EXAMPLE + This example shows how to install a named instance of SQL Server on a single server. + + .NOTES + SQL Server setup is run using the SYSTEM account. Even if SetupCredential is provided + it is not used to install SQL Server at this time (see issue #139). +#> +Configuration Example +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullorEmpty()] + [System.Management.Automation.PSCredential] + $SqlInstallCredential, + + [Parameter()] + [ValidateNotNullorEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential = $SqlInstallCredential, + + [Parameter(Mandatory = $true)] + [ValidateNotNullorEmpty()] + [System.Management.Automation.PSCredential] + $SqlServiceCredential, + + [Parameter()] + [ValidateNotNullorEmpty()] + [System.Management.Automation.PSCredential] + $SqlAgentServiceCredential = $SqlServiceCredential + ) + + Import-DscResource -ModuleName SqlServerDSC + + node localhost + { + #region Install prerequisites for SQL Server + WindowsFeature 'NetFramework35' + { + Name = 'NET-Framework-Core' + Source = '\\fileserver.company.local\images$\Win2k12R2\Sources\Sxs' # Assumes built-in Everyone has read permission to the share and path. + Ensure = 'Present' + } + + WindowsFeature 'NetFramework45' + { + Name = 'NET-Framework-45-Core' + Ensure = 'Present' + } + #endregion Install prerequisites for SQL Server + + #region Install SQL Server + SqlSetup 'InstallNamedInstance-INST2016' + { + InstanceName = 'INST2016' + Features = 'SQLENGINE,AS' + SQLCollation = 'SQL_Latin1_General_CP1_CI_AS' + SQLSvcAccount = $SqlServiceCredential + AgtSvcAccount = $SqlAgentServiceCredential + ASSvcAccount = $SqlServiceCredential + SQLSysAdminAccounts = 'COMPANY\SQL Administrators', $SqlAdministratorCredential.UserName + ASSysAdminAccounts = 'COMPANY\SQL Administrators', $SqlAdministratorCredential.UserName + InstallSharedDir = 'C:\Program Files\Microsoft SQL Server' + InstallSharedWOWDir = 'C:\Program Files (x86)\Microsoft SQL Server' + InstanceDir = 'C:\Program Files\Microsoft SQL Server' + InstallSQLDataDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Data' + SQLUserDBDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Data' + SQLUserDBLogDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Data' + SQLTempDBDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Data' + SQLTempDBLogDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Data' + SQLBackupDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Backup' + ASConfigDir = 'C:\MSOLAP13.INST2016\Config' + ASDataDir = 'C:\MSOLAP13.INST2016\Data' + ASLogDir = 'C:\MSOLAP13.INST2016\Log' + ASBackupDir = 'C:\MSOLAP13.INST2016\Backup' + ASTempDir = 'C:\MSOLAP13.INST2016\Temp' + SourcePath = 'C:\InstallMedia\SQL2016RTM' + UpdateEnabled = 'False' + ForceReboot = $false + + SqlSvcStartupType = 'Automatic' + AgtSvcStartupType = 'Disabled' + AsSvcStartupType = 'Automatic' + BrowserSvcStartupType = 'Automatic' + + PsDscRunAsCredential = $SqlInstallCredential + + DependsOn = '[WindowsFeature]NetFramework35', '[WindowsFeature]NetFramework45' + } + #endregion Install SQL Server + } +} diff --git a/README.md b/README.md index b8a6d3374..7f71a32cf 100644 --- a/README.md +++ b/README.md @@ -1633,8 +1633,18 @@ need a '*SVCPASSWORD' argument in the setup arguments. { MULTIDIMENSIONAL | TABULAR | POWERPIVOT }. * **`[PSCredential]` ISSvcAccount** _(Write)_: Service account for Integration Services service. +* **`[String]` SqlSvcStartupType** _(Write)_: Specifies the startup mode for + SQL Server Engine service. { Automatic | Disabled | Manual } +* **`[String]` AgtSvcStartupType** _(Write)_: Specifies the startup mode for + SQL Server Agent service. { Automatic | Disabled | Manual } +* **`[String]` AsSvcStartupType** _(Write)_: Specifies the startup mode for + SQL Server Analysis service. { Automatic | Disabled | Manual } +* **`[String]` IsSvcStartupType** _(Write)_: Specifies the startup mode for + SQL Server Integration service. { Automatic | Disabled | Manual } +* **`[String]` RsSvcStartupType** _(Write)_: Specifies the startup mode for + SQL Server Report service. { Automatic | Disabled | Manual } * **`[String]` BrowserSvcStartupType** _(Write)_: Specifies the startup mode for - SQL Server Browser service. { Automatic | Disabled | 'Manual' } + SQL Server Browser service. { Automatic | Disabled | Manual } * **`[String]` FailoverClusterGroupName** _(Write)_: The name of the resource group to create for the clustered SQL Server instance. Default is 'SQL Server (_InstanceName_)'. @@ -1670,6 +1680,7 @@ need a '*SVCPASSWORD' argument in the setup arguments. * [Install a named instance on a single server from an UNC path using SourceCredential](/Examples/Resources/SqlSetup/3-InstallNamedInstanceSingleServerFromUncPathUsingSourceCredential.ps1) * [Install a named instance as the first node in SQL Server Failover Cluster](/Examples/Resources/SqlSetup/4-InstallNamedInstanceInFailoverClusterFirstNode.ps1) * [Install a named instance as the second node in SQL Server Failover Cluster](/Examples/Resources/SqlSetup/5-InstallNamedInstanceInFailoverClusterSecondNode.ps1) +* [Install a named instance with the Agent Service set to Disabled](/Examples/Resources/SqlSetup/6-InstallNamedInstanceSingleServerWithAgtSvcStartupTypeDisabled.ps1) #### Known issues diff --git a/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 b/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 index 3a7fcd7e8..f542dc88d 100644 --- a/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 +++ b/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 @@ -251,6 +251,7 @@ try $resourceCurrentState.Action | Should -BeNullOrEmpty $resourceCurrentState.AgtSvcAccount | Should -BeNullOrEmpty $resourceCurrentState.AgtSvcAccountUsername | Should -Be ('.\{0}' -f (Split-Path -Path $mockSqlAgentServicePrimaryAccountUserName -Leaf)) + $resourceCurrentState.AgtSvcStartupType | Should -Be 'Automatic' $resourceCurrentState.ASServerMode | Should -Be $mockAnalysisServicesMultiServerMode $resourceCurrentState.ASBackupDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockDatabaseEngineNamedInstanceName\OLAP\Backup") $resourceCurrentState.ASCollation | Should -Be $mockCollation @@ -260,6 +261,7 @@ try $resourceCurrentState.ASTempDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockDatabaseEngineNamedInstanceName\OLAP\Temp") $resourceCurrentState.ASSvcAccount | Should -BeNullOrEmpty $resourceCurrentState.ASSvcAccountUsername | Should -Be ('.\{0}' -f (Split-Path -Path $mockSqlServicePrimaryAccountUserName -Leaf)) + $resourceCurrentState.AsSvcStartupType | Should -Be 'Automatic' $resourceCurrentState.ASSysAdminAccounts | Should -Be @( $mockSqlAdminAccountUserName, "NT SERVICE\SSASTELEMETRY`$$mockDatabaseEngineNamedInstanceName" @@ -293,6 +295,7 @@ try $resourceCurrentState.SQLCollation | Should -Be $mockCollation $resourceCurrentState.SQLSvcAccount | Should -BeNullOrEmpty $resourceCurrentState.SQLSvcAccountUsername | Should -Be ('.\{0}' -f (Split-Path -Path $mockSqlServicePrimaryAccountUserName -Leaf)) + $resourceCurrentState.SqlSvcStartupType | Should -Be 'Automatic' $resourceCurrentState.SQLSysAdminAccounts | Should -Be @( $mockSqlAdminAccountUserName, $mockSqlInstallAccountUserName, diff --git a/Tests/Integration/MSFT_SqlSetup.config.ps1 b/Tests/Integration/MSFT_SqlSetup.config.ps1 index fd42d9b29..aef829505 100644 --- a/Tests/Integration/MSFT_SqlSetup.config.ps1 +++ b/Tests/Integration/MSFT_SqlSetup.config.ps1 @@ -195,6 +195,8 @@ Configuration MSFT_SqlSetup_InstallDatabaseEngineNamedInstanceAsSystem_Config InstanceName = $Node.DatabaseEngineNamedInstanceName Features = $Node.DatabaseEngineNamedInstanceFeatures SourcePath = "$($Node.DriveLetter):\" + SqlSvcStartupType = 'Automatic' + AgtSvcStartupType = 'Automatic' BrowserSvcStartupType = 'Automatic' SecurityMode = 'SQL' SAPwd = $SqlAdministratorCredential @@ -202,6 +204,7 @@ Configuration MSFT_SqlSetup_InstallDatabaseEngineNamedInstanceAsSystem_Config SQLSvcAccount = $SqlServicePrimaryCredential AgtSvcAccount = $SqlAgentServicePrimaryCredential ASServerMode = $Node.AnalysisServicesMultiServerMode + AsSvcStartupType = 'Automatic' ASCollation = $Node.Collation ASSvcAccount = $SqlServicePrimaryCredential InstallSharedDir = $Node.InstallSharedDir diff --git a/Tests/Unit/MSFT_SqlSetup.Tests.ps1 b/Tests/Unit/MSFT_SqlSetup.Tests.ps1 index c13e57c57..f29cc5bff 100644 --- a/Tests/Unit/MSFT_SqlSetup.Tests.ps1 +++ b/Tests/Unit/MSFT_SqlSetup.Tests.ps1 @@ -105,7 +105,7 @@ try # Testing each supported SQL Server version $testProductVersion = @( - 14, # SQL Server "2017" + 14, # SQL Server 2017 13, # SQL Server 2016 12, # SQL Server 2014 11, # SQL Server 2012 @@ -177,6 +177,11 @@ try $mockAnalysisServicePassword = 'Analysiss3v!c3P@ssw0rd' $mockAnalysisServiceCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @($mockAnalysisServiceAccount,($mockAnalysisServicePassword | ConvertTo-SecureString -AsPlainText -Force)) + $mockAgtSvcStartupMode = 'Auto' + $mockAsSvcStartupMode = 'Auto' + $mockIsSvcStartupMode = 'Auto' + $mockRsSvcStartupMode = 'Auto' + $mockClusterNodes = @($env:COMPUTERNAME,'SQL01','SQL02') $mockSqlDataDirectoryPath = 'E:\MSSQL\Data' @@ -274,7 +279,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_DatabaseServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ) ) } @@ -284,7 +290,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_AgentServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockAgtSvcStartupMode -PassThru -Force ) ) } @@ -294,7 +301,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_FullTextServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ) ) } @@ -304,7 +312,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_ReportingServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ) ) } @@ -314,7 +323,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value ($mockDefaultInstance_IntegrationServiceName -f $mockSqlMajorVersion) -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ) ) } @@ -324,7 +334,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_AnalysisServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ) ) } @@ -334,12 +345,14 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_DatabaseServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_AgentServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockAgtSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | @@ -349,17 +362,20 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_ReportingServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockRsSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value ($mockDefaultInstance_IntegrationServiceName -f $mockSqlMajorVersion) -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockIsSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDefaultInstance_AnalysisServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockAsSvcStartupMode -PassThru -Force ) ) } @@ -369,7 +385,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_DatabaseServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ) ) } @@ -379,7 +396,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_AgentServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockAgtSvcStartupMode -PassThru -Force ) ) } @@ -399,7 +417,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_ReportingServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockRsSvcStartupMode -PassThru -Force ) ) } @@ -409,7 +428,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value ($mockNamedInstance_IntegrationServiceName -f $mockSqlMajorVersion) -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockIsSvcStartupMode -PassThru -Force ) ) } @@ -419,7 +439,8 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_AnalysisServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockAsSvcStartupMode -PassThru -Force ) ) } @@ -429,12 +450,14 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_DatabaseServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockSqlSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_AgentServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockAgentServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockAgtSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | @@ -444,17 +467,20 @@ try ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_ReportingServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockRsSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value ($mockNamedInstance_IntegrationServiceName -f $mockSqlMajorVersion) -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockIsSvcStartupMode -PassThru -Force ), ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockNamedInstance_AnalysisServiceName -PassThru | - Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force + Add-Member -MemberType NoteProperty -Name 'StartName' -Value $mockSqlServiceAccount -PassThru -Force | + Add-Member -MemberType NoteProperty -Name 'StartMode' -Value $mockAsSvcStartupMode -PassThru -Force ) ) } @@ -931,6 +957,12 @@ try Features = $defaultFeatures } + $MockSqlSvcStartupType = 'Automatic' + $MockAgtSvcStartupType = 'Automatic' + $MockAsSvcStartupType = 'Automatic' + $MockIsSvcStartupType = 'Automatic' + $MockRsSvcStartupType = 'Automatic' + $mockDefaultClusterParameters = @{ SQLSysAdminAccounts = 'COMPANY\User1','COMPANY\SQLAdmins' @@ -1030,7 +1062,7 @@ try if ($mockSqlMajorVersion -in (13,14)) { - # Mock all SSMS products here to make sure we don't return any when testing SQL Server 2016 + # Mock all SSMS products here to make sure we don't return any when testing SQL Server 2016 and 2017 Mock -CommandName Get-ItemProperty -ParameterFilter { $Path -eq (Join-Path -Path $mockRegistryUninstallProductsPath -ChildPath $mockSqlServerManagementStudio2008R2_ProductIdentifyingNumber) -or $Path -eq (Join-Path -Path $mockRegistryUninstallProductsPath -ChildPath $mockSqlServerManagementStudio2012_ProductIdentifyingNumber) -or @@ -3101,6 +3133,11 @@ try UpdateEnabled = 'True' UpdateSource = 'C:\Updates\' # Regression test for issue #720 ASServerMode = 'TABULAR' + SqlSvcStartupType = $mockSqlSvcStartupType + AgtSvcStartupType = $mockAgtSvcStartupType + AsSvcStartupType = $mockAsSvcStartupType + IsSvcStartupType = $mockIsSvcStartupType + RsSvcStartupType = $mockRsSvcStartupType } if ( $mockSqlMajorVersion -in (13,14) ) @@ -3112,7 +3149,6 @@ try Quiet = 'True' IAcceptSQLServerLicenseTerms = 'True' Action = 'Install' - AGTSVCSTARTUPTYPE = 'Automatic' InstanceName = 'MSSQLSERVER' Features = $testParameters.Features SQLSysAdminAccounts = 'COMPANY\sqladmin COMPANY\SQLAdmins COMPANY\User1' @@ -3125,6 +3161,11 @@ try UpdateEnabled = 'True' UpdateSource = 'C:\Updates' # Regression test for issue #720 ASServerMode = 'TABULAR' + SqlSvcStartupType = $mockSqlSvcStartupType + AgtSvcStartupType = $mockAgtSvcStartupType + AsSvcStartupType = $mockAsSvcStartupType + IsSvcStartupType = $mockIsSvcStartupType + RsSvcStartupType = $mockRsSvcStartupType } { Set-TargetResource @testParameters } | Should -Not -Throw @@ -3159,7 +3200,7 @@ try if( $mockSqlMajorVersion -in (13,14) ) { - It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016 and 2017' { $testParameters += @{ InstanceName = $mockDefaultInstance_InstanceName SourceCredential = $null @@ -3172,7 +3213,7 @@ try { Set-TargetResource @testParameters } | Should -Throw "'SSMS' is not a valid value for setting 'FEATURES'. Refer to SQL Help for more information." } - It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016 and 2017' { $testParameters += @{ InstanceName = $mockDefaultInstance_InstanceName SourceCredential = $null @@ -3365,14 +3406,14 @@ try if( $mockSqlMajorVersion -in (13,14) ) { - It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016 and 2017' { $testParameters.Features = 'SSMS' $mockStartSqlSetupProcessExpectedArgument = '' { Set-TargetResource @testParameters } | Should -Throw "'SSMS' is not a valid value for setting 'FEATURES'. Refer to SQL Help for more information." } - It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016 and 2017' { $testParameters.Features = 'ADV_SSMS' $mockStartSqlSetupProcessExpectedArgument = '' @@ -3539,14 +3580,14 @@ try if( $mockSqlMajorVersion -in (13,14) ) { - It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016 and 2017' { $testParameters.Features = 'SSMS' $mockStartSqlSetupProcessExpectedArgument = @{} { Set-TargetResource @testParameters } | Should -Throw "'SSMS' is not a valid value for setting 'FEATURES'. Refer to SQL Help for more information." } - It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016 and 2017' { $testParameters.Features = 'ADV_SSMS' $mockStartSqlSetupProcessExpectedArgument = @{} @@ -3710,14 +3751,14 @@ try if( $mockSqlMajorVersion -in (13,14) ) { - It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''SSMS'' when installing SQL Server 2016 and 2017' { $testParameters.Features = $($testParameters.Features), 'SSMS' -join ',' $mockStartSqlSetupProcessExpectedArgument = @{} { Set-TargetResource @testParameters } | Should -Throw "'SSMS' is not a valid value for setting 'FEATURES'. Refer to SQL Help for more information." } - It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016' { + It 'Should throw when feature parameter contains ''ADV_SSMS'' when installing SQL Server 2016 and 2017' { $testParameters.Features = $($testParameters.Features), 'ADV_SSMS' -join ',' $mockStartSqlSetupProcessExpectedArgument = @{}