From 686c1d5a83fe2f58e66b0f5a31ed1dd3ebfd8356 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Mon, 25 Dec 2017 17:10:43 +0100 Subject: [PATCH] SqlSetup: Added ASServerMode parameter (#964) - Changes to SqlSetup - Added parameter `ASServerMode` to support installing Analysis Services in Multidimensional mode, Tabular mode and PowerPivot mode (issue #388). - Added integration tests for testing Analysis Services Multidimensional mode and Tabular mode. --- CHANGELOG.md | 6 + DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 | 42 ++++ .../MSFT_SqlSetup/MSFT_SqlSetup.schema.mof | 1 + .../1-InstallDefaultInstanceSingleServer.ps1 | 4 +- README.md | 5 + .../MSFT_SqlSetup.Integration.Tests.ps1 | 190 +++++++++++++++--- Tests/Integration/MSFT_SqlSetup.config.ps1 | 114 +++++++++-- Tests/Unit/MSFT_SqlSetup.Tests.ps1 | 47 ++++- 8 files changed, 355 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5eb2ee62..c83b93d89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ ([issue #930](https://github.com/PowerShell/SqlServerDsc/issues/930)). - Made the description of parameter RestartService more descriptive ([issue #960](https://github.com/PowerShell/SqlServerDsc/issues/960)). +- Changes to SqlSetup + - Added parameter `ASServerMode` to support installing Analysis Services in + Multidimensional mode, Tabular mode and PowerPivot mode + ([issue #388](https://github.com/PowerShell/SqlServerDsc/issues/388)). + - Added integration tests for testing Analysis Services Multidimensional mode + and Tabular mode. ## 10.0.0.0 diff --git a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 index 6685b9c03..a23cc8bcb 100644 --- a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 +++ b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 @@ -293,6 +293,17 @@ function Get-TargetResource $analysisLogDirectory = $analysisServer.ServerProperties['LogDir'].Value $analysisBackupDirectory = $analysisServer.ServerProperties['BackupDir'].Value + <# + The property $analysisServer.ServerMode.value__ contains the + server mode (aka deployment mode) value 0, 1 or 2. See DeploymentMode + here https://docs.microsoft.com/en-us/sql/analysis-services/server-properties/general-properties. + + The property $analysisServer.ServerMode contains the display name of + the property value__. See more information here + https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.core.server.servermode.aspx. + #> + $analysisServerMode = $analysisServer.ServerMode.ToString().ToUpper() + $analysisSystemAdminAccounts = [System.String[]] $analysisServer.Roles['Administrators'].Members.Name $analysisConfigDirectory = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$analysisServiceName" -Name 'ImagePath').ImagePath.Replace(' -s ',',').Split(',')[1].Trim('"') @@ -487,6 +498,7 @@ function Get-TargetResource ASBackupDir = $analysisBackupDirectory ASTempDir = $analysisTempDirectory ASConfigDir = $analysisConfigDirectory + ASServerMode = $analysisServerMode ISSvcAccountUsername = $integrationServiceAccountUsername FailoverClusterGroupName = $clusteredSqlGroupName FailoverClusterNetworkName = $clusteredSqlHostname @@ -619,6 +631,13 @@ function Get-TargetResource .PARAMETER ASConfigDir Path for Analysis Services config. + .PARAMETER ASServerMode + 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. + { MULTIDIMENSIONAL | TABULAR | POWERPIVOT }. + .PARAMETER ISSvcAccount Service account for Integration Services service. @@ -797,6 +816,11 @@ function Set-TargetResource [System.String] $ASConfigDir, + [Parameter()] + [ValidateSet('MULTIDIMENSIONAL','TABULAR','POWERPIVOT', IgnoreCase = $false)] + [System.String] + $ASServerMode, + [Parameter()] [System.Management.Automation.PSCredential] $ISSvcAccount, @@ -1244,6 +1268,12 @@ function Set-TargetResource 'ASConfigDir' ) + + if ($PSBoundParameters.ContainsKey('ASServerMode')) + { + $setupArguments['ASServerMode'] = $ASServerMode + } + if ($PSBoundParameters.ContainsKey('ASSvcAccount')) { $setupArguments += (Get-ServiceAccountParameters -ServiceAccount $ASSvcAccount -ServiceType 'AS') @@ -1540,6 +1570,13 @@ function Set-TargetResource .PARAMETER ASConfigDir Path for Analysis Services config. + .PARAMETER ASServerMode + 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. + { MULTIDIMENSIONAL | TABULAR | POWERPIVOT }. + .PARAMETER ISSvcAccount Service account for Integration Services service. @@ -1717,6 +1754,11 @@ function Test-TargetResource [System.String] $ASConfigDir, + [Parameter()] + [ValidateSet('MULTIDIMENSIONAL','TABULAR','POWERPIVOT', IgnoreCase = $false)] + [System.String] + $ASServerMode, + [Parameter()] [System.Management.Automation.PSCredential] $ISSvcAccount, diff --git a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof index b937d47af..53831481e 100644 --- a/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof +++ b/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof @@ -44,6 +44,7 @@ class MSFT_SqlSetup : OMI_BaseResource [Write, Description("Path for Analysis Services backup files.")] String ASBackupDir; [Write, Description("Path for Analysis Services temp files.")] String ASTempDir; [Write, Description("Path for Analysis Services config.")] String ASConfigDir; + [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 Browser service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String BrowserSvcStartupType; diff --git a/Examples/Resources/SqlSetup/1-InstallDefaultInstanceSingleServer.ps1 b/Examples/Resources/SqlSetup/1-InstallDefaultInstanceSingleServer.ps1 index 9eafc2c7c..6e188f171 100644 --- a/Examples/Resources/SqlSetup/1-InstallDefaultInstanceSingleServer.ps1 +++ b/Examples/Resources/SqlSetup/1-InstallDefaultInstanceSingleServer.ps1 @@ -1,6 +1,7 @@ <# .EXAMPLE - This example shows how to install a default instance of SQL Server on a single server. + This example shows how to install a default instance of SQL Server, and + Analysis Services in Tabular mode, 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). @@ -74,6 +75,7 @@ Configuration Example SQLTempDBDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Data' SQLTempDBLogDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Data' SQLBackupDir = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup' + ASServerMode = 'TABULAR' ASConfigDir = 'C:\MSOLAP\Config' ASDataDir = 'C:\MSOLAP\Data' ASLogDir = 'C:\MSOLAP\Log' diff --git a/README.md b/README.md index 150cb89cd..966e57072 100644 --- a/README.md +++ b/README.md @@ -1374,6 +1374,11 @@ installing feature Database Engine and Analysis Services respectively. * **`[String]` ASBackupDir** _(Write)_: Path for Analysis Services backup files. * **`[String]` ASTempDir** _(Write)_: Path for Analysis Services temp files. * **`[String]` ASConfigDir** _(Write)_: Path for Analysis Services config. +* **`[String]` ASServerMode** _(Write)_: 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. + { MULTIDIMENSIONAL | TABULAR | POWERPIVOT }. * **`[PSCredential]` ISSvcAccount** _(Write)_: Service account for Integration Services service. * **`[String]` BrowserSvcStartupType** _(Write)_: Specifies the startup mode for diff --git a/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 b/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 index 7a86c282d..1c9054fd3 100644 --- a/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 +++ b/Tests/Integration/MSFT_SqlSetup.Integration.Tests.ps1 @@ -47,9 +47,13 @@ try . $configFile # These sets variables used for verification from the dot-sourced $ConfigurationData variable. - $mockInstanceName = $ConfigurationData.AllNodes.InstanceName - $mockFeatures = $ConfigurationData.AllNodes.Features - $mockSqlCollation = $ConfigurationData.AllNodes.SQLCollation + $mockSqlEngineInstanceName = $ConfigurationData.AllNodes.SqlEngineInstanceName + $mockSqlEngineFeatures = $ConfigurationData.AllNodes.SqlEngineFeatures + $mockAnalysisServicesTabularInstanceName = $ConfigurationData.AllNodes.AnalysisServicesTabularInstanceName + $mockAnalysisServicesTabularFeatures = $ConfigurationData.AllNodes.AnalysisServicesTabularFeatures + $mockAnalysisServicesTabularServerMode = $ConfigurationData.AllNodes.AnalysisServicesTabularServerMode + $mockAnalysisServicesMultiServerMode = $ConfigurationData.AllNodes.AnalysisServicesMultiServerMode + $mockCollation = $ConfigurationData.AllNodes.Collation $mockInstallSharedDir = $ConfigurationData.AllNodes.InstallSharedDir $mockInstallSharedWOWDir = $ConfigurationData.AllNodes.InstallSharedWOWDir $mockUpdateEnable = $ConfigurationData.AllNodes.UpdateEnabled @@ -99,10 +103,12 @@ try $mockSqlAgentServiceAccountUserName = "$env:COMPUTERNAME\svc-SqlAgent" $mockSqlAgentServiceCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $mockSqlAgentServiceAccountUserName, $mockSqlAgentServiceAccountPassword - $configurationName = "$($script:DSCResourceName)_InstallSqlEngineAsSystem_Config" - $resourceId = "[$($script:DSCResourceFriendlyName)]Integration_Test" + Describe "$($script:DSCResourceName)_InstallSqlEngineAsSystem_Integration" { + BeforeAll { + $configurationName = "$($script:DSCResourceName)_InstallSqlEngineAsSystem_Config" + $resourceId = "[$($script:DSCResourceFriendlyName)]Integration_Test" + } - Describe "$($script:DSCResourceName)_Integration" { It 'Should compile and apply the MOF without throwing' { { $configurationParameters = @{ @@ -173,30 +179,35 @@ try $resourceCurrentState.Action | Should -BeNullOrEmpty $resourceCurrentState.AgtSvcAccount | Should -BeNullOrEmpty $resourceCurrentState.AgtSvcAccountUsername | Should -Be ('.\{0}' -f (Split-Path -Path $mockSqlAgentServiceAccountUserName -Leaf)) - $resourceCurrentState.ASBackupDir | Should -BeNullOrEmpty - $resourceCurrentState.ASCollation | Should -BeNullOrEmpty - $resourceCurrentState.ASConfigDir | Should -BeNullOrEmpty - $resourceCurrentState.ASDataDir | Should -BeNullOrEmpty - $resourceCurrentState.ASLogDir | Should -BeNullOrEmpty + $resourceCurrentState.ASServerMode | Should -Be $mockAnalysisServicesMultiServerMode + $resourceCurrentState.ASBackupDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockSqlEngineInstanceName\OLAP\Backup") + $resourceCurrentState.ASCollation | Should -Be $mockCollation + $resourceCurrentState.ASConfigDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockSqlEngineInstanceName\OLAP\Config") + $resourceCurrentState.ASDataDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockSqlEngineInstanceName\OLAP\Data") + $resourceCurrentState.ASLogDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockSqlEngineInstanceName\OLAP\Log") + $resourceCurrentState.ASTempDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockSqlEngineInstanceName\OLAP\Temp") $resourceCurrentState.ASSvcAccount | Should -BeNullOrEmpty - $resourceCurrentState.ASSvcAccountUsername | Should -BeNullOrEmpty - $resourceCurrentState.ASSysAdminAccounts | Should -BeNullOrEmpty - $resourceCurrentState.ASTempDir | Should -BeNullOrEmpty + $resourceCurrentState.ASSvcAccountUsername | Should -Be ('.\{0}' -f (Split-Path -Path $mockSqlServiceAccountUserName -Leaf)) + $resourceCurrentState.ASSysAdminAccounts | Should -Be @( + $mockSqlAdminAccountUserName, + $mockSqlInstallAccountUserName, + "NT SERVICE\SSASTELEMETRY`$$mockSqlEngineInstanceName" + ) $resourceCurrentState.BrowserSvcStartupType | Should -BeNullOrEmpty $resourceCurrentState.ErrorReporting | Should -BeNullOrEmpty $resourceCurrentState.FailoverClusterGroupName | Should -BeNullOrEmpty $resourceCurrentState.FailoverClusterIPAddress | Should -BeNullOrEmpty $resourceCurrentState.FailoverClusterNetworkName | Should -BeNullOrEmpty - $resourceCurrentState.Features | Should -Be $mockFeatures + $resourceCurrentState.Features | Should -Be $mockSqlEngineFeatures $resourceCurrentState.ForceReboot | Should -BeNullOrEmpty $resourceCurrentState.FTSvcAccount | Should -BeNullOrEmpty $resourceCurrentState.FTSvcAccountUsername | Should -BeNullOrEmpty $resourceCurrentState.InstallSharedDir | Should -Be $mockInstallSharedDir $resourceCurrentState.InstallSharedWOWDir | Should -Be $mockInstallSharedWOWDir - $resourceCurrentState.InstallSQLDataDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockInstanceName\MSSQL") + $resourceCurrentState.InstallSQLDataDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockSqlEngineInstanceName\MSSQL") $resourceCurrentState.InstanceDir | Should -Be $mockInstallSharedDir - $resourceCurrentState.InstanceID | Should -Be $mockInstanceName - $resourceCurrentState.InstanceName | Should -Be $mockInstanceName + $resourceCurrentState.InstanceID | Should -Be $mockSqlEngineInstanceName + $resourceCurrentState.InstanceName | Should -Be $mockSqlEngineInstanceName $resourceCurrentState.ISSvcAccount | Should -BeNullOrEmpty $resourceCurrentState.ISSvcAccountUsername | Should -BeNullOrEmpty $resourceCurrentState.ProductKey | Should -BeNullOrEmpty @@ -207,23 +218,154 @@ try $resourceCurrentState.SetupProcessTimeout | Should -BeNullOrEmpty $resourceCurrentState.SourceCredential | Should -BeNullOrEmpty $resourceCurrentState.SourcePath | Should -Be "$($mockIsoMediaDriveLetter):\" - $resourceCurrentState.SQLBackupDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockInstanceName\MSSQL\Backup") - $resourceCurrentState.SQLCollation | Should -Be $mockSqlCollation + $resourceCurrentState.SQLBackupDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockSqlEngineInstanceName\MSSQL\Backup") + $resourceCurrentState.SQLCollation | Should -Be $mockCollation $resourceCurrentState.SQLSvcAccount | Should -BeNullOrEmpty $resourceCurrentState.SQLSvcAccountUsername | Should -Be ('.\{0}' -f (Split-Path -Path $mockSqlServiceAccountUserName -Leaf)) $resourceCurrentState.SQLSysAdminAccounts | Should -Be @( $mockSqlAdminAccountUserName, $mockSqlInstallAccountUserName, - "NT SERVICE\MSSQL`$$mockInstanceName", - "NT SERVICE\SQLAgent`$$mockInstanceName", + "NT SERVICE\MSSQL`$$mockSqlEngineInstanceName", + "NT SERVICE\SQLAgent`$$mockSqlEngineInstanceName", 'NT SERVICE\SQLWriter', 'NT SERVICE\Winmgmt', 'sa' ) $resourceCurrentState.SQLTempDBDir | Should -BeNullOrEmpty $resourceCurrentState.SQLTempDBLogDir | Should -BeNullOrEmpty - $resourceCurrentState.SQLUserDBDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockInstanceName\MSSQL\DATA\") - $resourceCurrentState.SQLUserDBLogDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockInstanceName\MSSQL\DATA\") + $resourceCurrentState.SQLUserDBDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockSqlEngineInstanceName\MSSQL\DATA\") + $resourceCurrentState.SQLUserDBLogDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSSQL13.$mockSqlEngineInstanceName\MSSQL\DATA\") + $resourceCurrentState.SQMReporting | Should -BeNullOrEmpty + $resourceCurrentState.SuppressReboot | Should -BeNullOrEmpty + $resourceCurrentState.UpdateEnabled | Should -BeNullOrEmpty + $resourceCurrentState.UpdateSource | Should -BeNullOrEmpty + + } + } + + Describe "$($script:DSCResourceName)_InstallAnalysisServicesAsSystem_Integration" { + BeforeAll { + $configurationName = "$($script:DSCResourceName)_InstallAnalysisServicesAsSystem_Config" + $resourceId = "[$($script:DSCResourceFriendlyName)]Integration_Test" + } + + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlInstallCredential = $mockSqlInstallCredential + SqlAdministratorCredential = $mockSqlAdminCredential + SqlServiceCredential = $mockSqlServiceCredential + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } -ErrorVariable itBlockError + + # Check if previous It-block failed. If so output the SQL Server setup log file. + if ( $itBlockError.Count -ne 0 ) + { + <# + Below code will output the Summary.txt log file, this is to be + able to debug any problems that potentially occurred during setup. + This will pick up the newest Summary.txt log file, so any + other log files will be ignored (AppVeyor build worker has + SQL Server instances installed by default). + This code is meant to work regardless what SQL Server + major version is used for the integration test. + #> + $summaryLogPath = Get-ChildItem -Path 'C:\Program Files\Microsoft SQL Server\**\Setup Bootstrap\Log\Summary.txt' | + Sort-Object -Property LastWriteTime -Descending | + Select-Object -First 1 + + $summaryLog = Get-Content $summaryLogPath + + Write-Verbose -Message $('-' * 80) -Verbose + Write-Verbose -Message 'Summary.txt' -Verbose + Write-Verbose -Message $('-' * 80) -Verbose + $summaryLog | ForEach-Object { + Write-Verbose $_ -Verbose + } + Write-Verbose -Message $('-' * 80) -Verbose + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $currentConfiguration = Get-DscConfiguration + + $resourceCurrentState = $currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Action | Should -BeNullOrEmpty + $resourceCurrentState.AgtSvcAccount | Should -BeNullOrEmpty + $resourceCurrentState.AgtSvcAccountUsername | Should -BeNullOrEmpty + $resourceCurrentState.ASServerMode | Should -Be $mockAnalysisServicesTabularServerMode + $resourceCurrentState.ASBackupDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockAnalysisServicesTabularInstanceName\OLAP\Backup") + $resourceCurrentState.ASCollation | Should -Be $mockCollation + $resourceCurrentState.ASConfigDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockAnalysisServicesTabularInstanceName\OLAP\Config") + $resourceCurrentState.ASDataDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockAnalysisServicesTabularInstanceName\OLAP\Data") + $resourceCurrentState.ASLogDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockAnalysisServicesTabularInstanceName\OLAP\Log") + $resourceCurrentState.ASTempDir | Should -Be (Join-Path -Path $mockInstallSharedDir -ChildPath "MSAS13.$mockAnalysisServicesTabularInstanceName\OLAP\Temp") + $resourceCurrentState.ASSvcAccount | Should -BeNullOrEmpty + $resourceCurrentState.ASSvcAccountUsername | Should -Be ('.\{0}' -f (Split-Path -Path $mockSqlServiceAccountUserName -Leaf)) + $resourceCurrentState.ASSysAdminAccounts | Should -Be @( + $mockSqlAdminAccountUserName, + $mockSqlInstallAccountUserName, + "NT SERVICE\SSASTELEMETRY`$$mockAnalysisServicesTabularInstanceName" + ) + $resourceCurrentState.BrowserSvcStartupType | Should -BeNullOrEmpty + $resourceCurrentState.ErrorReporting | Should -BeNullOrEmpty + $resourceCurrentState.FailoverClusterGroupName | Should -BeNullOrEmpty + $resourceCurrentState.FailoverClusterIPAddress | Should -BeNullOrEmpty + $resourceCurrentState.FailoverClusterNetworkName | Should -BeNullOrEmpty + $resourceCurrentState.Features | Should -Be $mockAnalysisServicesTabularFeatures + $resourceCurrentState.ForceReboot | Should -BeNullOrEmpty + $resourceCurrentState.FTSvcAccount | Should -BeNullOrEmpty + $resourceCurrentState.FTSvcAccountUsername | Should -BeNullOrEmpty + $resourceCurrentState.InstallSharedDir | Should -Be $mockInstallSharedDir + $resourceCurrentState.InstallSharedWOWDir | Should -Be $mockInstallSharedWOWDir + $resourceCurrentState.InstallSQLDataDir | Should -BeNullOrEmpty + $resourceCurrentState.InstanceDir | Should -BeNullOrEmpty + $resourceCurrentState.InstanceID | Should -BeNullOrEmpty + $resourceCurrentState.InstanceName | Should -Be $mockAnalysisServicesTabularInstanceName + $resourceCurrentState.ISSvcAccount | Should -BeNullOrEmpty + $resourceCurrentState.ISSvcAccountUsername | Should -BeNullOrEmpty + $resourceCurrentState.ProductKey | Should -BeNullOrEmpty + $resourceCurrentState.RSSvcAccount | Should -BeNullOrEmpty + $resourceCurrentState.RSSvcAccountUsername | Should -BeNullOrEmpty + $resourceCurrentState.SAPwd | Should -BeNullOrEmpty + $resourceCurrentState.SecurityMode | Should -BeNullOrEmpty + $resourceCurrentState.SetupProcessTimeout | Should -BeNullOrEmpty + $resourceCurrentState.SourceCredential | Should -BeNullOrEmpty + $resourceCurrentState.SourcePath | Should -Be "$($mockIsoMediaDriveLetter):\" + $resourceCurrentState.SQLBackupDir | Should -BeNullOrEmpty + $resourceCurrentState.SQLCollation | Should -BeNullOrEmpty + $resourceCurrentState.SQLSvcAccount | Should -BeNullOrEmpty + $resourceCurrentState.SQLSvcAccountUsername | Should -BeNullOrEmpty + $resourceCurrentState.SQLSysAdminAccounts | Should -BeNullOrEmpty + $resourceCurrentState.SQLTempDBDir | Should -BeNullOrEmpty + $resourceCurrentState.SQLTempDBLogDir | Should -BeNullOrEmpty + $resourceCurrentState.SQLUserDBDir | Should -BeNullOrEmpty + $resourceCurrentState.SQLUserDBLogDir | Should -BeNullOrEmpty $resourceCurrentState.SQMReporting | Should -BeNullOrEmpty $resourceCurrentState.SuppressReboot | Should -BeNullOrEmpty $resourceCurrentState.UpdateEnabled | Should -BeNullOrEmpty diff --git a/Tests/Integration/MSFT_SqlSetup.config.ps1 b/Tests/Integration/MSFT_SqlSetup.config.ps1 index 8843f48aa..9125097d3 100644 --- a/Tests/Integration/MSFT_SqlSetup.config.ps1 +++ b/Tests/Integration/MSFT_SqlSetup.config.ps1 @@ -9,21 +9,40 @@ $mockIsoMediaDriveLetter = [char](([int][char]$mockLastDrive) + 1) $ConfigurationData = @{ AllNodes = @( @{ - NodeName = 'localhost' - - InstanceName = 'DSCSQL2016' - Features = 'SQLENGINE,CONN,BC,SDK' - SQLCollation = 'Finnish_Swedish_CI_AS' - InstallSharedDir = 'C:\Program Files\Microsoft SQL Server' - InstallSharedWOWDir = 'C:\Program Files (x86)\Microsoft SQL Server' - UpdateEnabled = 'False' - SuppressReboot = $true # Make sure we don't reboot during testing. - ForceReboot = $false - - ImagePath = "$env:TEMP\SQL2016.iso" - DriveLetter = $mockIsoMediaDriveLetter - - PSDscAllowPlainTextPassword = $true + NodeName = 'localhost' + + # SQL Engine properties + SqlEngineInstanceName = 'DSCSQL2016' + SqlEngineFeatures = 'SQLENGINE,AS,CONN,BC,SDK' + AnalysisServicesMultiServerMode = 'MULTIDIMENSIONAL' + + # Analysis Services Tabular properties + AnalysisServicesTabularInstanceName = 'DSCTABULAR' + <# + CONN,BC,SDK is installed with the DSCSQL2016 so those feature + will found for DSCTABULAR instance as well. + #> + AnalysisServicesTabularFeatures = 'AS,CONN,BC,SDK' + AnalysisServicesTabularServerMode = 'TABULAR' + + # General SqlSetup properties + Collation = 'Finnish_Swedish_CI_AS' + InstallSharedDir = 'C:\Program Files\Microsoft SQL Server' + InstallSharedWOWDir = 'C:\Program Files (x86)\Microsoft SQL Server' + UpdateEnabled = 'False' + SuppressReboot = $true # Make sure we don't reboot during testing. + ForceReboot = $false + + # Properties for mounting media + ImagePath = "$env:TEMP\SQL2016.iso" + DriveLetter = $mockIsoMediaDriveLetter + + <# + We must compile the configuration using plain text since the + common integration test framework does not use certificates. + This should not be used in production. + #> + PSDscAllowPlainTextPassword = $true } ) } @@ -95,8 +114,8 @@ Configuration MSFT_SqlSetup_InstallSqlEngineAsSystem_Config Group 'AddSqlInstallAsAdministrator' { - Ensure = 'Present' - GroupName = 'Administrators' + Ensure = 'Present' + GroupName = 'Administrators' MembersToInclude = $SqlInstallCredential.UserName } @@ -115,13 +134,15 @@ Configuration MSFT_SqlSetup_InstallSqlEngineAsSystem_Config SqlSetup 'Integration_Test' { - InstanceName = $Node.InstanceName - Features = $Node.Features + InstanceName = $Node.SqlEngineInstanceName + Features = $Node.SqlEngineFeatures SourcePath = "$($Node.DriveLetter):\" BrowserSvcStartupType = 'Automatic' - SQLCollation = $Node.SQLCollation + SQLCollation = $Node.Collation SQLSvcAccount = $SqlServiceCredential AgtSvcAccount = $SqlAgentServiceCredential + ASServerMode = $Node.AnalysisServicesMultiServerMode + ASCollation = $Node.Collation ASSvcAccount = $SqlServiceCredential InstallSharedDir = $Node.InstallSharedDir InstallSharedWOWDir = $Node.InstallSharedWOWDir @@ -139,6 +160,12 @@ Configuration MSFT_SqlSetup_InstallSqlEngineAsSystem_Config $SqlInstallCredential.UserName ) + # This must be set if using SYSTEM account to install. + ASSysAdminAccounts = @( + $SqlAdministratorCredential.UserName + $SqlInstallCredential.UserName + ) + DependsOn = @( '[xMountImage]MountIsoMedia' '[User]CreateSqlServiceAccount' @@ -151,3 +178,50 @@ Configuration MSFT_SqlSetup_InstallSqlEngineAsSystem_Config } } } + +Configuration MSFT_SqlSetup_InstallAnalysisServicesAsSystem_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlInstallCredential, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlServiceCredential, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlSetup 'Integration_Test' + { + InstanceName = $Node.AnalysisServicesTabularInstanceName + Features = $Node.AnalysisServicesTabularFeatures + SourcePath = "$($Node.DriveLetter):\" + ASServerMode = $Node.AnalysisServicesTabularServerMode + ASCollation = $Node.Collation + ASSvcAccount = $SqlServiceCredential + InstallSharedDir = $Node.InstallSharedDir + InstallSharedWOWDir = $Node.InstallSharedWOWDir + UpdateEnabled = $Node.UpdateEnabled + SuppressReboot = $Node.SuppressReboot + ForceReboot = $Node.ForceReboot + + # This must be set if using SYSTEM account to install. + ASSysAdminAccounts = @( + $SqlAdministratorCredential.UserName + $SqlInstallCredential.UserName + ) + } + } +} + diff --git a/Tests/Unit/MSFT_SqlSetup.Tests.ps1 b/Tests/Unit/MSFT_SqlSetup.Tests.ps1 index a21083628..baa9ca2fa 100644 --- a/Tests/Unit/MSFT_SqlSetup.Tests.ps1 +++ b/Tests/Unit/MSFT_SqlSetup.Tests.ps1 @@ -626,26 +626,27 @@ try return @( ( New-Object Object | - Add-Member ScriptProperty ServerProperties { + Add-Member -MemberType ScriptProperty ServerProperties { return @{ - 'CollationName' = @( New-Object Object | Add-Member NoteProperty -Name 'Value' -Value $mockSqlAnalysisCollation -PassThru -Force ) - 'DataDir' = @( New-Object Object | Add-Member NoteProperty -Name 'Value' -Value $mockSqlAnalysisDataDirectory -PassThru -Force ) - 'TempDir' = @( New-Object Object | Add-Member NoteProperty -Name 'Value' -Value $mockSqlAnalysisTempDirectory -PassThru -Force ) - 'LogDir' = @( New-Object Object | Add-Member NoteProperty -Name 'Value' -Value $mockSqlAnalysisLogDirectory -PassThru -Force ) - 'BackupDir' = @( New-Object Object | Add-Member NoteProperty -Name 'Value' -Value $mockSqlAnalysisBackupDirectory -PassThru -Force ) + 'CollationName' = @( New-Object Object | Add-Member -MemberType NoteProperty -Name 'Value' -Value $mockSqlAnalysisCollation -PassThru -Force ) + 'DataDir' = @( New-Object Object | Add-Member -MemberType NoteProperty -Name 'Value' -Value $mockSqlAnalysisDataDirectory -PassThru -Force ) + 'TempDir' = @( New-Object Object | Add-Member -MemberType NoteProperty -Name 'Value' -Value $mockSqlAnalysisTempDirectory -PassThru -Force ) + 'LogDir' = @( New-Object Object | Add-Member -MemberType NoteProperty -Name 'Value' -Value $mockSqlAnalysisLogDirectory -PassThru -Force ) + 'BackupDir' = @( New-Object Object | Add-Member -MemberType NoteProperty -Name 'Value' -Value $mockSqlAnalysisBackupDirectory -PassThru -Force ) } } -PassThru | - Add-Member ScriptProperty Roles { + Add-Member -MemberType ScriptProperty Roles { return @{ 'Administrators' = @( New-Object Object | Add-Member ScriptProperty Members { return New-Object Object | - Add-Member ScriptProperty Name { + Add-Member -MemberType ScriptProperty Name { return $mockDynamicSqlAnalysisAdmins } -PassThru -Force } -PassThru -Force ) } - } -PassThru -Force + } -PassThru | + Add-Member -MemberType NoteProperty -Name 'ServerMode' -Value $mockDynamicAnalysisServerMode -PassThru -Force ) ) } @@ -985,6 +986,13 @@ try Mock -CommandName Get-ItemProperty -ParameterFilter { $Path -eq "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($mockSqlMajorVersion)0\Tools\Setup\Client_Components_Full" } -MockWith $mockGetItemProperty_ClientComponentsFull_FeatureList -Verifiable + + <# + This make sure the mock for Connect-SQLAnalysis get the correct + value for ServerMode property for the tests. It's dynamically + changed in other tests for testing different server modes. + #> + $mockDynamicAnalysisServerMode = 'MULTIDIMENSIONAL' } BeforeEach { @@ -1130,6 +1138,7 @@ try $result.ASBackupDir | Should -BeNullOrEmpty $result.ASTempDir | Should -BeNullOrEmpty $result.ASConfigDir | Should -BeNullOrEmpty + $result.ASServerMode | Should -BeNullOrEmpty $result.ISSvcAccountUsername | Should -BeNullOrEmpty } } @@ -1584,9 +1593,27 @@ try $result.ASBackupDir | Should -Be $mockSqlAnalysisBackupDirectory $result.ASTempDir | Should -Be $mockSqlAnalysisTempDirectory $result.ASConfigDir | Should -Be $mockSqlAnalysisConfigDirectory + $result.ASServerMode | Should -Be 'MULTIDIMENSIONAL' $result.ISSvcAccountUsername | Should -Be $mockSqlServiceAccount } + $mockDynamicAnalysisServerMode = 'POWERPIVOT' + + It 'Should return the correct values in the hash table' { + $result = Get-TargetResource @testParameters + $result.ASServerMode | Should -Be 'POWERPIVOT' + } + + $mockDynamicAnalysisServerMode = 'TABULAR' + + It 'Should return the correct values in the hash table' { + $result = Get-TargetResource @testParameters + $result.ASServerMode | Should -Be 'TABULAR' + } + + # Return the state to the default for all other tests. + $mockDynamicAnalysisServerMode = 'MULTIDIMENSIONAL' + <# This is a regression test for issue #691. This sets administrators to only one for mock Connect-SQLAnalysis. @@ -3068,6 +3095,7 @@ try InstallSharedWOWDir = 'C:\Program Files (x86)\Microsoft SQL Server' UpdateEnabled = 'True' UpdateSource = 'C:\Updates\' # Regression test for issue #720 + ASServerMode = 'TABULAR' } if ( $mockSqlMajorVersion -in (13,14) ) @@ -3091,6 +3119,7 @@ try InstallSharedWOWDir = 'C:\Program Files (x86)\Microsoft SQL Server' UpdateEnabled = 'True' UpdateSource = 'C:\Updates' # Regression test for issue #720 + ASServerMode = 'TABULAR' } { Set-TargetResource @testParameters } | Should -Not -Throw