From ece6f39ed240bc6c985fad6bf6be46d6ae1c2055 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Sat, 15 Apr 2023 17:37:29 +0200 Subject: [PATCH 01/16] SqlInstall: New resource --- CHANGELOG.md | 2 + source/Classes/011.SqlResourceBase.ps1 | 4 +- source/Classes/015.SqlSetupBase.ps1 | 34 + source/Classes/020.SqlInstall.ps1 | 837 +++++++++++++++++++++++++ 4 files changed, 875 insertions(+), 2 deletions(-) create mode 100644 source/Classes/015.SqlSetupBase.ps1 create mode 100644 source/Classes/020.SqlInstall.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dc985415..08ffc5704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -183,6 +183,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- New class-based resource: + - `SqlInstall` - Handles the Microsoft SQL Server setup action `Install`. - New public commands: - `Disconnect-SqlDscDatabaseEngine` - Disconnects from a SQL Server instance that was previously connected to using `Connect-SqlDscDatabaseEngine`. diff --git a/source/Classes/011.SqlResourceBase.ps1 b/source/Classes/011.SqlResourceBase.ps1 index bcd589217..adecd7da4 100644 --- a/source/Classes/011.SqlResourceBase.ps1 +++ b/source/Classes/011.SqlResourceBase.ps1 @@ -1,7 +1,7 @@ <# .SYNOPSIS - The SqlResource base have generic properties and methods for the class-based - resources. + The SqlResourceBase have generic properties and methods that are common for + all the class-based resources. .PARAMETER InstanceName The name of the _SQL Server_ instance to be configured. Default value is diff --git a/source/Classes/015.SqlSetupBase.ps1 b/source/Classes/015.SqlSetupBase.ps1 new file mode 100644 index 000000000..86a967a15 --- /dev/null +++ b/source/Classes/015.SqlSetupBase.ps1 @@ -0,0 +1,34 @@ +<# + .SYNOPSIS + The SqlSetupBase have generic properties and methods that are common for + the setup action class-based resources. + + .PARAMETER MediaPath + Specifies the path where to find the SQL Server installation media. On this + path the SQL Server setup executable must be found. + + .PARAMETER ConfigurationFile + Specifies an configuration file to use during SQL Server setup. This + parameter cannot be used together with any of the setup actions, but instead + it is expected that the configuration file specifies what setup action to + run. + + .PARAMETER Timeout + Specifies how long to wait for the setup process to finish. Uses the default + value of the command `Install-SqlDscServer`. If the setup process does not + finish before this time, an exception will be thrown. +#> +class SqlSetupBase : SqlResourceBase +{ + [DscProperty(Mandatory)] + [System.String] + $MediaPath + + [DscProperty()] + [System.String] + $ConfigurationFile + + [DscProperty()] + [System.UInt32] + $Timeout +} diff --git a/source/Classes/020.SqlInstall.ps1 b/source/Classes/020.SqlInstall.ps1 new file mode 100644 index 000000000..819c35ef8 --- /dev/null +++ b/source/Classes/020.SqlInstall.ps1 @@ -0,0 +1,837 @@ +<# + .SYNOPSIS + The `SqlInstall` DSC resource is used to create, modify, or remove + server audits. + + .DESCRIPTION + The `SqlInstall` DSC resource is used to create, modify, or remove + server audits. + + The parameters are intentionally not described since it would take a lot + of effort to keep them up to date. See the [SQL Server command line setup](https://docs.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server-from-the-command-prompt) + documentation which will stay relevant. + + The built-in parameter **PSDscRunAsCredential** can be used to run the resource + as another user. The resource will then authenticate to the SQL Server + instance as that user. It also possible to instead use impersonation by the + parameter **Credential**. + + ## Requirements + + * Target machine must be running Windows Server 2012 or later. + * Target machine must be running SQL Server Database Engine 2012 or later. + * Target machine must have access to the SQLPS PowerShell module or the SqlServer + PowerShell module. + + ## Known issues + + All issues are not listed here, see [here for all open issues](https://github.com/dsccommunity/SqlServerDsc/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+SqlInstall). + + ### Property **Reasons** does not work with **PSDscRunAsCredential** + + When using the built-in parameter **PSDscRunAsCredential** the read-only + property **Reasons** will return empty values for the properties **Code** + and **Phrase. The built-in property **PSDscRunAsCredential** does not work + together with class-based resources that using advanced type like the parameter + **Reasons** have. + + ### Using **Credential** property + + SQL Authentication and Group Managed Service Accounts is not supported as + impersonation credentials. Currently only Windows Integrated Security is + supported to use as credentials. + + For Windows Authentication the username must either be provided with the User + Principal Name (UPN), e.g. `username@domain.local` or if using non-domain + (for example a local Windows Server account) account the username must be + provided without the NetBIOS name, e.g. `username`. Using the NetBIOS name, e.g + using the format `DOMAIN\username` will not work. + + See more information in [Credential Overview](https://github.com/dsccommunity/SqlServerDsc/wiki/CredentialOverview). + + .PARAMETER AcceptLicensingTerms + Required parameter to be able to run unattended install. By specifying this + parameter you acknowledge the acceptance all license terms and notices for + the specified features, the terms and notices that the Microsoft SQL Server + setup executable normally ask for. + + .PARAMETER SuppressPrivacyStatementNotice + See the notes section for more information. + + .PARAMETER IAcknowledgeEntCalLimits + See the notes section for more information. + + .PARAMETER Enu + See the notes section for more information. + + .PARAMETER UpdateEnabled + See the notes section for more information. + + .PARAMETER UpdateSource + See the notes section for more information. + + .PARAMETER Features + See the notes section for more information. + + .PARAMETER InstallSharedDir + See the notes section for more information. + + .PARAMETER InstallSharedWowDir + See the notes section for more information. + + .PARAMETER InstanceDir + See the notes section for more information. + + .PARAMETER InstanceId + See the notes section for more information. + + .PARAMETER PBEngSvcAccount + See the notes section for more information. + + .PARAMETER PBEngSvcPassword + See the notes section for more information. + + .PARAMETER PBEngSvcStartupType + See the notes section for more information. + + .PARAMETER PBDMSSvcAccount + See the notes section for more information. + + .PARAMETER PBDMSSvcPassword + See the notes section for more information. + + .PARAMETER PBDMSSvcStartupType + See the notes section for more information. + + .PARAMETER PBStartPortRange + See the notes section for more information. + + .PARAMETER PBEndPortRange + See the notes section for more information. + + .PARAMETER PBScaleOut + See the notes section for more information. + + .PARAMETER ProductKey + See the notes section for more information. + + .PARAMETER AgtSvcAccount + See the notes section for more information. + + .PARAMETER AgtSvcPassword + See the notes section for more information. + + .PARAMETER AgtSvcStartupType + See the notes section for more information. + + .PARAMETER ASBackupDir + See the notes section for more information. + + .PARAMETER ASCollation + See the notes section for more information. + + .PARAMETER ASConfigDir + See the notes section for more information. + + .PARAMETER ASDataDir + See the notes section for more information. + + .PARAMETER ASLogDir + See the notes section for more information. + + .PARAMETER ASTempDir + See the notes section for more information. + + .PARAMETER ASServerMode + See the notes section for more information. + + .PARAMETER ASSvcAccount + See the notes section for more information. + + .PARAMETER ASSvcPassword + See the notes section for more information. + + .PARAMETER ASSvcStartupType + See the notes section for more information. + + .PARAMETER ASSysAdminAccounts + See the notes section for more information. + + .PARAMETER ASProviderMSOLAP + See the notes section for more information. + + .PARAMETER BrowserSvcStartupType + See the notes section for more information. + + .PARAMETER FTUpgradeOption + See the notes section for more information. + + .PARAMETER EnableRanU + See the notes section for more information. + + .PARAMETER InstallSqlDataDir + See the notes section for more information. + + .PARAMETER SqlBackupDir + See the notes section for more information. + + .PARAMETER SecurityMode + See the notes section for more information. + + .PARAMETER SAPwd + See the notes section for more information. + + .PARAMETER SqlCollation + See the notes section for more information. + + .PARAMETER SqlSvcAccount + See the notes section for more information. + + .PARAMETER SqlSvcPassword + See the notes section for more information. + + .PARAMETER SqlSvcStartupType + See the notes section for more information. + + .PARAMETER SqlSysAdminAccounts + See the notes section for more information. + + .PARAMETER SqlTempDbDir + See the notes section for more information. + + .PARAMETER SqlTempDbLogDir + See the notes section for more information. + + .PARAMETER SqlTempDbFileCount + See the notes section for more information. + + .PARAMETER SqlTempDbFileSize + See the notes section for more information. + + .PARAMETER SqlTempDbFileGrowth + See the notes section for more information. + + .PARAMETER SqlTempDbLogFileSize + See the notes section for more information. + + .PARAMETER SqlTempDbLogFileGrowth + See the notes section for more information. + + .PARAMETER SqlUserDbDir + See the notes section for more information. + + .PARAMETER SqlSvcInstantFileInit + See the notes section for more information. + + .PARAMETER SqlUserDbLogDir + See the notes section for more information. + + .PARAMETER SqlMaxDop + See the notes section for more information. + + .PARAMETER UseSqlRecommendedMemoryLimits + See the notes section for more information. + + .PARAMETER SqlMinMemory + See the notes section for more information. + + .PARAMETER SqlMaxMemory + See the notes section for more information. + + .PARAMETER FileStreamLevel + See the notes section for more information. + + .PARAMETER FileStreamShareName + See the notes section for more information. + + .PARAMETER ISSvcAccount + See the notes section for more information. + + .PARAMETER ISSvcPassword + See the notes section for more information. + + .PARAMETER ISSvcStartupType + See the notes section for more information. + + .PARAMETER AllowUpgradeForSSRSSharePointMode + See the notes section for more information. + + .PARAMETER NpEnabled + See the notes section for more information. + + .PARAMETER TcpEnabled + See the notes section for more information. + + .PARAMETER RsInstallMode + See the notes section for more information. + + .PARAMETER RSSvcAccount + See the notes section for more information. + + .PARAMETER RSSvcPassword + See the notes section for more information. + + .PARAMETER RSSvcStartupType + See the notes section for more information. + + .PARAMETER MPYCacheDirectory + See the notes section for more information. + + .PARAMETER MRCacheDirectory + See the notes section for more information. + + .PARAMETER SqlInstJava + See the notes section for more information. + + .PARAMETER SqlJavaDir + See the notes section for more information. + + .PARAMETER FailoverClusterGroup + See the notes section for more information. + + .PARAMETER FailoverClusterDisks + See the notes section for more information. + + .PARAMETER FailoverClusterNetworkName + See the notes section for more information. + + .PARAMETER FailoverClusterIPAddresses + See the notes section for more information. + + .PARAMETER FailoverClusterRollOwnership + See the notes section for more information. + + .PARAMETER AzureSubscriptionId + See the notes section for more information. + + .PARAMETER AzureResourceGroup + See the notes section for more information. + + .PARAMETER AzureRegion + See the notes section for more information. + + .PARAMETER AzureTenantId + See the notes section for more information. + + .PARAMETER AzureServicePrincipal + See the notes section for more information. + + .PARAMETER AzureServicePrincipalSecret + See the notes section for more information. + + .PARAMETER AzureArcProxy + See the notes section for more information. + + .PARAMETER SkipRules + See the notes section for more information. + + .PARAMETER ProductCoveredBySA + See the notes section for more information. + + .EXAMPLE + TODO: Must update the example. + + Invoke-DscResource -ModuleName SqlServerDsc -Name SqlInstall -Method Get -Property @{ + ServerName = 'localhost' + InstanceName = 'SQL2017' + Credential = (Get-Credential -UserName 'myuser@company.local' -Message 'Password:') + Features = 'SQLENGINE' + } + + This example shows how to call the resource using Invoke-DscResource. +#> +[DscResource(RunAsCredential = 'Optional')] +class SqlInstall : SqlSetupBase +{ + [DscProperty(Mandatory)] + [Nullable[System.Boolean]] + $AcceptLicensingTerms + + [DscProperty()] + [Nullable[System.Boolean]] + $SuppressPrivacyStatementNotice + + [DscProperty()] + [Nullable[System.Boolean]] + $IAcknowledgeEntCalLimits + + [DscProperty()] + [Nullable[System.Boolean]] + $Enu + + [DscProperty()] + [Nullable[System.Boolean]] + $UpdateEnabled + + [DscProperty()] + [System.String] + $UpdateSource + + [DscProperty(Mandatory)] + [ValidateSet( + 'SQL', + 'SQLEngine', # Part of parent feature SQL + 'Replication', # Part of parent feature SQL + 'FullText', # Part of parent feature SQL + 'DQ', # Part of parent feature SQL + 'PolyBase', # Part of parent feature SQL + 'PolyBaseCore', # Part of parent feature SQL + 'PolyBaseJava', # Part of parent feature SQL + 'AdvancedAnalytics', # Part of parent feature SQL + 'SQL_INST_MR', # Part of parent feature SQL + 'SQL_INST_MPY', # Part of parent feature SQL + 'SQL_INST_JAVA', # Part of parent feature SQL + 'AS', + 'RS', + 'RS_SHP', + 'RS_SHPWFE', # cspell: disable-line + 'DQC', + 'IS', + 'IS_Master', # Part of parent feature IS + 'IS_Worker', # Part of parent feature IS + 'MDS', + 'SQL_SHARED_MPY', + 'SQL_SHARED_MR', + 'Tools', + 'BC', # Part of parent feature Tools + 'Conn', # Part of parent feature Tools + 'DREPLAY_CTLR', # Part of parent feature Tools (cspell: disable-line) + 'DREPLAY_CLT', # Part of parent feature Tools (cspell: disable-line) + 'SNAC_SDK', # Part of parent feature Tools (cspell: disable-line) + 'SDK', # Part of parent feature Tools + 'LocalDB', # Part of parent feature Tools + 'AZUREEXTENSION' + )] + [System.String[]] + $Features + + [DscProperty()] + [System.String] + $InstallSharedDir + + [DscProperty()] + [System.String] + $InstallSharedWowDir + + [DscProperty()] + [System.String] + $InstanceDir + + [DscProperty()] + [System.String] + $InstanceId + + [DscProperty()] + [System.String] + $PBEngSvcAccount + + [DscProperty()] + [System.Security.SecureString] + $PBEngSvcPassword + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $PBEngSvcStartupType + + [DscProperty()] + [System.String] + $PBDMSSvcAccount + + [DscProperty()] + [System.Security.SecureString] + $PBDMSSvcPassword + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $PBDMSSvcStartupType + + [DscProperty()] + [Nullable[System.UInt16]] + $PBStartPortRange + + [DscProperty()] + [Nullable[System.UInt16]] + $PBEndPortRange + + [DscProperty()] + [Nullable[System.Boolean]] + $PBScaleOut + + [DscProperty()] + [System.String] + $ProductKey # This is argument PID but $PID is reserved variable. + + [DscProperty()] + [System.String] + $AgtSvcAccount + + [DscProperty()] + [System.Security.SecureString] + $AgtSvcPassword + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $AgtSvcStartupType + + [DscProperty()] + [System.String] + $ASBackupDir + + [DscProperty()] + [System.String] + $ASCollation + + [DscProperty()] + [System.String] + $ASConfigDir + + [DscProperty()] + [System.String] + $ASDataDir + + [DscProperty()] + [System.String] + $ASLogDir + + [DscProperty()] + [System.String] + $ASTempDir + + [DscProperty()] + [ValidateSet('Multidimensional', 'PowerPivot', 'Tabular')] + [System.String] + $ASServerMode + + [DscProperty()] + [System.String] + $ASSvcAccount + + [DscProperty()] + [System.Security.SecureString] + $ASSvcPassword + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $ASSvcStartupType + + [DscProperty()] + [System.String[]] + $ASSysAdminAccounts + + [DscProperty()] + [Nullable[System.Boolean]] + $ASProviderMSOLAP + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $BrowserSvcStartupType + + [DscProperty()] + [Nullable[System.Boolean]] + $EnableRanU + + [DscProperty()] + [System.String] + $InstallSqlDataDir + + [DscProperty()] + [System.String] + $SqlBackupDir + + [DscProperty()] + [ValidateSet('SQL')] + [System.String] + $SecurityMode + + [DscProperty()] + [System.Security.SecureString] + $SAPwd + + [DscProperty()] + [System.String] + $SqlCollation + + [DscProperty()] + [System.String] + $SqlSvcAccount + + [DscProperty()] + [System.Security.SecureString] + $SqlSvcPassword + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $SqlSvcStartupType + + [DscProperty()] + [System.String[]] + $SqlSysAdminAccounts + + [DscProperty()] + [System.String] + $SqlTempDbDir + + [DscProperty()] + [System.String] + $SqlTempDbLogDir + + [DscProperty()] + [Nullable[System.UInt16]] + $SqlTempDbFileCount + + [DscProperty()] + [ValidateRange(4, 262144)] + [Nullable[System.UInt16]] + $SqlTempDbFileSize + + [DscProperty()] + [ValidateRange(0, 1024)] + [Nullable[System.UInt16]] + $SqlTempDbFileGrowth + + [DscProperty()] + [ValidateRange(4, 262144)] + [Nullable[System.UInt16]] + $SqlTempDbLogFileSize + + [DscProperty()] + [ValidateRange(0, 1024)] + [Nullable[System.UInt16]] + $SqlTempDbLogFileGrowth + + [DscProperty()] + [System.String] + $SqlUserDbDir + + [DscProperty()] + [Nullable[System.Boolean]] + $SqlSvcInstantFileInit + + [DscProperty()] + [System.String] + $SqlUserDbLogDir + + [DscProperty()] + [ValidateRange(0, 32767)] + [Nullable[System.UInt16]] + $SqlMaxDop + + [DscProperty()] + [Nullable[System.Boolean]] + $UseSqlRecommendedMemoryLimits + + [DscProperty()] + [ValidateRange(0, 2147483647)] + [Nullable[System.UInt32]] + $SqlMinMemory + + [DscProperty()] + [ValidateRange(0, 2147483647)] + [Nullable[System.UInt32]] + $SqlMaxMemory + + [DscProperty()] + [ValidateRange(0, 3)] + [Nullable[System.UInt16]] + $FileStreamLevel + + [DscProperty()] + [System.String] + $FileStreamShareName + + [DscProperty()] + [System.String] + $ISSvcAccount + + [DscProperty()] + [System.Security.SecureString] + $ISSvcPassword + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $ISSvcStartupType + + [DscProperty()] + [Nullable[System.Boolean]] + $NpEnabled + + [DscProperty()] + [Nullable[System.Boolean]] + $TcpEnabled + + [DscProperty()] + [ValidateSet('SharePointFilesOnlyMode', 'DefaultNativeMode', 'FilesOnlyMode')] + [System.String] + $RsInstallMode + + [DscProperty()] + [System.String] + $RSSvcAccount + + [DscProperty()] + [System.Security.SecureString] + $RSSvcPassword + + [DscProperty()] + [ValidateSet('Automatic', 'Disabled', 'Manual')] + [System.String] + $RSSvcStartupType + + [DscProperty()] + [System.String] + $MPYCacheDirectory + + [DscProperty()] + [System.String] + $MRCacheDirectory + + [DscProperty()] + [Nullable[System.Boolean]] + $SqlInstJava + + [DscProperty()] + [System.String] + $SqlJavaDir + + [DscProperty()] + [System.String] + $AzureSubscriptionId + + [DscProperty()] + [System.String] + $AzureResourceGroup + + [DscProperty()] + [System.String] + $AzureRegion + + [DscProperty()] + [System.String] + $AzureTenantId + + [DscProperty()] + [System.String] + $AzureServicePrincipal + + [DscProperty()] + [System.Security.SecureString] + $AzureServicePrincipalSecret + + [DscProperty()] + [System.String] + $AzureArcProxy + + [DscProperty()] + [System.String[]] + $SkipRules + + [DscProperty()] + [Nullable[System.Boolean]] + $ProductCoveredBySA + + SqlInstall () : base () + { + # These properties will not be enforced. + $this.ExcludeDscProperties = @( + 'ServerName' + 'InstanceName' + 'Name' + 'Credential' + 'Force' + ) + } + + [SqlInstall] Get() + { + # Call the base method to return the properties. + return ([ResourceBase] $this).Get() + } + + [Nullable[System.Boolean]] Test() + { + # Call the base method to test all of the properties that should be enforced. + return ([ResourceBase] $this).Test() + } + + [void] Set() + { + # Call the base method to enforce the properties. + ([ResourceBase] $this).Set() + } + + <# + Base method Get() call this method to get the current state as a hashtable. + The parameter properties will contain the key properties. + #> + hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) + { + Write-Verbose -Message ( + $this.localizedData.EvaluateServerAudit -f @( + $properties.Name, + $properties.InstanceName + ) + ) + + $currentStateCredential = $null + + if ($this.Credential) + { + <# + This does not work, even if username is set, the method Get() will + return an empty PSCredential-object. Kept it here so it at least + return a Credential object. + #> + $currentStateCredential = [PSCredential]::new( + $this.Credential.UserName, + [SecureString]::new() + ) + } + + <# + Only set key property Name if the audit exist. Base class will set it + and handle Ensure. + #> + $currentState = @{ + Credential = $currentStateCredential + InstanceName = $properties.InstanceName + ServerName = $this.ServerName + } + + $serverObject = $this.GetServerObject() + + # TODO: Should call commands that can return the installed state. + + # $auditObjectArray = $serverObject | + # Get-SqlDscAudit -Name $properties.Name -ErrorAction 'SilentlyContinue' + + return $currentState + } + + <# + Base method Set() call this method with the properties that should be + enforced are not in desired state. It is not called if all properties + are in desired state. The variable $properties contain the properties + that are not in desired state. + #> + hidden [void] Modify([System.Collections.Hashtable] $properties) + { + Install-SqlDscServer @properties -Force -ErrorAction 'Stop' + } + + <# + Base method Assert() call this method with the properties that was assigned + a value. + #> + hidden [void] AssertProperties([System.Collections.Hashtable] $properties) + { + # TODO: There might be a need to assert properties, if not this should be removed. + } +} +# This has intentionally been put last in the file: cSpell: ignore PBDMS AZUREEXTENSION From f077c473166e5fc875368ea551f59c2b598cfb64 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Sat, 15 Apr 2023 17:54:10 +0200 Subject: [PATCH 02/16] Fix comment-based help --- source/Classes/020.SqlInstall.ps1 | 182 +++++++++++++++--------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/source/Classes/020.SqlInstall.ps1 b/source/Classes/020.SqlInstall.ps1 index 819c35ef8..f9df21213 100644 --- a/source/Classes/020.SqlInstall.ps1 +++ b/source/Classes/020.SqlInstall.ps1 @@ -56,277 +56,277 @@ setup executable normally ask for. .PARAMETER SuppressPrivacyStatementNotice - See the notes section for more information. + See the description section for more information. .PARAMETER IAcknowledgeEntCalLimits - See the notes section for more information. + See the description section for more information. .PARAMETER Enu - See the notes section for more information. + See the description section for more information. .PARAMETER UpdateEnabled - See the notes section for more information. + See the description section for more information. .PARAMETER UpdateSource - See the notes section for more information. + See the description section for more information. .PARAMETER Features - See the notes section for more information. + See the description section for more information. .PARAMETER InstallSharedDir - See the notes section for more information. + See the description section for more information. .PARAMETER InstallSharedWowDir - See the notes section for more information. + See the description section for more information. .PARAMETER InstanceDir - See the notes section for more information. + See the description section for more information. .PARAMETER InstanceId - See the notes section for more information. + See the description section for more information. .PARAMETER PBEngSvcAccount - See the notes section for more information. + See the description section for more information. .PARAMETER PBEngSvcPassword - See the notes section for more information. + See the description section for more information. .PARAMETER PBEngSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER PBDMSSvcAccount - See the notes section for more information. + See the description section for more information. .PARAMETER PBDMSSvcPassword - See the notes section for more information. + See the description section for more information. .PARAMETER PBDMSSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER PBStartPortRange - See the notes section for more information. + See the description section for more information. .PARAMETER PBEndPortRange - See the notes section for more information. + See the description section for more information. .PARAMETER PBScaleOut - See the notes section for more information. + See the description section for more information. .PARAMETER ProductKey - See the notes section for more information. + See the description section for more information. .PARAMETER AgtSvcAccount - See the notes section for more information. + See the description section for more information. .PARAMETER AgtSvcPassword - See the notes section for more information. + See the description section for more information. .PARAMETER AgtSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER ASBackupDir - See the notes section for more information. + See the description section for more information. .PARAMETER ASCollation - See the notes section for more information. + See the description section for more information. .PARAMETER ASConfigDir - See the notes section for more information. + See the description section for more information. .PARAMETER ASDataDir - See the notes section for more information. + See the description section for more information. .PARAMETER ASLogDir - See the notes section for more information. + See the description section for more information. .PARAMETER ASTempDir - See the notes section for more information. + See the description section for more information. .PARAMETER ASServerMode - See the notes section for more information. + See the description section for more information. .PARAMETER ASSvcAccount - See the notes section for more information. + See the description section for more information. .PARAMETER ASSvcPassword - See the notes section for more information. + See the description section for more information. .PARAMETER ASSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER ASSysAdminAccounts - See the notes section for more information. + See the description section for more information. .PARAMETER ASProviderMSOLAP - See the notes section for more information. + See the description section for more information. .PARAMETER BrowserSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER FTUpgradeOption - See the notes section for more information. + See the description section for more information. .PARAMETER EnableRanU - See the notes section for more information. + See the description section for more information. .PARAMETER InstallSqlDataDir - See the notes section for more information. + See the description section for more information. .PARAMETER SqlBackupDir - See the notes section for more information. + See the description section for more information. .PARAMETER SecurityMode - See the notes section for more information. + See the description section for more information. .PARAMETER SAPwd - See the notes section for more information. + See the description section for more information. .PARAMETER SqlCollation - See the notes section for more information. + See the description section for more information. .PARAMETER SqlSvcAccount - See the notes section for more information. + See the description section for more information. .PARAMETER SqlSvcPassword - See the notes section for more information. + See the description section for more information. .PARAMETER SqlSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER SqlSysAdminAccounts - See the notes section for more information. + See the description section for more information. .PARAMETER SqlTempDbDir - See the notes section for more information. + See the description section for more information. .PARAMETER SqlTempDbLogDir - See the notes section for more information. + See the description section for more information. .PARAMETER SqlTempDbFileCount - See the notes section for more information. + See the description section for more information. .PARAMETER SqlTempDbFileSize - See the notes section for more information. + See the description section for more information. .PARAMETER SqlTempDbFileGrowth - See the notes section for more information. + See the description section for more information. .PARAMETER SqlTempDbLogFileSize - See the notes section for more information. + See the description section for more information. .PARAMETER SqlTempDbLogFileGrowth - See the notes section for more information. + See the description section for more information. .PARAMETER SqlUserDbDir - See the notes section for more information. + See the description section for more information. .PARAMETER SqlSvcInstantFileInit - See the notes section for more information. + See the description section for more information. .PARAMETER SqlUserDbLogDir - See the notes section for more information. + See the description section for more information. .PARAMETER SqlMaxDop - See the notes section for more information. + See the description section for more information. .PARAMETER UseSqlRecommendedMemoryLimits - See the notes section for more information. + See the description section for more information. .PARAMETER SqlMinMemory - See the notes section for more information. + See the description section for more information. .PARAMETER SqlMaxMemory - See the notes section for more information. + See the description section for more information. .PARAMETER FileStreamLevel - See the notes section for more information. + See the description section for more information. .PARAMETER FileStreamShareName - See the notes section for more information. + See the description section for more information. .PARAMETER ISSvcAccount - See the notes section for more information. + See the description section for more information. .PARAMETER ISSvcPassword - See the notes section for more information. + See the description section for more information. .PARAMETER ISSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER AllowUpgradeForSSRSSharePointMode - See the notes section for more information. + See the description section for more information. .PARAMETER NpEnabled - See the notes section for more information. + See the description section for more information. .PARAMETER TcpEnabled - See the notes section for more information. + See the description section for more information. .PARAMETER RsInstallMode - See the notes section for more information. + See the description section for more information. .PARAMETER RSSvcAccount - See the notes section for more information. + See the description section for more information. .PARAMETER RSSvcPassword - See the notes section for more information. + See the description section for more information. .PARAMETER RSSvcStartupType - See the notes section for more information. + See the description section for more information. .PARAMETER MPYCacheDirectory - See the notes section for more information. + See the description section for more information. .PARAMETER MRCacheDirectory - See the notes section for more information. + See the description section for more information. .PARAMETER SqlInstJava - See the notes section for more information. + See the description section for more information. .PARAMETER SqlJavaDir - See the notes section for more information. + See the description section for more information. .PARAMETER FailoverClusterGroup - See the notes section for more information. + See the description section for more information. .PARAMETER FailoverClusterDisks - See the notes section for more information. + See the description section for more information. .PARAMETER FailoverClusterNetworkName - See the notes section for more information. + See the description section for more information. .PARAMETER FailoverClusterIPAddresses - See the notes section for more information. + See the description section for more information. .PARAMETER FailoverClusterRollOwnership - See the notes section for more information. + See the description section for more information. .PARAMETER AzureSubscriptionId - See the notes section for more information. + See the description section for more information. .PARAMETER AzureResourceGroup - See the notes section for more information. + See the description section for more information. .PARAMETER AzureRegion - See the notes section for more information. + See the description section for more information. .PARAMETER AzureTenantId - See the notes section for more information. + See the description section for more information. .PARAMETER AzureServicePrincipal - See the notes section for more information. + See the description section for more information. .PARAMETER AzureServicePrincipalSecret - See the notes section for more information. + See the description section for more information. .PARAMETER AzureArcProxy - See the notes section for more information. + See the description section for more information. .PARAMETER SkipRules - See the notes section for more information. + See the description section for more information. .PARAMETER ProductCoveredBySA - See the notes section for more information. + See the description section for more information. .EXAMPLE TODO: Must update the example. From b782b28fcf5f7afa7ff7081b7c0d2f6448ed0b9b Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Sun, 16 Apr 2023 12:24:06 +0200 Subject: [PATCH 03/16] Fix wrong comments --- source/en-US/SqlAudit.strings.psd1 | 2 +- source/en-US/SqlPermission.strings.psd1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/en-US/SqlAudit.strings.psd1 b/source/en-US/SqlAudit.strings.psd1 index 8a818d13b..31c855095 100644 --- a/source/en-US/SqlAudit.strings.psd1 +++ b/source/en-US/SqlAudit.strings.psd1 @@ -8,7 +8,7 @@ ConvertFrom-StringData @' ## Strings overrides for the ResourceBase's default strings. # None - ## Strings directly used by the derived class SqlDatabasePermission. + ## Strings directly used by the derived class SqlAudit. BothFileSizePropertiesMustBeSet = Both the parameter MaximumFileSize and MaximumFileSizeUnit must be assigned. (SA0001) ReservDiskSpaceWithoutMaximumFiles = The parameter ReservDiskSpace can only be used together with the parameter MaximumFiles. (SA0002) PathInvalid = The path '{0}' does not exist. Audit file can only be created in a path that already exist and where the SQL Server instance has permission to write. (SA0003) diff --git a/source/en-US/SqlPermission.strings.psd1 b/source/en-US/SqlPermission.strings.psd1 index 6e4afa3be..7366eb3a0 100644 --- a/source/en-US/SqlPermission.strings.psd1 +++ b/source/en-US/SqlPermission.strings.psd1 @@ -8,7 +8,7 @@ ConvertFrom-StringData @' ## Strings overrides for the ResourceBase's default strings. # None - ## Strings directly used by the derived class SqlDatabasePermission. + ## Strings directly used by the derived class SqlPermission. EvaluateServerPermissionForPrincipal = Evaluate the current permissions for the principal '{0}' on the instance '{1}'. (SP0001) DesiredPermissionAreAbsent = The desired permission '{0}' that shall be present are absent. (SP0002) DesiredAbsentPermissionArePresent = The desired permission '{0}' that shall be absent are present. (SP0003) From 70c8ec089af2d4f92b9ce6268ffd48d0c6b879e1 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Wed, 19 Apr 2023 14:05:45 +0200 Subject: [PATCH 04/16] FIx bug in tests --- tests/Unit/SqlServerDsc.Common.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/SqlServerDsc.Common.Tests.ps1 b/tests/Unit/SqlServerDsc.Common.Tests.ps1 index 960bb8fee..fa8549e7f 100644 --- a/tests/Unit/SqlServerDsc.Common.Tests.ps1 +++ b/tests/Unit/SqlServerDsc.Common.Tests.ps1 @@ -103,7 +103,7 @@ Describe 'SqlServerDsc.Common\Get-RegistryPropertyValue' -Tag 'GetRegistryProper $result = Get-RegistryPropertyValue -Path $mockWrongRegistryPath -Name $mockPropertyName $result | Should -BeNullOrEmpty - Should -Invoke -CommandName Get-ItemProperty -Exactly -Times 1 -Scope It -Module $script:subModuleName + Should -Invoke -CommandName Get-ItemProperty -Exactly -Times 1 -Scope It } } From 517ac759dabb71f76f707f41b0548613d8c0d90a Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Wed, 19 Apr 2023 14:49:58 +0200 Subject: [PATCH 05/16] Add private command Get-RegistryPropertyValue --- CHANGELOG.md | 2 + .../SqlServerDsc.Common.psm1 | 4 + source/Private/Get-RegistryPropertyValue.ps1 | 45 ++++++++ .../Get-RegistryPropertyValue.Tests.ps1 | 105 ++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 source/Private/Get-RegistryPropertyValue.ps1 create mode 100644 tests/Unit/Private/Get-RegistryPropertyValue.Tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 08ffc5704..111df8039 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -199,6 +199,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 for a file. - `Assert-Feature` - Throws an exception if a feature is not supported for a specific Microsoft SQL Server major version. + - `Get-RegistryPropertyValue` - Returns the value of the provided property + at the provided registry path. - SqlServerDsc.Common - `Connect-SQL`. - Add new parameter `Encrypt`. diff --git a/source/Modules/SqlServerDsc.Common/SqlServerDsc.Common.psm1 b/source/Modules/SqlServerDsc.Common/SqlServerDsc.Common.psm1 index 5a18c3a89..a152fcd93 100644 --- a/source/Modules/SqlServerDsc.Common/SqlServerDsc.Common.psm1 +++ b/source/Modules/SqlServerDsc.Common/SqlServerDsc.Common.psm1 @@ -14,6 +14,10 @@ $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' .PARAMETER PropertyName Specifies the the name of the property to return the value for. + + .NOTES + This function should be removed when it is not longer used, and instead + the private function Get-RegistryPropertyValue shall be used. #> function Get-RegistryPropertyValue { diff --git a/source/Private/Get-RegistryPropertyValue.ps1 b/source/Private/Get-RegistryPropertyValue.ps1 new file mode 100644 index 000000000..94fbacc57 --- /dev/null +++ b/source/Private/Get-RegistryPropertyValue.ps1 @@ -0,0 +1,45 @@ +<# + .SYNOPSIS + Returns the value of the provided property at the provided registry + path. + + .DESCRIPTION + Returns the value of the provided property at the provided registry + path. + + .PARAMETER Path + Specifies the path in the registry to the property name. + + .PARAMETER PropertyName + Specifies the the name of the property to return the value for. + + .EXAMPLE + Get-RegistryPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSAS13.SQL2016\Setup' -Name 'Version' + + Returns the registry value for the property name 'Version' in the specified + registry path. +#> +function Get-RegistryPropertyValue +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Path, + + [Parameter(Mandatory = $true)] + [System.String] + $Name + ) + + $getItemPropertyParameters = @{ + Path = $Path + Name = $Name + } + + $getItemPropertyResult = (Get-ItemProperty @getItemPropertyParameters).$Name + + return $getItemPropertyResult +} diff --git a/tests/Unit/Private/Get-RegistryPropertyValue.Tests.ps1 b/tests/Unit/Private/Get-RegistryPropertyValue.Tests.ps1 new file mode 100644 index 000000000..4f12cda1a --- /dev/null +++ b/tests/Unit/Private/Get-RegistryPropertyValue.Tests.ps1 @@ -0,0 +1,105 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Get-RegistryPropertyValue' -Tag 'Private' { + Context 'When there are no property in the registry' { + BeforeAll { + Mock -CommandName Get-ItemProperty -MockWith { + return @{ + 'UnknownProperty' = 'AnyValue' + } + } + } + + It 'Should return $null' { + InModuleScope -ScriptBlock { + $result = Get-RegistryPropertyValue -Path 'HKLM:\SOFTWARE\MockAnyPath' -Name 'InstanceName' + $result | Should -BeNullOrEmpty + } + + Should -Invoke -CommandName Get-ItemProperty -Exactly -Times 1 -Scope It + } + } + + Context 'When the call to Get-ItemProperty with ErrorAction set to ''Stop''' { + It 'Should throw the correct error' { + InModuleScope -ScriptBlock { + { Get-RegistryPropertyValue -Path 'HKLM:\SOFTWARE\MockAnyPath' -Name 'InstanceName' -ErrorAction 'Stop' } | + Should -Throw -ExpectedMessage "Cannot find path 'HKLM:\SOFTWARE\MockAnyPath' because it does not exist." + } + } + } + + Context 'When the call to Get-ItemProperty with ErrorAction set to ''SilentlyContinue''' { + It 'Should not throw an exception and return $null' { + InModuleScope -ScriptBlock { + $result = Get-RegistryPropertyValue -Path 'HKLM:\SOFTWARE\MockAnyPath' -Name 'InstanceName' -ErrorAction 'SilentlyContinue' + $result | Should -BeNullOrEmpty + } + } + } + + Context 'When there are a property in the registry' { + BeforeAll { + Mock -CommandName Get-ItemProperty -MockWith { + return @{ + 'InstanceName' = 'AnyValue' + } + } + } + + It 'Should return the correct value' { + InModuleScope -ScriptBlock { + $result = Get-RegistryPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS' -Name 'InstanceName' + $result | Should -Be 'AnyValue' + } + + Should -Invoke -CommandName Get-ItemProperty -Exactly -Times 1 -Scope It + } + } +} From ab55d795c786f81654b2ea52d59df27eb0a4afb0 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Thu, 20 Apr 2023 12:26:31 +0200 Subject: [PATCH 06/16] Add private command ConvertFrom-ServiceStartMode --- CHANGELOG.md | 2 + .../DSC_SqlSetup/DSC_SqlSetup.psm1 | 4 + .../Private/ConvertFrom-ServiceStartMode.ps1 | 36 ++++++++ .../ConvertFrom-ServiceStartMode.Tests.ps1 | 82 +++++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 source/Private/ConvertFrom-ServiceStartMode.ps1 create mode 100644 tests/Unit/Private/ConvertFrom-ServiceStartMode.Tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 111df8039..eb38ddcce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -201,6 +201,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 for a specific Microsoft SQL Server major version. - `Get-RegistryPropertyValue` - Returns the value of the provided property at the provided registry path. + - `ConvertFrom-ServiceStartMode` - Converts the specified start mode to + the equivalent normalized startup type. - SqlServerDsc.Common - `Connect-SQL`. - Add new parameter `Encrypt`. diff --git a/source/DSCResources/DSC_SqlSetup/DSC_SqlSetup.psm1 b/source/DSCResources/DSC_SqlSetup/DSC_SqlSetup.psm1 index ccab76979..30b90b1a1 100644 --- a/source/DSCResources/DSC_SqlSetup/DSC_SqlSetup.psm1 +++ b/source/DSCResources/DSC_SqlSetup/DSC_SqlSetup.psm1 @@ -2506,6 +2506,10 @@ function Get-ServiceAccountParameters .PARAMETER StartMode The StartMode to convert. + + .NOTES + This function can be removed when it is no longer needed or replace by + private function ConvertFrom-ServiceStartupMode. #> function ConvertTo-StartupType { diff --git a/source/Private/ConvertFrom-ServiceStartMode.ps1 b/source/Private/ConvertFrom-ServiceStartMode.ps1 new file mode 100644 index 000000000..644d9d339 --- /dev/null +++ b/source/Private/ConvertFrom-ServiceStartMode.ps1 @@ -0,0 +1,36 @@ +<# + .SYNOPSIS + Converts the specified start mode to the equivalent normalized startup type. + + .DESCRIPTION + Converts the specified start mode of a Win32_Service CIM object or + a `[Microsoft.SqlServer.Management.Smo.Wmi.Service]` object to the + equivalent normalized startup type. + + .PARAMETER StartMode + Specifies the start mode to convert to normalized startup type. + + .EXAMPLE + ConvertFrom-ServiceStartMode -StartMode 'Auto' + + Returns the startup type 'Automatic'. +#> +function ConvertFrom-ServiceStartMode +{ + param + ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [System.String] + $StartMode + ) + + process + { + if ($StartMode -eq 'Auto') + { + $StartMode = 'Automatic' + } + + return $StartMode + } +} diff --git a/tests/Unit/Private/ConvertFrom-ServiceStartMode.Tests.ps1 b/tests/Unit/Private/ConvertFrom-ServiceStartMode.Tests.ps1 new file mode 100644 index 000000000..1b4276206 --- /dev/null +++ b/tests/Unit/Private/ConvertFrom-ServiceStartMode.Tests.ps1 @@ -0,0 +1,82 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'because ConvertTo-SecureString is used to simplify the tests.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + # Loading mocked classes + Add-Type -Path (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '../Stubs') -ChildPath 'SMO.cs') + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'ConvertFrom-ServiceStartMode' -Tag 'Private' { + Context 'When translating to service start mode' { + BeforeDiscovery { + $testCases = @( + @{ + MockStartMode = 'Auto' + MockExpectedServiceType = 'Automatic' + } + @{ + MockStartMode = 'Manual' + MockExpectedServiceType = 'Manual' + } + @{ + MockStartMode = 'Disabled' + MockExpectedServiceType = 'Disabled' + } + ) + } + + It 'Should properly map '''' to managed service type ''''' -ForEach $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $MockStartMode | + ConvertFrom-ServiceStartMode | + Should -Be $MockExpectedServiceType + } + } + } +} From 3b5716cd3c15e715f53cb42ca43f12f9137a7dd7 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Thu, 20 Apr 2023 12:27:03 +0200 Subject: [PATCH 07/16] Fix ignore spell of SSMS --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index a4f6fdefe..4d12744ef 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -72,7 +72,8 @@ "creplace", "dbatools", "db_datareader", - "fastbuild" + "fastbuild", + "SSMS" ], "cSpell.ignorePaths": [ ".git" From c80a50e597749a2480e5d8d0db3413b9d3ddad9e Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Thu, 20 Apr 2023 12:34:59 +0200 Subject: [PATCH 08/16] Add private command Get-InstanceId --- CHANGELOG.md | 2 + source/Private/Get-InstanceId.ps1 | 70 +++++++++++++++++ tests/Unit/Private/Get-InstanceId.Tests.ps1 | 85 +++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 source/Private/Get-InstanceId.ps1 create mode 100644 tests/Unit/Private/Get-InstanceId.Tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index eb38ddcce..9dd78d7c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -203,6 +203,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 at the provided registry path. - `ConvertFrom-ServiceStartMode` - Converts the specified start mode to the equivalent normalized startup type. + - `Get-InstanceId` - Returns the SQL Server instance id of the specified + service type and instance name. - SqlServerDsc.Common - `Connect-SQL`. - Add new parameter `Encrypt`. diff --git a/source/Private/Get-InstanceId.ps1 b/source/Private/Get-InstanceId.ps1 new file mode 100644 index 000000000..3245bab04 --- /dev/null +++ b/source/Private/Get-InstanceId.ps1 @@ -0,0 +1,70 @@ +<# + .SYNOPSIS + Returns the SQL Server instance id of the specified service type and instance + name. + + .DESCRIPTION + Returns the SQL Server instance id of the specified service type and instance + name. + + .PARAMETER ServiceType + Specifies one supported normalized service type for which to return the + instance id. + + .PARAMETER InstanceName + Specifies the instance name for which to return the instance id. + + .EXAMPLE + Get-InstanceId -ServiceType 'DatabaseEngine' -InstanceName 'SQL2022' + + Returns the registry value for the property name 'Version' in the specified + registry path. +#> +function Get-InstanceId +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [ValidateSet( + 'DatabaseEngine', + 'AnalysisServices', + 'ReportingServices' + )] + [System.String] + $ServiceType, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName + ) + + switch ($ServiceType) + { + 'DatabaseEngine' + { + $registryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' + + break + } + + 'AnalysisServices' + { + $registryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\OLAP' + + break + } + + 'ReportingServices' + { + $registryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS' + + break + } + } + + $instanceId = Get-RegistryPropertyValue -Path $registryPath -Name $InstanceName + + return $instanceId +} diff --git a/tests/Unit/Private/Get-InstanceId.Tests.ps1 b/tests/Unit/Private/Get-InstanceId.Tests.ps1 new file mode 100644 index 000000000..7a2cf7b6f --- /dev/null +++ b/tests/Unit/Private/Get-InstanceId.Tests.ps1 @@ -0,0 +1,85 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'because ConvertTo-SecureString is used to simplify the tests.')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'SqlServerDsc' + + $env:SqlServerDscCI = $true + + Import-Module -Name $script:dscModuleName + + # Loading mocked classes + Add-Type -Path (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '../Stubs') -ChildPath 'SMO.cs') + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + Remove-Item -Path 'env:SqlServerDscCI' +} + +Describe 'Get-InstanceId' -Tag 'Private' { + Context 'When getting instance id' { + BeforeDiscovery { + $testCases = @( + @{ + MockComponent = 'DatabaseEngine' + } + @{ + MockComponent = 'AnalysisServices' + } + @{ + MockComponent = 'ReportingServices' + } + ) + } + + BeforeAll { + Mock -CommandName Get-RegistryPropertyValue -MockWith { + return 'MockInstanceId' + } + } + + It 'Should return the correct value for component ''''' -ForEach $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $MockComponent | + Get-InstanceId -InstanceName 'SQL2022' | + Should -Be 'MockInstanceId' + } + } + } +} From de4289e7aec9d1778a91cc3b45dc73de97c51402 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Thu, 27 Apr 2023 18:09:17 +0200 Subject: [PATCH 09/16] Changes to SqlInstall --- source/Classes/020.SqlInstall.ps1 | 24 ++++++++++++++++++++---- source/en-US/SqlInstall.strings.psd1 | 14 ++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 source/en-US/SqlInstall.strings.psd1 diff --git a/source/Classes/020.SqlInstall.ps1 b/source/Classes/020.SqlInstall.ps1 index f9df21213..299c75829 100644 --- a/source/Classes/020.SqlInstall.ps1 +++ b/source/Classes/020.SqlInstall.ps1 @@ -740,11 +740,8 @@ class SqlInstall : SqlSetupBase { # These properties will not be enforced. $this.ExcludeDscProperties = @( - 'ServerName' - 'InstanceName' - 'Name' + 'ServerName' # TODO: This should exclude all properties other than Features 'Credential' - 'Force' ) } @@ -794,6 +791,17 @@ class SqlInstall : SqlSetupBase ) } + $setupExecutablePath = Join-Path -Path $this.MediaPath -ChildPath 'setup.exe' + + $setupExecutableVersionInformation = Get-FileVersionInformation -FilePath $setupExecutablePath + + Write-Verbose -Message ( + $script:localizedData.SetupExecutablePath -f @( + $setupExecutablePath, + $setupExecutableVersionInformation.ProductVersion + ) + ) + <# Only set key property Name if the audit exist. Base class will set it and handle Ensure. @@ -804,6 +812,14 @@ class SqlInstall : SqlSetupBase ServerName = $this.ServerName } + <# + TODO: + + Should call a Get-SqlDscInstalledComponents (optional parameter is InstanceName). + Result is InstanceName, list of features, and for each Feature all needed properties. + #> + $currentInstalledServiceNames = (Get-SqlDscManagedComputerService).Name + $serverObject = $this.GetServerObject() # TODO: Should call commands that can return the installed state. diff --git a/source/en-US/SqlInstall.strings.psd1 b/source/en-US/SqlInstall.strings.psd1 new file mode 100644 index 000000000..218410ab0 --- /dev/null +++ b/source/en-US/SqlInstall.strings.psd1 @@ -0,0 +1,14 @@ +<# + .SYNOPSIS + The localized resource strings in English (en-US) for the + resource SqlPermission. +#> + +ConvertFrom-StringData @' + ## Strings overrides for the ResourceBase's default strings. + # None + + ## Strings directly used by the derived class SqlInstall. + EvaluateInstanceFeatures = Evaluate the installed features on the instance '{0}'. (SI0001) + SetupExecutablePath = The path to the Microsoft SQL Server setup executable '{0}' with product version {1}. +'@ From 5302146380ffabcc9c470db2caaf03e0c591338f Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Thu, 27 Apr 2023 18:09:59 +0200 Subject: [PATCH 10/16] Add public command Test-IsDataQualityClientInstalled --- .../Test-IsDataQualityClientInstalled.ps1 | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 source/Public/Test-IsDataQualityClientInstalled.ps1 diff --git a/source/Public/Test-IsDataQualityClientInstalled.ps1 b/source/Public/Test-IsDataQualityClientInstalled.ps1 new file mode 100644 index 000000000..6b930a5fb --- /dev/null +++ b/source/Public/Test-IsDataQualityClientInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the Data Quality Client is installed. + + .DESCRIPTION + Returns whether the Data Quality Client is installed. + + .PARAMETER Version + Specifies the version for which to return installed components. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-IsDataQualityClientInstalled -Version ([System.Version] '16.0') + + Returns $true Data Quality Client is installed. +#> +function Test-IsDataQualityClientInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.Version] + $Version + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $Version.Major + Name = 'SQL_DQ_CLIENT_Full' + ErrorAction = 'SilentlyContinue' + } + + $isDQCInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isDQCInstalled -eq 1) + { + $result = $true + } + + return $result +} From f4100f10e5d31d2fd8de2ea5980bc995bd596258 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Thu, 27 Apr 2023 18:10:12 +0200 Subject: [PATCH 11/16] First iteration of Get-SqlDscInstalledComponent --- .../Public/Get-SqlDscInstalledComponent.ps1 | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 source/Public/Get-SqlDscInstalledComponent.ps1 diff --git a/source/Public/Get-SqlDscInstalledComponent.ps1 b/source/Public/Get-SqlDscInstalledComponent.ps1 new file mode 100644 index 000000000..dae80dda7 --- /dev/null +++ b/source/Public/Get-SqlDscInstalledComponent.ps1 @@ -0,0 +1,235 @@ +<# + .SYNOPSIS + Returns installed Microsoft SQL Server component. + + .DESCRIPTION + Returns installed Microsoft SQL Server component. + + .PARAMETER ServerName + Specifies the server name to return the components from. + + .PARAMETER InstanceName + Specifies the instance name for which to return installed components. + + .PARAMETER Version + Specifies the version for which to return installed components. If the + parameter InstanceName is not provided then all instances with the version + will be returned. + + .EXAMPLE + Get-SqlDscInstalledComponents + + Returns all the installed components. + + .OUTPUTS + `[System.Management.Automation.PSCustomObject]` +#> +function Get-SqlDscInstalledComponent +{ + [OutputType([System.Management.Automation.PSCustomObject])] + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = (Get-ComputerName), + + [Parameter()] + [System.String] + $InstanceName, + + [Parameter()] + [System.Version] + $Version + ) + + Assert-ElevatedUser -ErrorAction 'Stop' + + $installedComponents = @() + + $currentInstalledServices = Get-SqlDscManagedComputerService -ServerName $ServerName -ErrorAction 'Stop' + + foreach ($installedService in $currentInstalledServices) + { + $serviceType = $installedService.Type | ConvertFrom-ManagedServiceType -ErrorAction 'SilentlyContinue' + + if (-not $serviceType) + { + <# + This is a workaround because [Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType] + does not support all service types yet. + #> + $serviceType = $installedService.Type + } + + $fileProductVersion = $null + + $serviceExecutablePath = (($installedService.PathName -replace '"') -split ' -')[0] + + if ((Test-Path -Path $serviceExecutablePath)) + { + $fileProductVersion = [System.Version] (Get-FileVersionInformation -FilePath $serviceExecutablePath).ProductVersion + } + + # Get InstanceName from the service name if it exist. + $serviceInstanceName = if ($installedService.Name -match '\$(.*)$') + { + $Matches[1] + } + + $serviceStartMode = $installedService.StartMode | ConvertFrom-ServiceStartMode + + <# + There are more properties that can be fetch from advanced properties, + for example InstanceId, Clustered, and Version (for some), but it takes + about 6 seconds for it to return a value. Because of the slowness this + command does not use advanced properties, e.g: + ($installedService.AdvancedProperties | ? Name -eq 'InstanceId').Value + #> + $serviceComponent = [PSCustomObject] @{ + ServiceName = $installedService.Name + ServiceType = $serviceType + ServiceDisplayName = $installedService.DisplayName + ServiceAccountName = $installedService.ServiceAccount + ServiceStartMode = $serviceStartMode + InstanceName = $serviceInstanceName + ServiceExecutableVersion = $fileProductVersion + + # Properties that should be on all objects, but set later + InstanceId = $null + Feature = @() + } + + $installedComponents += $serviceComponent + } + + # Loop to set InstanceId. + foreach ($component in $installedComponents.Where({ $_.ServiceType -in ('DatabaseEngine', 'AnalysisServices', 'ReportingServices') })) + { + $component.InstanceId = $component.ServiceType | Get-InstanceId -InstanceName $component.InstanceName + } + + # Loop to get features. + foreach ($component in $installedComponents) + { + switch ($component.ServiceType) + { + 'DatabaseEngine' + { + $component.Feature += 'SQLEngine' + + #$isReplicationInstalled = Test-IsReplicationFeatureInstalled -InstanceName $InstanceName + + if ($isReplicationInstalled) + { + $component.Feature += 'Replication' + } + + #$isDQInstalled = Test-IsDQComponentInstalled -InstanceName $InstanceName -SqlServerMajorVersion $sqlVersion + + if ($isDQInstalled) + { + $component.Feature += 'DQ' + } + + #TODO: This has nothing to do with DatabaseEngine. + $isDQInstalled = Test-IsDataQualityClientInstalled -Version $component.Version + + if ($isDQInstalled) + { + $component.Feature += 'DQC' + } + + #$isSsmsInstalled = Test-IsSsmsInstalled -SqlServerMajorVersion $sqlVersion + + if ($isSsmsInstalled) + { + $component.Feature += 'SSMS' + } + + #$isSsmsAdvancedInstalled = Test-IsSsmsAdvancedInstalled -SqlServerMajorVersion $sqlVersion + + if ($isSsmsAdvancedInstalled) + { + $component.Feature += 'ADV_SSMS' + } + + break + } + + '9' + { + $component.Feature += 'FullText' + + break + } + + '12' + { + $component.Feature += 'AdvancedAnalytics' + + break + } + + 'AnalysisServices' + { + $component.Feature += 'AS' + + break + } + + 'IntegrationServices' + { + $component.Feature += 'IS' + + break + } + + 'ReportingServices' + { + $component.Feature += 'RS' + + break + } + } + } + + + # Filter result + + $componentsToReturn = @() + + if ($PSBoundParameters.ContainsKey('Version')) + { + if ($PSBoundParameters.ContainsKey('InstanceName')) + { + $componentsToReturn += $installedComponents | + Where-Object -FilterScript { + -not $_.InstanceName -and $_.FileProductVersion.Major -eq $Version.Major + } + } + else + { + $componentsToReturn += $installedComponents | + Where-Object -FilterScript { + $_.FileProductVersion.Major -eq $Version.Major + } + } + } + + if ($PSBoundParameters.ContainsKey('InstanceName')) + { + $componentsToReturn += $installedComponents | + Where-Object -FilterScript { + $_.InstanceName -eq $InstanceName + } + } + + if (-not $componentsToReturn) + { + $componentsToReturn = $installedComponents + } + + return $componentsToReturn +} From e26f69c5e041eec6db7cb11501d00014e94b6e7a Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Thu, 27 Apr 2023 19:53:05 +0200 Subject: [PATCH 12/16] Update Get-SqlDscInstalledComponent --- .../Public/Get-SqlDscInstalledComponent.ps1 | 139 +++++++++++------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/source/Public/Get-SqlDscInstalledComponent.ps1 b/source/Public/Get-SqlDscInstalledComponent.ps1 index dae80dda7..560102e2c 100644 --- a/source/Public/Get-SqlDscInstalledComponent.ps1 +++ b/source/Public/Get-SqlDscInstalledComponent.ps1 @@ -46,7 +46,7 @@ function Get-SqlDscInstalledComponent Assert-ElevatedUser -ErrorAction 'Stop' - $installedComponents = @() + $serviceComponent = @() $currentInstalledServices = Get-SqlDscManagedComputerService -ServerName $ServerName -ErrorAction 'Stop' @@ -87,7 +87,7 @@ function Get-SqlDscInstalledComponent command does not use advanced properties, e.g: ($installedService.AdvancedProperties | ? Name -eq 'InstanceId').Value #> - $serviceComponent = [PSCustomObject] @{ + $serviceComponent += [PSCustomObject] @{ ServiceName = $installedService.Name ServiceType = $serviceType ServiceDisplayName = $installedService.DisplayName @@ -100,99 +100,132 @@ function Get-SqlDscInstalledComponent InstanceId = $null Feature = @() } - - $installedComponents += $serviceComponent } - # Loop to set InstanceId. - foreach ($component in $installedComponents.Where({ $_.ServiceType -in ('DatabaseEngine', 'AnalysisServices', 'ReportingServices') })) + # Get InstanceId for all installed services. + foreach ($component in $serviceComponent.Where({ $_.ServiceType -in ('DatabaseEngine', 'AnalysisServices', 'ReportingServices') })) { $component.InstanceId = $component.ServiceType | Get-InstanceId -InstanceName $component.InstanceName } - # Loop to get features. - foreach ($component in $installedComponents) + $installedComponents = @() + + # Evaluate features based on installed services. + foreach ($currentServiceComponent in $serviceComponent) { - switch ($component.ServiceType) + $installedComponent = [PSCustomObject] @{ + Feature = $null + } + + switch ($currentServiceComponent.ServiceType) { 'DatabaseEngine' { - $component.Feature += 'SQLEngine' - - #$isReplicationInstalled = Test-IsReplicationFeatureInstalled -InstanceName $InstanceName - - if ($isReplicationInstalled) - { - $component.Feature += 'Replication' - } - - #$isDQInstalled = Test-IsDQComponentInstalled -InstanceName $InstanceName -SqlServerMajorVersion $sqlVersion - - if ($isDQInstalled) - { - $component.Feature += 'DQ' - } - - #TODO: This has nothing to do with DatabaseEngine. - $isDQInstalled = Test-IsDataQualityClientInstalled -Version $component.Version - - if ($isDQInstalled) - { - $component.Feature += 'DQC' - } - - #$isSsmsInstalled = Test-IsSsmsInstalled -SqlServerMajorVersion $sqlVersion - - if ($isSsmsInstalled) - { - $component.Feature += 'SSMS' - } - - #$isSsmsAdvancedInstalled = Test-IsSsmsAdvancedInstalled -SqlServerMajorVersion $sqlVersion - - if ($isSsmsAdvancedInstalled) - { - $component.Feature += 'ADV_SSMS' - } + $installedComponent.Feature = 'SQLEngine' break } '9' { - $component.Feature += 'FullText' + $installedComponent.Feature += 'FullText' break } '12' { - $component.Feature += 'AdvancedAnalytics' + $installedComponent.Feature += 'AdvancedAnalytics' break } 'AnalysisServices' { - $component.Feature += 'AS' + $installedComponent.Feature += 'AS' break } 'IntegrationServices' { - $component.Feature += 'IS' + $installedComponent.Feature += 'IS' break } 'ReportingServices' { - $component.Feature += 'RS' + $installedComponent.Feature += 'RS' + + break + } + + Default + { + # Skip services like SQL Browser and SQL Agent. break } } + + # Skip service if it wasn't detected as a feature. + if ($installedComponent.Feature) + { + $installedComponent | + Add-Member -MemberType 'NoteProperty' -Name 'InstanceName' -Value $currentServiceComponent.InstanceName -PassThru | + Add-Member -MemberType 'NoteProperty' -Name 'InstanceId' -Value $currentServiceComponent.InstanceId -PassThru | + Add-Member -MemberType 'NoteProperty' -Name 'Version' -Value $currentServiceComponent.ServiceExecutableVersion -PassThru | + Add-Member -MemberType 'NoteProperty' -Name 'ServiceProperties' -Value $currentServiceComponent + + $installedComponents += $installedComponent + } + } + + #$isReplicationInstalled = Test-IsReplicationFeatureInstalled -InstanceName $InstanceName + + if ($isReplicationInstalled) + { + $component.Feature = 'Replication' + } + + #$isDQInstalled = Test-IsDQComponentInstalled -InstanceName $InstanceName -SqlServerMajorVersion $sqlVersion + + if ($isDQInstalled) + { + $component.Feature = 'DQ' + } + + # Fetch registry keys that is three digits, like 100, 110, .., 160, and so on. + $installedDatabaseLevel = (Split-Path -Leaf -Path (Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\').Name) -match '^\d\d\d$' + + foreach ($databaseLevel in $installedDatabaseLevel) + { + $databaseLevelVersion = [System.Version] ('{0}.{1}' -f $databaseLevel.Substring(0,2), $databaseLevel.Substring(2,1)) + + $isDQInstalled = Test-IsDataQualityClientInstalled -Version $databaseLevelVersion + + if ($isDQInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'DQC' + Version = $databaseLevelVersion + } + } + } + + #$isSsmsInstalled = Test-IsSsmsInstalled -SqlServerMajorVersion $sqlVersion + + if ($isSsmsInstalled) + { + $component.Feature = 'SSMS' + } + + #$isSsmsAdvancedInstalled = Test-IsSsmsAdvancedInstalled -SqlServerMajorVersion $sqlVersion + + if ($isSsmsAdvancedInstalled) + { + $component.Feature = 'ADV_SSMS' } @@ -206,14 +239,14 @@ function Get-SqlDscInstalledComponent { $componentsToReturn += $installedComponents | Where-Object -FilterScript { - -not $_.InstanceName -and $_.FileProductVersion.Major -eq $Version.Major + -not $_.InstanceName -and $_.Version.Major -eq $Version.Major } } else { $componentsToReturn += $installedComponents | Where-Object -FilterScript { - $_.FileProductVersion.Major -eq $Version.Major + $_.Version.Major -eq $Version.Major } } } From ec524027a3ddfcb08f37072db25963f9ff384517 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Fri, 28 Apr 2023 20:26:16 +0200 Subject: [PATCH 13/16] Fix more commands to test current state --- .../Public/Get-SqlDscInstalledComponent.ps1 | 205 +++++++++++------- source/Public/Get-SqlDscInstalledService.ps1 | 94 ++++++++ .../Test-IsAdvancedAnalyticsInstalled.ps1 | 48 ++++ ...ckwardCompatibilityComponentsInstalled.ps1 | 48 ++++ source/Public/Test-IsBooksOnlineInstalled.ps1 | 48 ++++ ...Test-IsConnectivityComponentsInstalled.ps1 | 48 ++++ .../Test-IsDataQualityClientInstalled.ps1 | 4 +- .../Test-IsMasterDataServicesInstalled.ps1 | 48 ++++ source/Public/Test-IsReplicationInstalled.ps1 | 48 ++++ ...Test-IsSoftwareDevelopmentKitInstalled.ps1 | 48 ++++ 10 files changed, 553 insertions(+), 86 deletions(-) create mode 100644 source/Public/Get-SqlDscInstalledService.ps1 create mode 100644 source/Public/Test-IsAdvancedAnalyticsInstalled.ps1 create mode 100644 source/Public/Test-IsBackwardCompatibilityComponentsInstalled.ps1 create mode 100644 source/Public/Test-IsBooksOnlineInstalled.ps1 create mode 100644 source/Public/Test-IsConnectivityComponentsInstalled.ps1 create mode 100644 source/Public/Test-IsMasterDataServicesInstalled.ps1 create mode 100644 source/Public/Test-IsReplicationInstalled.ps1 create mode 100644 source/Public/Test-IsSoftwareDevelopmentKitInstalled.ps1 diff --git a/source/Public/Get-SqlDscInstalledComponent.ps1 b/source/Public/Get-SqlDscInstalledComponent.ps1 index 560102e2c..bbbd782df 100644 --- a/source/Public/Get-SqlDscInstalledComponent.ps1 +++ b/source/Public/Get-SqlDscInstalledComponent.ps1 @@ -46,67 +46,7 @@ function Get-SqlDscInstalledComponent Assert-ElevatedUser -ErrorAction 'Stop' - $serviceComponent = @() - - $currentInstalledServices = Get-SqlDscManagedComputerService -ServerName $ServerName -ErrorAction 'Stop' - - foreach ($installedService in $currentInstalledServices) - { - $serviceType = $installedService.Type | ConvertFrom-ManagedServiceType -ErrorAction 'SilentlyContinue' - - if (-not $serviceType) - { - <# - This is a workaround because [Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType] - does not support all service types yet. - #> - $serviceType = $installedService.Type - } - - $fileProductVersion = $null - - $serviceExecutablePath = (($installedService.PathName -replace '"') -split ' -')[0] - - if ((Test-Path -Path $serviceExecutablePath)) - { - $fileProductVersion = [System.Version] (Get-FileVersionInformation -FilePath $serviceExecutablePath).ProductVersion - } - - # Get InstanceName from the service name if it exist. - $serviceInstanceName = if ($installedService.Name -match '\$(.*)$') - { - $Matches[1] - } - - $serviceStartMode = $installedService.StartMode | ConvertFrom-ServiceStartMode - - <# - There are more properties that can be fetch from advanced properties, - for example InstanceId, Clustered, and Version (for some), but it takes - about 6 seconds for it to return a value. Because of the slowness this - command does not use advanced properties, e.g: - ($installedService.AdvancedProperties | ? Name -eq 'InstanceId').Value - #> - $serviceComponent += [PSCustomObject] @{ - ServiceName = $installedService.Name - ServiceType = $serviceType - ServiceDisplayName = $installedService.DisplayName - ServiceAccountName = $installedService.ServiceAccount - ServiceStartMode = $serviceStartMode - InstanceName = $serviceInstanceName - ServiceExecutableVersion = $fileProductVersion - - # Properties that should be on all objects, but set later - InstanceId = $null - Feature = @() - } - } - - # Get InstanceId for all installed services. - foreach ($component in $serviceComponent.Where({ $_.ServiceType -in ('DatabaseEngine', 'AnalysisServices', 'ReportingServices') })) - { - $component.InstanceId = $component.ServiceType | Get-InstanceId -InstanceName $component.InstanceName - } + $serviceComponent = Get-SqlDscInstalledService -ServerName $ServerName $installedComponents = @() @@ -174,28 +114,23 @@ function Get-SqlDscInstalledComponent { $installedComponent | Add-Member -MemberType 'NoteProperty' -Name 'InstanceName' -Value $currentServiceComponent.InstanceName -PassThru | - Add-Member -MemberType 'NoteProperty' -Name 'InstanceId' -Value $currentServiceComponent.InstanceId -PassThru | Add-Member -MemberType 'NoteProperty' -Name 'Version' -Value $currentServiceComponent.ServiceExecutableVersion -PassThru | Add-Member -MemberType 'NoteProperty' -Name 'ServiceProperties' -Value $currentServiceComponent + # Get InstanceId for all installed services. + if ($currentServiceComponent.ServiceType -in ('DatabaseEngine', 'AnalysisServices', 'ReportingServices')) + { + $installedComponent | + Add-Member -MemberType 'NoteProperty' -Name 'InstanceId' -Value ( + $currentServiceComponent.ServiceType | + Get-InstanceId -InstanceName $currentServiceComponent.InstanceName + ) + } + $installedComponents += $installedComponent } } - #$isReplicationInstalled = Test-IsReplicationFeatureInstalled -InstanceName $InstanceName - - if ($isReplicationInstalled) - { - $component.Feature = 'Replication' - } - - #$isDQInstalled = Test-IsDQComponentInstalled -InstanceName $InstanceName -SqlServerMajorVersion $sqlVersion - - if ($isDQInstalled) - { - $component.Feature = 'DQ' - } - # Fetch registry keys that is three digits, like 100, 110, .., 160, and so on. $installedDatabaseLevel = (Split-Path -Leaf -Path (Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\').Name) -match '^\d\d\d$' @@ -203,6 +138,7 @@ function Get-SqlDscInstalledComponent { $databaseLevelVersion = [System.Version] ('{0}.{1}' -f $databaseLevel.Substring(0,2), $databaseLevel.Substring(2,1)) + # Look for installed version of Data Quality Client. $isDQInstalled = Test-IsDataQualityClientInstalled -Version $databaseLevelVersion if ($isDQInstalled) @@ -212,22 +148,123 @@ function Get-SqlDscInstalledComponent Version = $databaseLevelVersion } } - } - #$isSsmsInstalled = Test-IsSsmsInstalled -SqlServerMajorVersion $sqlVersion + # Look for installed version of SQL Server Books Online. + $isBOLInstalled = Test-IsBooksOnlineInstalled -Version $databaseLevelVersion - if ($isSsmsInstalled) - { - $component.Feature = 'SSMS' + if ($isBOLInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'BOL' + Version = $databaseLevelVersion + } + } + + # Look for installed version of Connectivity Components. + $isConnInstalled = Test-IsConnectivityComponentsInstalled -Version $databaseLevelVersion + + if ($isConnInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'CONN' + Version = $databaseLevelVersion + } + } + + # Look for installed version of Backward Compatibility Components. + $isBCInstalled = Test-IsBackwardCompatibilityComponentsInstalled -Version $databaseLevelVersion + + if ($isBCInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'BC' + Version = $databaseLevelVersion + } + } + + # Look for installed version of Software Development Kit. + $isSDKInstalled = Test-IsSoftwareDevelopmentKitInstalled -Version $databaseLevelVersion + + if ($isSDKInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'SDK' + Version = $databaseLevelVersion + } + } + + # Look for installed version of Master Data Services. + $isMDSInstalled = Test-IsMasterDataServicesInstalled -Version $databaseLevelVersion + + if ($isMDSInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'MDS' + Version = $databaseLevelVersion + } + } } - #$isSsmsAdvancedInstalled = Test-IsSsmsAdvancedInstalled -SqlServerMajorVersion $sqlVersion + $databaseEngineInstance = $installedComponents | + Where-Object -FilterScript { + $_.InstanceId -match '^MSSQL' + } - if ($isSsmsAdvancedInstalled) + foreach ($currentInstance in $databaseEngineInstance) { - $component.Feature = 'ADV_SSMS' + # Looking for installed version for Replication. + $isReplicationInstalled = Test-IsReplicationInstalled -InstanceId $currentInstance.InstanceId + + if ($isReplicationInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'Replication' + Version = $currentInstance.Version + InstanceName = $currentInstance.InstanceName + InstanceId = $currentInstance.InstanceId + } + } + + # Looking for installed version for Replication. + $isReplicationInstalled = Test-IsAdvancedAnalyticsInstalled -InstanceId $currentInstance.InstanceId + + if ($isReplicationInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'AdvancedAnalytics' + Version = $currentInstance.Version + InstanceName = $currentInstance.InstanceName + InstanceId = $currentInstance.InstanceId + } + } } + # SQL_DQ_Full = DQ : Data Quality Services + # sql_inst_mr = SQL_INST_MR : R Open and proprietary R packages + # sql_inst_mpy = SQL_INST_MPY : Anaconda and proprietary Python packages. + # SQL_Polybase_Core_Inst = PolyBaseCore : PolyBase technology + + #$isDQInstalled = Test-IsDQComponentInstalled -InstanceName $InstanceName -SqlServerMajorVersion $sqlVersion + + # if ($isDQInstalled) + # { + # $component.Feature = 'DQ' + # } + + # #$isSsmsInstalled = Test-IsSsmsInstalled -SqlServerMajorVersion $sqlVersion + + # if ($isSsmsInstalled) + # { + # $component.Feature = 'SSMS' + # } + + # #$isSsmsAdvancedInstalled = Test-IsSsmsAdvancedInstalled -SqlServerMajorVersion $sqlVersion + + # if ($isSsmsAdvancedInstalled) + # { + # $component.Feature = 'ADV_SSMS' + # } + # Filter result diff --git a/source/Public/Get-SqlDscInstalledService.ps1 b/source/Public/Get-SqlDscInstalledService.ps1 new file mode 100644 index 000000000..56850cc19 --- /dev/null +++ b/source/Public/Get-SqlDscInstalledService.ps1 @@ -0,0 +1,94 @@ +<# + .SYNOPSIS + Returns an installed Microsoft SQL Server component that runs as a service. + + .DESCRIPTION + Returns an installed Microsoft SQL Server component that runs as a service. + + .PARAMETER ServerName + Specifies the server name to return the components from. + + .EXAMPLE + Get-SqlDscInstalledComponents + + Returns all the installed services. + + .OUTPUTS + `[System.Management.Automation.PSCustomObject]` +#> +function Get-SqlDscInstalledService +{ + [OutputType([System.Management.Automation.PSCustomObject])] + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = (Get-ComputerName), + + [Parameter()] + [System.String] + $InstanceName, + + [Parameter()] + [System.Version] + $Version + ) + + Assert-ElevatedUser -ErrorAction 'Stop' + + $serviceComponent = @() + + $currentInstalledServices = Get-SqlDscManagedComputerService -ServerName $ServerName -ErrorAction 'Stop' + + foreach ($installedService in $currentInstalledServices) + { + $serviceType = $installedService.Type | ConvertFrom-ManagedServiceType -ErrorAction 'SilentlyContinue' + + if (-not $serviceType) + { + <# + This is a workaround because [Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType] + does not support all service types yet. + #> + $serviceType = $installedService.Type + } + + $fileProductVersion = $null + + $serviceExecutablePath = (($installedService.PathName -replace '"') -split ' -')[0] + + if ((Test-Path -Path $serviceExecutablePath)) + { + $fileProductVersion = [System.Version] (Get-FileVersionInformation -FilePath $serviceExecutablePath).ProductVersion + } + + # Get InstanceName from the service name if it exist. + $serviceInstanceName = if ($installedService.Name -match '\$(.*)$') + { + $Matches[1] + } + + $serviceStartMode = $installedService.StartMode | ConvertFrom-ServiceStartMode + + <# + There are more properties that can be fetch from advanced properties, + for example InstanceId, Clustered, and Version (for some), but it takes + about 6 seconds for it to return a value. Because of the slowness this + command does not use advanced properties, e.g: + ($installedService.AdvancedProperties | ? Name -eq 'InstanceId').Value + #> + $serviceComponent += [PSCustomObject] @{ + ServiceName = $installedService.Name + ServiceType = $serviceType + ServiceDisplayName = $installedService.DisplayName + ServiceAccountName = $installedService.ServiceAccount + ServiceStartMode = $serviceStartMode + InstanceName = $serviceInstanceName + ServiceExecutableVersion = $fileProductVersion + } + } + + return $serviceComponent +} diff --git a/source/Public/Test-IsAdvancedAnalyticsInstalled.ps1 b/source/Public/Test-IsAdvancedAnalyticsInstalled.ps1 new file mode 100644 index 000000000..a0943afb9 --- /dev/null +++ b/source/Public/Test-IsAdvancedAnalyticsInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the component Advanced Analytics is installed. + + .DESCRIPTION + Returns whether the component Advanced Analytics is installed. + + .PARAMETER InstanceId + Specifies the instance id on which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-IsReplicationInstalled -InstanceId 'MSSQL16.SQL2022' + + Returns $true if Advanced Analytics is installed. +#> +function Test-IsAdvancedAnalyticsInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.String] + $InstanceId + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $InstanceId + Name = 'AdvancedAnalytics' + ErrorAction = 'SilentlyContinue' + } + + $isAdvancedAnalyticsInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isAdvancedAnalyticsInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-IsBackwardCompatibilityComponentsInstalled.ps1 b/source/Public/Test-IsBackwardCompatibilityComponentsInstalled.ps1 new file mode 100644 index 000000000..9478447c5 --- /dev/null +++ b/source/Public/Test-IsBackwardCompatibilityComponentsInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the Backward Compatibility Components are installed. + + .DESCRIPTION + Returns whether the Backward Compatibility Components are installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-IsBackwardCompatibilityComponentsInstalled -Version ([System.Version] '16.0') + + Returns $true if Backward Compatibility Components are installed. +#> +function Test-IsBackwardCompatibilityComponentsInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.Version] + $Version + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $Version.Major + Name = 'Tools_Legacy_Full' + ErrorAction = 'SilentlyContinue' + } + + $isBCInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isBCInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-IsBooksOnlineInstalled.ps1 b/source/Public/Test-IsBooksOnlineInstalled.ps1 new file mode 100644 index 000000000..32658d1ee --- /dev/null +++ b/source/Public/Test-IsBooksOnlineInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the Books Online is installed. + + .DESCRIPTION + Returns whether the Books Online is installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-IsBooksOnlineInstalled -Version ([System.Version] '16.0') + + Returns $true if SQL Server Books Online is installed. +#> +function Test-IsBooksOnlineInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.Version] + $Version + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $Version.Major + Name = 'SQL_BOL_Components' + ErrorAction = 'SilentlyContinue' + } + + $isBOLInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isBOLInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-IsConnectivityComponentsInstalled.ps1 b/source/Public/Test-IsConnectivityComponentsInstalled.ps1 new file mode 100644 index 000000000..23663861c --- /dev/null +++ b/source/Public/Test-IsConnectivityComponentsInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the Connectivity Components are installed. + + .DESCRIPTION + Returns whether the Connectivity Components are installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-IsConnectivityComponentsInstalled -Version ([System.Version] '16.0') + + Returns $true if Connectivity Components are installed. +#> +function Test-IsConnectivityComponentsInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.Version] + $Version + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $Version.Major + Name = 'Connectivity_Full' + ErrorAction = 'SilentlyContinue' + } + + $isConnInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isConnInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-IsDataQualityClientInstalled.ps1 b/source/Public/Test-IsDataQualityClientInstalled.ps1 index 6b930a5fb..910f5ef1e 100644 --- a/source/Public/Test-IsDataQualityClientInstalled.ps1 +++ b/source/Public/Test-IsDataQualityClientInstalled.ps1 @@ -6,7 +6,7 @@ Returns whether the Data Quality Client is installed. .PARAMETER Version - Specifies the version for which to return installed components. + Specifies the version for which to check if component is installed. .OUTPUTS [System.Boolean] @@ -14,7 +14,7 @@ .EXAMPLE Test-IsDataQualityClientInstalled -Version ([System.Version] '16.0') - Returns $true Data Quality Client is installed. + Returns $true if Data Quality Client is installed. #> function Test-IsDataQualityClientInstalled { diff --git a/source/Public/Test-IsMasterDataServicesInstalled.ps1 b/source/Public/Test-IsMasterDataServicesInstalled.ps1 new file mode 100644 index 000000000..63ca8270b --- /dev/null +++ b/source/Public/Test-IsMasterDataServicesInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the Master Data Services are installed. + + .DESCRIPTION + Returns whether the Master Data Services are installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + IsMasterDataServicesInstalled -Version ([System.Version] '16.0') + + Returns $true if Master Data Services are installed. +#> +function Test-IsMasterDataServicesInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.Version] + $Version + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $Version.Major + Name = 'MDSCoreFeature' + ErrorAction = 'SilentlyContinue' + } + + $isMDSInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isMDSInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-IsReplicationInstalled.ps1 b/source/Public/Test-IsReplicationInstalled.ps1 new file mode 100644 index 000000000..66dda6e66 --- /dev/null +++ b/source/Public/Test-IsReplicationInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the component Replication is installed. + + .DESCRIPTION + Returns whether the component Replication is installed. + + .PARAMETER InstanceId + Specifies the instance id on which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-IsReplicationInstalled -InstanceId 'MSSQL13.SQL2016' + + Returns $true if Replication is installed. +#> +function Test-IsReplicationInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.String] + $InstanceId + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $InstanceId + Name = 'SQL_Replication_Core_Inst' + ErrorAction = 'SilentlyContinue' + } + + $isReplicationInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isReplicationInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-IsSoftwareDevelopmentKitInstalled.ps1 b/source/Public/Test-IsSoftwareDevelopmentKitInstalled.ps1 new file mode 100644 index 000000000..0b9abf313 --- /dev/null +++ b/source/Public/Test-IsSoftwareDevelopmentKitInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the Software Development Kit is installed. + + .DESCRIPTION + Returns whether the Software Development Kit is installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-IsSoftwareDevelopmentKitInstalled -Version ([System.Version] '16.0') + + Returns $true if Software Development Kit is installed. +#> +function Test-IsSoftwareDevelopmentKitInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.Version] + $Version + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $Version.Major + Name = 'SDK_Full' + ErrorAction = 'SilentlyContinue' + } + + $isSDKInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isSDKInstalled -eq 1) + { + $result = $true + } + + return $result +} From 1fa080176f92c70fc934b441ecd28cb3be99cff2 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Sun, 30 Apr 2023 17:01:34 +0200 Subject: [PATCH 14/16] Iteration 2 --- .vscode/settings.json | 13 +- .../Classes/005.InstalledComponentSetting.ps1 | 86 +++++++++++ .../Get-SqlDscDatabaseEngineSetting.ps1 | 84 +++++++++++ .../Public/Get-SqlDscInstalledComponent.ps1 | 133 ++++++++++-------- source/Public/Get-SqlDscInstalledInstance.ps1 | 90 ++++++++++++ source/Public/Get-SqlDscInstalledService.ps1 | 10 +- .../Get-SqlDscIntegrationServicesSetting.ps1 | 58 ++++++++ .../Get-SqlDscMasterDataServicesSetting.ps1 | 69 +++++++++ ...kwardCompatibilityComponentsInstalled.ps1} | 6 +- ... => Test-SqlDscIsBooksOnlineInstalled.ps1} | 6 +- ...lDscIsConnectivityComponentsInstalled.ps1} | 6 +- ...st-SqlDscIsDataQualityClientInstalled.ps1} | 6 +- ...est-SqlDscIsDataQualityServerInstalled.ps1 | 48 +++++++ ...t-SqlDscIsIntegrationServicesInstalled.ps1 | 38 +++++ ...DscIsManagementStudioAdvancedInstalled.ps1 | 102 ++++++++++++++ ...Test-SqlDscIsManagementStudioInstalled.ps1 | 95 +++++++++++++ ...t-SqlDscIsMasterDataServicesInstalled.ps1} | 16 +-- .../Test-SqlDscIsROpenRPackagesInstalled.ps1 | 48 +++++++ ...s1 => Test-SqlDscIsRServicesInstalled.ps1} | 12 +- ... => Test-SqlDscIsReplicationInstalled.ps1} | 6 +- ...lDscIsSoftwareDevelopmentKitInstalled.ps1} | 4 +- source/en-US/SqlServerDsc.strings.psd1 | 12 ++ 22 files changed, 844 insertions(+), 104 deletions(-) create mode 100644 source/Classes/005.InstalledComponentSetting.ps1 create mode 100644 source/Public/Get-SqlDscDatabaseEngineSetting.ps1 create mode 100644 source/Public/Get-SqlDscInstalledInstance.ps1 create mode 100644 source/Public/Get-SqlDscIntegrationServicesSetting.ps1 create mode 100644 source/Public/Get-SqlDscMasterDataServicesSetting.ps1 rename source/Public/{Test-IsBackwardCompatibilityComponentsInstalled.ps1 => Test-SqlDscIsBackwardCompatibilityComponentsInstalled.ps1} (84%) rename source/Public/{Test-IsBooksOnlineInstalled.ps1 => Test-SqlDscIsBooksOnlineInstalled.ps1} (86%) rename source/Public/{Test-IsConnectivityComponentsInstalled.ps1 => Test-SqlDscIsConnectivityComponentsInstalled.ps1} (85%) rename source/Public/{Test-IsDataQualityClientInstalled.ps1 => Test-SqlDscIsDataQualityClientInstalled.ps1} (85%) create mode 100644 source/Public/Test-SqlDscIsDataQualityServerInstalled.ps1 create mode 100644 source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 create mode 100644 source/Public/Test-SqlDscIsManagementStudioAdvancedInstalled.ps1 create mode 100644 source/Public/Test-SqlDscIsManagementStudioInstalled.ps1 rename source/Public/{Test-IsMasterDataServicesInstalled.ps1 => Test-SqlDscIsMasterDataServicesInstalled.ps1} (56%) create mode 100644 source/Public/Test-SqlDscIsROpenRPackagesInstalled.ps1 rename source/Public/{Test-IsAdvancedAnalyticsInstalled.ps1 => Test-SqlDscIsRServicesInstalled.ps1} (70%) rename source/Public/{Test-IsReplicationInstalled.ps1 => Test-SqlDscIsReplicationInstalled.ps1} (87%) rename source/Public/{Test-IsSoftwareDevelopmentKitInstalled.ps1 => Test-SqlDscIsSoftwareDevelopmentKitInstalled.ps1} (92%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4d12744ef..8bc3f173b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -73,7 +73,18 @@ "dbatools", "db_datareader", "fastbuild", - "SSMS" + "SSMS", + "HKEY", + "POWERPIVOT", + "Tempdb", + "NPENABLED", + "TCPENABLED", + "RSINSTALLMODE", + "SVCACCOUNT", + "SVCPASSWORD", + "SQLSERVERAGENT", + "MSSQLFD", + "MSRS" ], "cSpell.ignorePaths": [ ".git" diff --git a/source/Classes/005.InstalledComponentSetting.ps1 b/source/Classes/005.InstalledComponentSetting.ps1 new file mode 100644 index 000000000..85b58afb1 --- /dev/null +++ b/source/Classes/005.InstalledComponentSetting.ps1 @@ -0,0 +1,86 @@ +<# + .SYNOPSIS + Common properties across all components that can be installed. + + .EXAMPLE + [InstalledComponentSetting]::new() + + Creates a new empty object. + + .NOTES + This class should be parent of an derived class that have more properties + that are unique for each component. +#> +class InstalledComponentSetting +{ + [System.String[]] + $FeatureList + + [System.Version] + $Version + + [System.Version] + $PatchLevel + + [System.String] + $Edition + + [System.String] + $EditionType + + [Nullable[System.UInt32]] + $Language + + [System.String] + $ProductCode + + [System.String] + $SqlPath + + InstalledComponentSetting () + { + } + + static [InstalledComponentSetting] op_Addition([InstalledComponentSetting] $Left, [InstalledComponentSetting] $Right) + { + $propertyList = $Left.PSObject.Properties.Name + + foreach ($property in $propertyList) + { + # Only add values if left side is $null and right side is not null. + if (-not $Left.$property -and $Right.$property) + { + $Left.$property = $Right.$property + } + } + + return $Left + } + + static [InstalledComponentSetting] Parse([PSCustomObject] $Settings) + { + $installedComponentSetting = [InstalledComponentSetting]::new() + + if ($settings.FeatureList) + { + $installedComponentSetting.FeatureList = $settings.FeatureList -split ' ' + } + + $propertyList = ( + $installedComponentSetting.PSObject.Properties | + Where-Object -FilterScript { + $_.Name -ne 'FeatureList' + } + ).Name + + foreach ($property in $propertyList) + { + if ($settings.$property) + { + $installedComponentSetting.$property = $settings.$property + } + } + + return $installedComponentSetting + } +} diff --git a/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 b/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 new file mode 100644 index 000000000..cdacea515 --- /dev/null +++ b/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 @@ -0,0 +1,84 @@ +<# + .SYNOPSIS + Returns the integration services settings. + + .DESCRIPTION + Returns the integration services settings. + + .PARAMETER Version + Specifies the version for which to return settings for. + + .OUTPUTS + `[System.Management.Automation.PSCustomObject]` + + .EXAMPLE + Get-SqlDscIntegrationServicesSetting -Version ([System.Version] '16.0') + + Returns the settings for the integration services. +#> +function Get-SqlDscDatabaseEngineSetting +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.Version] + $Version + ) + + <# + HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.SQL2016\Setup + + FeatureList + Version + PatchLevel + Edition + EditionType + Language + ProductCode + SqlPath + + TODO: Gör en Get-SqlDscServiceName med data från HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Services + Liknande Get-SqlDscInstalledInstance + #> + $masterDataServicesSettings = $null + + $getItemPropertyParameters = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\Master Data Services\Setup\MDSCoreFeature' -f $Version.Major + ErrorAction = 'SilentlyContinue' + } + + $mdsCoreFeatureSettings = Get-ItemProperty @getItemPropertyParameters + + if (-not $mdsCoreFeatureSettings) + { + $missingIntegrationServiceMessage = $script:localizedData.MasterDataServicesSetting_Get_NotInstalled -f $Version.ToString() + + $writeErrorParameters = @{ + Message = $missingIntegrationServiceMessage + Category = 'InvalidOperation' + ErrorId = 'GISS0001' # cspell: disable-line + TargetObject = $Version + } + + Write-Error @writeErrorParameters + } + else + { + $masterDataServicesSettings1 = [InstalledComponentSetting]::Parse($mdsCoreFeatureSettings) + + $getItemPropertyParameters = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\Master Data Services\Setup' -f $Version.Major + ErrorAction = 'SilentlyContinue' + } + + $mdsSetupSettings = Get-ItemProperty @getItemPropertyParameters + + $masterDataServicesSettings2 = [InstalledComponentSetting]::Parse($mdsSetupSettings) + + $masterDataServicesSettings = $masterDataServicesSettings1 + $masterDataServicesSettings2 + } + + return $masterDataServicesSettings +} diff --git a/source/Public/Get-SqlDscInstalledComponent.ps1 b/source/Public/Get-SqlDscInstalledComponent.ps1 index bbbd782df..4ca6c65a0 100644 --- a/source/Public/Get-SqlDscInstalledComponent.ps1 +++ b/source/Public/Get-SqlDscInstalledComponent.ps1 @@ -17,7 +17,7 @@ will be returned. .EXAMPLE - Get-SqlDscInstalledComponents + Get-SqlDscInstalledComponent Returns all the installed components. @@ -59,6 +59,7 @@ function Get-SqlDscInstalledComponent switch ($currentServiceComponent.ServiceType) { + # TODO: Add a Test-command for the path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.SQL2016\ConfigurationState\SQL_Engine_Core_Inst 'DatabaseEngine' { $installedComponent.Feature = 'SQLEngine' @@ -66,6 +67,7 @@ function Get-SqlDscInstalledComponent break } + # TODO: Add a Test-command for the path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.SQL2022\ConfigurationState\SQL_FullText_Adv '9' { $installedComponent.Feature += 'FullText' @@ -73,13 +75,7 @@ function Get-SqlDscInstalledComponent break } - '12' - { - $installedComponent.Feature += 'AdvancedAnalytics' - - break - } - + # TODO: Add an Test-command for the path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSAS16.SQL2022\ConfigurationState\Analysis_Server_Full 'AnalysisServices' { $installedComponent.Feature += 'AS' @@ -87,13 +83,7 @@ function Get-SqlDscInstalledComponent break } - 'IntegrationServices' - { - $installedComponent.Feature += 'IS' - - break - } - + # TODO: Add an Test-command for the path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSRS13.SQL2016\ConfigurationState\RS_Server_Adv 'ReportingServices' { $installedComponent.Feature += 'RS' @@ -101,7 +91,7 @@ function Get-SqlDscInstalledComponent break } - Default + default { # Skip services like SQL Browser and SQL Agent. @@ -136,10 +126,20 @@ function Get-SqlDscInstalledComponent foreach ($databaseLevel in $installedDatabaseLevel) { - $databaseLevelVersion = [System.Version] ('{0}.{1}' -f $databaseLevel.Substring(0,2), $databaseLevel.Substring(2,1)) + $databaseLevelVersion = [System.Version] ('{0}.{1}' -f $databaseLevel.Substring(0, 2), $databaseLevel.Substring(2, 1)) + + $integrationServicesSettings = Get-SqlDscIntegrationServicesSetting -Version $databaseLevelVersion -ErrorAction 'SilentlyContinue' + + if ($integrationServicesSettings) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'IS' + Version = $integrationServicesSettings.Version + } + } # Look for installed version of Data Quality Client. - $isDQInstalled = Test-IsDataQualityClientInstalled -Version $databaseLevelVersion + $isDQInstalled = Test-SqlDscIsDataQualityClientInstalled -Version $databaseLevelVersion if ($isDQInstalled) { @@ -150,7 +150,7 @@ function Get-SqlDscInstalledComponent } # Look for installed version of SQL Server Books Online. - $isBOLInstalled = Test-IsBooksOnlineInstalled -Version $databaseLevelVersion + $isBOLInstalled = Test-SqlDscIsBooksOnlineInstalled -Version $databaseLevelVersion if ($isBOLInstalled) { @@ -161,7 +161,7 @@ function Get-SqlDscInstalledComponent } # Look for installed version of Connectivity Components. - $isConnInstalled = Test-IsConnectivityComponentsInstalled -Version $databaseLevelVersion + $isConnInstalled = Test-SqlDscIsConnectivityComponentsInstalled -Version $databaseLevelVersion if ($isConnInstalled) { @@ -172,7 +172,7 @@ function Get-SqlDscInstalledComponent } # Look for installed version of Backward Compatibility Components. - $isBCInstalled = Test-IsBackwardCompatibilityComponentsInstalled -Version $databaseLevelVersion + $isBCInstalled = Test-SqlDscIsBackwardCompatibilityComponentsInstalled -Version $databaseLevelVersion if ($isBCInstalled) { @@ -183,7 +183,7 @@ function Get-SqlDscInstalledComponent } # Look for installed version of Software Development Kit. - $isSDKInstalled = Test-IsSoftwareDevelopmentKitInstalled -Version $databaseLevelVersion + $isSDKInstalled = Test-SqlDscIsSoftwareDevelopmentKitInstalled -Version $databaseLevelVersion if ($isSDKInstalled) { @@ -194,77 +194,94 @@ function Get-SqlDscInstalledComponent } # Look for installed version of Master Data Services. - $isMDSInstalled = Test-IsMasterDataServicesInstalled -Version $databaseLevelVersion + $masterDataServicesSettings = Get-SqlDscMasterDataServicesSetting -Version $databaseLevelVersion -ErrorAction 'SilentlyContinue' - if ($isMDSInstalled) + if ($masterDataServicesSettings) { $installedComponents += [PSCustomObject] @{ Feature = 'MDS' + Version = $masterDataServicesSettings.Version + } + } + + # Look for installed version of SQL Server Management Studio. + $isManagementStudioInstalled = Test-SqlDscIsManagementStudioInstalled -Version $databaseLevelVersion -ErrorAction 'SilentlyContinue' + + if ($isManagementStudioInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'SSMS' Version = $databaseLevelVersion } } - } - $databaseEngineInstance = $installedComponents | - Where-Object -FilterScript { - $_.InstanceId -match '^MSSQL' + # Look for installed version of SQL Server Management Studio Advanced. + $isManagementStudioAdvancedInstalled = Test-SqlDscIsManagementStudioAdvancedInstalled -Version $databaseLevelVersion -ErrorAction 'SilentlyContinue' + + if ($isManagementStudioAdvancedInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'ADV_SSMS' + Version = $databaseLevelVersion } + } + } + + # Fetch all database engine instances. + $installedDatabaseEngineInstance = Get-SqlDscInstalledInstance -ServiceType 'DatabaseEngine' - foreach ($currentInstance in $databaseEngineInstance) + foreach ($currentInstance in $installedDatabaseEngineInstance) { # Looking for installed version for Replication. - $isReplicationInstalled = Test-IsReplicationInstalled -InstanceId $currentInstance.InstanceId + $isReplicationInstalled = Test-SqlDscIsReplicationInstalled -InstanceId $currentInstance.InstanceId if ($isReplicationInstalled) { $installedComponents += [PSCustomObject] @{ Feature = 'Replication' - Version = $currentInstance.Version + #Version = $currentInstance.Version InstanceName = $currentInstance.InstanceName InstanceId = $currentInstance.InstanceId } } - # Looking for installed version for Replication. - $isReplicationInstalled = Test-IsAdvancedAnalyticsInstalled -InstanceId $currentInstance.InstanceId + # Looking for installed version for Advanced Analytics - R Services (In-Database)). + $isReplicationInstalled = Test-SqlDscIsRServicesInstalled -InstanceId $currentInstance.InstanceId if ($isReplicationInstalled) { $installedComponents += [PSCustomObject] @{ Feature = 'AdvancedAnalytics' - Version = $currentInstance.Version + #Version = $currentInstance.Version InstanceName = $currentInstance.InstanceName InstanceId = $currentInstance.InstanceId } } - } - - # SQL_DQ_Full = DQ : Data Quality Services - # sql_inst_mr = SQL_INST_MR : R Open and proprietary R packages - # sql_inst_mpy = SQL_INST_MPY : Anaconda and proprietary Python packages. - # SQL_Polybase_Core_Inst = PolyBaseCore : PolyBase technology - - #$isDQInstalled = Test-IsDQComponentInstalled -InstanceName $InstanceName -SqlServerMajorVersion $sqlVersion - # if ($isDQInstalled) - # { - # $component.Feature = 'DQ' - # } + $isDataQualityServerInstalled = Test-SqlDscIsDataQualityServerInstalled -InstanceId $currentInstance.InstanceId - # #$isSsmsInstalled = Test-IsSsmsInstalled -SqlServerMajorVersion $sqlVersion - - # if ($isSsmsInstalled) - # { - # $component.Feature = 'SSMS' - # } - - # #$isSsmsAdvancedInstalled = Test-IsSsmsAdvancedInstalled -SqlServerMajorVersion $sqlVersion + if ($isDataQualityServerInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'DQ' + #Version = $currentInstance.Version + InstanceName = $currentInstance.InstanceName + InstanceId = $currentInstance.InstanceId + } + } - # if ($isSsmsAdvancedInstalled) - # { - # $component.Feature = 'ADV_SSMS' - # } + $isROpenRPackagesInstalled = Test-SqlDscIsROpenRPackagesInstalled -InstanceId $currentInstance.InstanceId + if ($isROpenRPackagesInstalled) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'SQL_INST_MR' + #Version = $currentInstance.Version + InstanceName = $currentInstance.InstanceName + InstanceId = $currentInstance.InstanceId + } + } + } # Filter result diff --git a/source/Public/Get-SqlDscInstalledInstance.ps1 b/source/Public/Get-SqlDscInstalledInstance.ps1 new file mode 100644 index 000000000..8b7b6cad5 --- /dev/null +++ b/source/Public/Get-SqlDscInstalledInstance.ps1 @@ -0,0 +1,90 @@ +<# + .SYNOPSIS + Returns the installed instances on the current node. + + .DESCRIPTION + Returns the installed instances on the current node. + + .PARAMETER InstanceName + Specifies the instance name to return instances for. + + .OUTPUTS + `[System.Object[]]` + + .EXAMPLE + Get-SqlDscInstalledInstance + + Returns all installed instances. +#> +function Get-SqlDscInstalledInstance +{ + [CmdletBinding()] + [OutputType([System.Object[]])] + param + ( + [Parameter()] + [System.String] + $InstanceName, + + [Parameter()] + [ValidateSet('DatabaseEngine', 'AnalysisServices', 'ReportingServices')] + [System.String[]] + $ServiceType + ) + + $instances = @() + + $installedServiceType = Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names' + + foreach ($currentServiceType in $installedServiceType) + { + $serviceTypeName = switch ($currentServiceType.PSChildName) + { + 'OLAP' + { + 'AnalysisServices' + + break + } + + 'SQL' + { + 'DatabaseEngine' + + break + } + + 'RS' + { + 'ReportingServices' + + break + } + } + + if ($PSBoundParameters.ContainsKey('ServiceType') -and $serviceTypeName -notin $ServiceType) + { + continue + } + + $instanceNames = $currentServiceType.GetValueNames() + + foreach ($currentInstanceName in $instanceNames) + { + if ($PSBoundParameters.ContainsKey('InstanceName') -and $currentInstanceName -ne $InstanceName) + { + continue + } + + $foundInstance = [PSCustomObject] @{ + ServiceType = $serviceTypeName + InstanceName = $currentInstanceName + InstanceId = $currentServiceType.GetValue($currentInstanceName) + } + + $instances += $foundInstance + } + } + + return $instances +} diff --git a/source/Public/Get-SqlDscInstalledService.ps1 b/source/Public/Get-SqlDscInstalledService.ps1 index 56850cc19..0a1bcb21a 100644 --- a/source/Public/Get-SqlDscInstalledService.ps1 +++ b/source/Public/Get-SqlDscInstalledService.ps1 @@ -25,15 +25,7 @@ function Get-SqlDscInstalledService [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $ServerName = (Get-ComputerName), - - [Parameter()] - [System.String] - $InstanceName, - - [Parameter()] - [System.Version] - $Version + $ServerName = (Get-ComputerName) ) Assert-ElevatedUser -ErrorAction 'Stop' diff --git a/source/Public/Get-SqlDscIntegrationServicesSetting.ps1 b/source/Public/Get-SqlDscIntegrationServicesSetting.ps1 new file mode 100644 index 000000000..96d766e13 --- /dev/null +++ b/source/Public/Get-SqlDscIntegrationServicesSetting.ps1 @@ -0,0 +1,58 @@ +<# + .SYNOPSIS + Returns the Integration Services settings. + + .DESCRIPTION + Returns the Integration Services settings. + + .PARAMETER Version + Specifies the version for which to return settings for. + + .OUTPUTS + `[System.Management.Automation.PSCustomObject]` + + .EXAMPLE + Get-SqlDscIntegrationServicesSetting -Version ([System.Version] '16.0') + + Returns the settings for the Integration Services. +#> +function Get-SqlDscIntegrationServicesSetting +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.Version] + $Version + ) + + $integrationServicesSettings = $null + + $getItemPropertyParameters = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\DTS\Setup' -f $Version.Major + ErrorAction = 'SilentlyContinue' + } + + $setupSettings = Get-ItemProperty @getItemPropertyParameters + + if (-not $setupSettings) + { + $missingIntegrationServiceMessage = $script:localizedData.IntegrationServicesSetting_Get_NotInstalled -f $Version.ToString() + + $writeErrorParameters = @{ + Message = $missingIntegrationServiceMessage + Category = 'InvalidOperation' + ErrorId = 'GISS0001' # cspell: disable-line + TargetObject = $Version + } + + Write-Error @writeErrorParameters + } + else + { + $integrationServicesSettings = [InstalledComponentSetting]::Parse($setupSettings) + } + + return $integrationServicesSettings +} diff --git a/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 b/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 new file mode 100644 index 000000000..93a4bab9b --- /dev/null +++ b/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 @@ -0,0 +1,69 @@ +<# + .SYNOPSIS + Returns the integration services settings. + + .DESCRIPTION + Returns the integration services settings. + + .PARAMETER Version + Specifies the version for which to return settings for. + + .OUTPUTS + `[System.Management.Automation.PSCustomObject]` + + .EXAMPLE + Get-SqlDscIntegrationServicesSetting -Version ([System.Version] '16.0') + + Returns the settings for the integration services. +#> +function Get-SqlDscMasterDataServicesSetting +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.Version] + $Version + ) + + $masterDataServicesSettings = $null + + $getItemPropertyParameters = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\Master Data Services\Setup\MDSCoreFeature' -f $Version.Major + ErrorAction = 'SilentlyContinue' + } + + $mdsCoreFeatureSettings = Get-ItemProperty @getItemPropertyParameters + + if (-not $mdsCoreFeatureSettings) + { + $missingIntegrationServiceMessage = $script:localizedData.MasterDataServicesSetting_Get_NotInstalled -f $Version.ToString() + + $writeErrorParameters = @{ + Message = $missingIntegrationServiceMessage + Category = 'InvalidOperation' + ErrorId = 'GISS0001' # cspell: disable-line + TargetObject = $Version + } + + Write-Error @writeErrorParameters + } + else + { + $masterDataServicesSettings1 = [InstalledComponentSetting]::Parse($mdsCoreFeatureSettings) + + $getItemPropertyParameters = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\Master Data Services\Setup' -f $Version.Major + ErrorAction = 'SilentlyContinue' + } + + $mdsSetupSettings = Get-ItemProperty @getItemPropertyParameters + + $masterDataServicesSettings2 = [InstalledComponentSetting]::Parse($mdsSetupSettings) + + $masterDataServicesSettings = $masterDataServicesSettings1 + $masterDataServicesSettings2 + } + + return $masterDataServicesSettings +} diff --git a/source/Public/Test-IsBackwardCompatibilityComponentsInstalled.ps1 b/source/Public/Test-SqlDscIsBackwardCompatibilityComponentsInstalled.ps1 similarity index 84% rename from source/Public/Test-IsBackwardCompatibilityComponentsInstalled.ps1 rename to source/Public/Test-SqlDscIsBackwardCompatibilityComponentsInstalled.ps1 index 9478447c5..ec0e523c0 100644 --- a/source/Public/Test-IsBackwardCompatibilityComponentsInstalled.ps1 +++ b/source/Public/Test-SqlDscIsBackwardCompatibilityComponentsInstalled.ps1 @@ -12,17 +12,17 @@ [System.Boolean] .EXAMPLE - Test-IsBackwardCompatibilityComponentsInstalled -Version ([System.Version] '16.0') + Test-SqlDscIsBackwardCompatibilityComponentsInstalled -Version ([System.Version] '16.0') Returns $true if Backward Compatibility Components are installed. #> -function Test-IsBackwardCompatibilityComponentsInstalled +function Test-SqlDscIsBackwardCompatibilityComponentsInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.Version] $Version ) diff --git a/source/Public/Test-IsBooksOnlineInstalled.ps1 b/source/Public/Test-SqlDscIsBooksOnlineInstalled.ps1 similarity index 86% rename from source/Public/Test-IsBooksOnlineInstalled.ps1 rename to source/Public/Test-SqlDscIsBooksOnlineInstalled.ps1 index 32658d1ee..25ef93bc6 100644 --- a/source/Public/Test-IsBooksOnlineInstalled.ps1 +++ b/source/Public/Test-SqlDscIsBooksOnlineInstalled.ps1 @@ -12,17 +12,17 @@ [System.Boolean] .EXAMPLE - Test-IsBooksOnlineInstalled -Version ([System.Version] '16.0') + Test-SqlDscIsBooksOnlineInstalled -Version ([System.Version] '16.0') Returns $true if SQL Server Books Online is installed. #> -function Test-IsBooksOnlineInstalled +function Test-SqlDscIsBooksOnlineInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.Version] $Version ) diff --git a/source/Public/Test-IsConnectivityComponentsInstalled.ps1 b/source/Public/Test-SqlDscIsConnectivityComponentsInstalled.ps1 similarity index 85% rename from source/Public/Test-IsConnectivityComponentsInstalled.ps1 rename to source/Public/Test-SqlDscIsConnectivityComponentsInstalled.ps1 index 23663861c..665c45a49 100644 --- a/source/Public/Test-IsConnectivityComponentsInstalled.ps1 +++ b/source/Public/Test-SqlDscIsConnectivityComponentsInstalled.ps1 @@ -12,17 +12,17 @@ [System.Boolean] .EXAMPLE - Test-IsConnectivityComponentsInstalled -Version ([System.Version] '16.0') + Test-SqlDscIsConnectivityComponentsInstalled -Version ([System.Version] '16.0') Returns $true if Connectivity Components are installed. #> -function Test-IsConnectivityComponentsInstalled +function Test-SqlDscIsConnectivityComponentsInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.Version] $Version ) diff --git a/source/Public/Test-IsDataQualityClientInstalled.ps1 b/source/Public/Test-SqlDscIsDataQualityClientInstalled.ps1 similarity index 85% rename from source/Public/Test-IsDataQualityClientInstalled.ps1 rename to source/Public/Test-SqlDscIsDataQualityClientInstalled.ps1 index 910f5ef1e..3542e52e9 100644 --- a/source/Public/Test-IsDataQualityClientInstalled.ps1 +++ b/source/Public/Test-SqlDscIsDataQualityClientInstalled.ps1 @@ -12,17 +12,17 @@ [System.Boolean] .EXAMPLE - Test-IsDataQualityClientInstalled -Version ([System.Version] '16.0') + Test-SqlDscIsDataQualityClientInstalled -Version ([System.Version] '16.0') Returns $true if Data Quality Client is installed. #> -function Test-IsDataQualityClientInstalled +function Test-SqlDscIsDataQualityClientInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.Version] $Version ) diff --git a/source/Public/Test-SqlDscIsDataQualityServerInstalled.ps1 b/source/Public/Test-SqlDscIsDataQualityServerInstalled.ps1 new file mode 100644 index 000000000..ef82f2009 --- /dev/null +++ b/source/Public/Test-SqlDscIsDataQualityServerInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the component Data Quality Server is installed. + + .DESCRIPTION + Returns whether the component Data Quality Server is installed. + + .PARAMETER InstanceId + Specifies the instance id on which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-SqlDscIsDataQualityServerInstalled -InstanceId 'MSSQL16.SQL2022' + + Returns $true if Data Quality Server is installed. +#> +function Test-SqlDscIsDataQualityServerInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceId + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $InstanceId + Name = 'SQL_DQ_Full' + ErrorAction = 'SilentlyContinue' + } + + $isDataQualityServerInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isDataQualityServerInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 b/source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 new file mode 100644 index 000000000..d96793846 --- /dev/null +++ b/source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 @@ -0,0 +1,38 @@ +<# + .SYNOPSIS + Returns whether the Integration Services are installed. + + .DESCRIPTION + Returns whether the Integration Services are installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-SqlDscIsIntegrationServicesInstalled -Version ([System.Version] '16.0') + + Returns $true if Integration Services are installed. +#> +function Test-SqlDscIsIntegrationServicesInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.Version] + $Version + ) + + $result = $false + + if ((Get-SqlDscIntegrationServicesSetting -Version $Version -ErrorAction 'SilentlyContinue')) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-SqlDscIsManagementStudioAdvancedInstalled.ps1 b/source/Public/Test-SqlDscIsManagementStudioAdvancedInstalled.ps1 new file mode 100644 index 000000000..daec8e765 --- /dev/null +++ b/source/Public/Test-SqlDscIsManagementStudioAdvancedInstalled.ps1 @@ -0,0 +1,102 @@ +<# + .SYNOPSIS + Returns whether the SQL Server Management Studio Advanced is installed. + + .DESCRIPTION + Returns whether the SQL Server Management Studio Advanced is installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-SqlDscIsManagementStudioAdvancedInstalled -Version ([System.Version] '12.0') + + Returns $true if SQL Server Management Studio Advanced is installed. +#> +function Test-SqlDscIsManagementStudioAdvancedInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.Version] + $Version + ) + + # If an unsupported version was passed, make sure the function returns $false. + $productIdentifyingNumber = $null + + switch ($Version.Major) + { + 10 + { + <# + Evaluating if SQL Server Management Studio Advanced 2008 or + SQL Server Management Studio Advanced 2008 R2 (major version 10) + is installed. + #> + $productIdentifyingNumber = '{B5FE23CC-0151-4595-84C3-F1DE6F44FE9B}' + + break + } + + 11 + { + <# + Evaluating if SQL Server Management Studio Advanced 2012 (major + version 11) is installed. + #> + $productIdentifyingNumber = '{7842C220-6E9A-4D5A-AE70-0E138271F883}' + + break + } + + 12 + { + <# + Evaluating if SQL Server Management Studio Advanced 2014 (major + version 12) is installed. + #> + $productIdentifyingNumber = '{B5ECFA5C-AC4F-45A4-A12E-A76ABDD9CCBA}' + + break + } + + default + { + $writeErrorParameters = @{ + Message = $script:localizedData.IsManagementStudioAdvancedInstalled_Test_NotSupportedVersion + Category = 'InvalidOperation' + ErrorId = 'TIMSAI0001' # cSpell: disable-line + TargetObject = $Version + } + + Write-Error @writeErrorParameters + } + } + + $result = $false + + if ($productIdentifyingNumber) + { + $registryUninstallPath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall' + + $getItemPropertyParameters = @{ + Path = Join-Path -Path $registryUninstallPath -ChildPath $productIdentifyingNumber + ErrorAction = 'SilentlyContinue' + } + + $registryObject = Get-ItemProperty @getItemPropertyParameters + + if ($registryObject) + { + $result = $true + } + } + + return $result +} diff --git a/source/Public/Test-SqlDscIsManagementStudioInstalled.ps1 b/source/Public/Test-SqlDscIsManagementStudioInstalled.ps1 new file mode 100644 index 000000000..68b91a6f3 --- /dev/null +++ b/source/Public/Test-SqlDscIsManagementStudioInstalled.ps1 @@ -0,0 +1,95 @@ +<# + .SYNOPSIS + Returns whether the SQL Server Management Studio is installed. + + .DESCRIPTION + Returns whether the SQL Server Management Studio is installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-SqlDscIsManagementStudioInstalled -Version ([System.Version] '12.0') + + Returns $true if SQL Server Management Studio is installed. +#> +function Test-SqlDscIsManagementStudioInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.Version] + $Version + ) + + # If an unsupported version was passed, make sure the function returns $false. + $productIdentifyingNumber = $null + + switch ($Version.Major) + { + 10 + { + <# + Verify if SQL Server Management Studio 2008 or SQL Server Management + Studio 2008 R2 (major version 10) is installed. + #> + $productIdentifyingNumber = '{72AB7E6F-BC24-481E-8C45-1AB5B3DD795D}' + + break + } + + 11 + { + # Verify if SQL Server Management Studio 2012 (major version 11) is installed. + $productIdentifyingNumber = '{A7037EB2-F953-4B12-B843-195F4D988DA1}' + + break + } + + 12 + { + # Verify if SQL Server Management Studio 2014 (major version 12) is installed. + $productIdentifyingNumber = '{75A54138-3B98-4705-92E4-F619825B121F}' + + break + } + + default + { + $writeErrorParameters = @{ + Message = $script:localizedData.IsManagementStudioInstalled_Test_NotSupportedVersion + Category = 'InvalidOperation' + ErrorId = 'TIMSI0001' # cSpell: disable-line + TargetObject = $Version + } + + Write-Error @writeErrorParameters + } + } + + $result = $false + + if ($productIdentifyingNumber) + { + $registryUninstallPath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall' + + $getItemPropertyParameters = @{ + Path = Join-Path -Path $registryUninstallPath -ChildPath $productIdentifyingNumber + ErrorAction = 'SilentlyContinue' + } + + $registryObject = Get-ItemProperty @getItemPropertyParameters + + if ($registryObject) + { + $result = $true + } + } + + return $result +} diff --git a/source/Public/Test-IsMasterDataServicesInstalled.ps1 b/source/Public/Test-SqlDscIsMasterDataServicesInstalled.ps1 similarity index 56% rename from source/Public/Test-IsMasterDataServicesInstalled.ps1 rename to source/Public/Test-SqlDscIsMasterDataServicesInstalled.ps1 index 63ca8270b..adea3d4f5 100644 --- a/source/Public/Test-IsMasterDataServicesInstalled.ps1 +++ b/source/Public/Test-SqlDscIsMasterDataServicesInstalled.ps1 @@ -16,30 +16,20 @@ Returns $true if Master Data Services are installed. #> -function Test-IsMasterDataServicesInstalled +function Test-SqlDscIsMasterDataServicesInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.Version] $Version ) - $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\ConfigurationState' - - $getRegistryPropertyValueParameters = @{ - Path = $configurationStateRegistryPath -f $Version.Major - Name = 'MDSCoreFeature' - ErrorAction = 'SilentlyContinue' - } - - $isMDSInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters - $result = $false - if ($isMDSInstalled -eq 1) + if ((Get-SqlDscMasterDataServicesSetting -Version $Version -ErrorAction 'SilentlyContinue')) { $result = $true } diff --git a/source/Public/Test-SqlDscIsROpenRPackagesInstalled.ps1 b/source/Public/Test-SqlDscIsROpenRPackagesInstalled.ps1 new file mode 100644 index 000000000..1db1b3106 --- /dev/null +++ b/source/Public/Test-SqlDscIsROpenRPackagesInstalled.ps1 @@ -0,0 +1,48 @@ +<# + .SYNOPSIS + Returns whether the component R Open and proprietary R packages are installed. + + .DESCRIPTION + Returns whether the component R Open and proprietary R packages is installed. + + .PARAMETER InstanceId + Specifies the instance id on which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-SqlDscIsROpenRPackagesInstalled -InstanceId 'MSSQL16.SQL2022' + + Returns $true if R Open and proprietary R packages is installed. +#> +function Test-SqlDscIsROpenRPackagesInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceId + ) + + $configurationStateRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\ConfigurationState' + + $getRegistryPropertyValueParameters = @{ + Path = $configurationStateRegistryPath -f $InstanceId + Name = 'sql_inst_mr' + ErrorAction = 'SilentlyContinue' + } + + $isROpenRPackagesInstalled = Get-RegistryPropertyValue @getRegistryPropertyValueParameters + + $result = $false + + if ($isROpenRPackagesInstalled -eq 1) + { + $result = $true + } + + return $result +} diff --git a/source/Public/Test-IsAdvancedAnalyticsInstalled.ps1 b/source/Public/Test-SqlDscIsRServicesInstalled.ps1 similarity index 70% rename from source/Public/Test-IsAdvancedAnalyticsInstalled.ps1 rename to source/Public/Test-SqlDscIsRServicesInstalled.ps1 index a0943afb9..8214d46c0 100644 --- a/source/Public/Test-IsAdvancedAnalyticsInstalled.ps1 +++ b/source/Public/Test-SqlDscIsRServicesInstalled.ps1 @@ -1,9 +1,9 @@ <# .SYNOPSIS - Returns whether the component Advanced Analytics is installed. + Returns whether the component R Services (In-Database) are installed. .DESCRIPTION - Returns whether the component Advanced Analytics is installed. + Returns whether the component R Services (In-Database) is installed. .PARAMETER InstanceId Specifies the instance id on which to check if component is installed. @@ -12,17 +12,17 @@ [System.Boolean] .EXAMPLE - Test-IsReplicationInstalled -InstanceId 'MSSQL16.SQL2022' + Test-IsRServicesInstalled -InstanceId 'MSSQL16.SQL2022' - Returns $true if Advanced Analytics is installed. + Returns $true if R Services (In-Database) is installed. #> -function Test-IsAdvancedAnalyticsInstalled +function Test-SqlDscIsRServicesInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.String] $InstanceId ) diff --git a/source/Public/Test-IsReplicationInstalled.ps1 b/source/Public/Test-SqlDscIsReplicationInstalled.ps1 similarity index 87% rename from source/Public/Test-IsReplicationInstalled.ps1 rename to source/Public/Test-SqlDscIsReplicationInstalled.ps1 index 66dda6e66..e25eba11c 100644 --- a/source/Public/Test-IsReplicationInstalled.ps1 +++ b/source/Public/Test-SqlDscIsReplicationInstalled.ps1 @@ -12,17 +12,17 @@ [System.Boolean] .EXAMPLE - Test-IsReplicationInstalled -InstanceId 'MSSQL13.SQL2016' + Test-SqlDscIsReplicationInstalled -InstanceId 'MSSQL13.SQL2016' Returns $true if Replication is installed. #> -function Test-IsReplicationInstalled +function Test-SqlDscIsReplicationInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.String] $InstanceId ) diff --git a/source/Public/Test-IsSoftwareDevelopmentKitInstalled.ps1 b/source/Public/Test-SqlDscIsSoftwareDevelopmentKitInstalled.ps1 similarity index 92% rename from source/Public/Test-IsSoftwareDevelopmentKitInstalled.ps1 rename to source/Public/Test-SqlDscIsSoftwareDevelopmentKitInstalled.ps1 index 0b9abf313..8106b6f77 100644 --- a/source/Public/Test-IsSoftwareDevelopmentKitInstalled.ps1 +++ b/source/Public/Test-SqlDscIsSoftwareDevelopmentKitInstalled.ps1 @@ -16,13 +16,13 @@ Returns $true if Software Development Kit is installed. #> -function Test-IsSoftwareDevelopmentKitInstalled +function Test-SqlDscIsSoftwareDevelopmentKitInstalled { [CmdletBinding()] [OutputType([System.Boolean])] param ( - [Parameter()] + [Parameter(Mandatory = $true)] [System.Version] $Version ) diff --git a/source/en-US/SqlServerDsc.strings.psd1 b/source/en-US/SqlServerDsc.strings.psd1 index 07e5bf4c5..470a91bff 100644 --- a/source/en-US/SqlServerDsc.strings.psd1 +++ b/source/en-US/SqlServerDsc.strings.psd1 @@ -182,4 +182,16 @@ PreferredModule_ModuleVersionNotFound = No preferred Powershell module with vers ## Get-SqlDscConfigurationOption ConfigurationOption_Get_Missing = There is no configuration option with the name '{0}'. + + ## Test-IsManagementStudioInstalled + IsManagementStudioInstalled_Test_NotSupportedVersion = SQL Server Management Studio is not supported for the provided version. + + ## Test-IsManagementStudioAdvancedInstalled + IsManagementStudioAdvancedInstalled_Test_NotSupportedVersion = SQL Server Management Studio Advanced is not supported for the provided version. + + ## Get-SqlDscIntegrationServicesSetting + IntegrationServicesSetting_Get_NotInstalled = There are no Integration Services installed with version {0}. + + ## Get-SqlDscMasterDataServicesSetting + MasterDataServicesSetting_Get_NotInstalled = There are no Master Data Services installed with version {0}. '@ From 889524bd4eda7e0e807d5fe89ca4b61cbe865cb0 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Mon, 1 May 2023 09:28:22 +0200 Subject: [PATCH 15/16] Iteration 3 --- .../Get-SqlDscDatabaseEngineSetting.ps1 | 62 ++++++------------- .../Public/Get-SqlDscInstalledComponent.ps1 | 38 +++++++----- .../Get-SqlDscMasterDataServicesSetting.ps1 | 4 +- source/Public/Get-SqlDscServiceType.ps1 | 54 ++++++++++++++++ source/en-US/SqlServerDsc.strings.psd1 | 3 + 5 files changed, 98 insertions(+), 63 deletions(-) create mode 100644 source/Public/Get-SqlDscServiceType.ps1 diff --git a/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 b/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 index cdacea515..472734ca3 100644 --- a/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 +++ b/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 @@ -1,20 +1,20 @@ <# .SYNOPSIS - Returns the integration services settings. + Returns the database engine settings. .DESCRIPTION - Returns the integration services settings. + Returns the database engine settings. - .PARAMETER Version - Specifies the version for which to return settings for. + .PARAMETER InstanceId + Specifies the instance id on which to check if component is installed. .OUTPUTS `[System.Management.Automation.PSCustomObject]` .EXAMPLE - Get-SqlDscIntegrationServicesSetting -Version ([System.Version] '16.0') + Get-SqlDscDatabaseEngineSetting -InstanceId 'MSSQL13.SQL2016' - Returns the settings for the integration services. + Returns the settings for the database engine. #> function Get-SqlDscDatabaseEngineSetting { @@ -23,42 +23,27 @@ function Get-SqlDscDatabaseEngineSetting param ( [Parameter(Mandatory = $true)] - [System.Version] - $Version + [System.String] + $InstanceId ) - <# - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.SQL2016\Setup - - FeatureList - Version - PatchLevel - Edition - EditionType - Language - ProductCode - SqlPath - - TODO: Gör en Get-SqlDscServiceName med data från HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Services - Liknande Get-SqlDscInstalledInstance - #> - $masterDataServicesSettings = $null + $databaseEngineSettings = $null $getItemPropertyParameters = @{ - Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\Master Data Services\Setup\MDSCoreFeature' -f $Version.Major + Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\Setup' -f $InstanceId ErrorAction = 'SilentlyContinue' } - $mdsCoreFeatureSettings = Get-ItemProperty @getItemPropertyParameters + $setupSettings = Get-ItemProperty @getItemPropertyParameters - if (-not $mdsCoreFeatureSettings) + if (-not $setupSettings) { - $missingIntegrationServiceMessage = $script:localizedData.MasterDataServicesSetting_Get_NotInstalled -f $Version.ToString() + $missingDatabaseEngineMessage = $script:localizedData.DatabaseEngineSetting_Get_NotInstalled -f $Version.ToString() $writeErrorParameters = @{ - Message = $missingIntegrationServiceMessage - Category = 'InvalidOperation' - ErrorId = 'GISS0001' # cspell: disable-line + Message = $missingDatabaseEngineMessage + Category = 'InvalidOperation' + ErrorId = 'GISS0001' # cspell: disable-line TargetObject = $Version } @@ -66,19 +51,8 @@ function Get-SqlDscDatabaseEngineSetting } else { - $masterDataServicesSettings1 = [InstalledComponentSetting]::Parse($mdsCoreFeatureSettings) - - $getItemPropertyParameters = @{ - Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}0\Master Data Services\Setup' -f $Version.Major - ErrorAction = 'SilentlyContinue' - } - - $mdsSetupSettings = Get-ItemProperty @getItemPropertyParameters - - $masterDataServicesSettings2 = [InstalledComponentSetting]::Parse($mdsSetupSettings) - - $masterDataServicesSettings = $masterDataServicesSettings1 + $masterDataServicesSettings2 + $databaseEngineSettings = [InstalledComponentSetting]::Parse($setupSettings) } - return $masterDataServicesSettings + return $databaseEngineSettings } diff --git a/source/Public/Get-SqlDscInstalledComponent.ps1 b/source/Public/Get-SqlDscInstalledComponent.ps1 index 4ca6c65a0..85403aa2b 100644 --- a/source/Public/Get-SqlDscInstalledComponent.ps1 +++ b/source/Public/Get-SqlDscInstalledComponent.ps1 @@ -59,14 +59,6 @@ function Get-SqlDscInstalledComponent switch ($currentServiceComponent.ServiceType) { - # TODO: Add a Test-command for the path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.SQL2016\ConfigurationState\SQL_Engine_Core_Inst - 'DatabaseEngine' - { - $installedComponent.Feature = 'SQLEngine' - - break - } - # TODO: Add a Test-command for the path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.SQL2022\ConfigurationState\SQL_FullText_Adv '9' { @@ -114,7 +106,7 @@ function Get-SqlDscInstalledComponent Add-Member -MemberType 'NoteProperty' -Name 'InstanceId' -Value ( $currentServiceComponent.ServiceType | Get-InstanceId -InstanceName $currentServiceComponent.InstanceName - ) + ) } $installedComponents += $installedComponent @@ -232,16 +224,28 @@ function Get-SqlDscInstalledComponent foreach ($currentInstance in $installedDatabaseEngineInstance) { + # Look for installed version of Database Engine. + $databaseEngineSettings = Get-SqlDscDatabaseEngineSetting -InstanceId $currentInstance.InstanceId -ErrorAction 'SilentlyContinue' + + if ($databaseEngineSettings) + { + $installedComponents += [PSCustomObject] @{ + Feature = 'SQLENGINE' + InstanceName = $currentInstance.InstanceName + Version = $databaseEngineSettings.Version + } + } + # Looking for installed version for Replication. $isReplicationInstalled = Test-SqlDscIsReplicationInstalled -InstanceId $currentInstance.InstanceId if ($isReplicationInstalled) { $installedComponents += [PSCustomObject] @{ - Feature = 'Replication' + Feature = 'Replication' #Version = $currentInstance.Version InstanceName = $currentInstance.InstanceName - InstanceId = $currentInstance.InstanceId + InstanceId = $currentInstance.InstanceId } } @@ -251,10 +255,10 @@ function Get-SqlDscInstalledComponent if ($isReplicationInstalled) { $installedComponents += [PSCustomObject] @{ - Feature = 'AdvancedAnalytics' + Feature = 'AdvancedAnalytics' #Version = $currentInstance.Version InstanceName = $currentInstance.InstanceName - InstanceId = $currentInstance.InstanceId + InstanceId = $currentInstance.InstanceId } } @@ -263,10 +267,10 @@ function Get-SqlDscInstalledComponent if ($isDataQualityServerInstalled) { $installedComponents += [PSCustomObject] @{ - Feature = 'DQ' + Feature = 'DQ' #Version = $currentInstance.Version InstanceName = $currentInstance.InstanceName - InstanceId = $currentInstance.InstanceId + InstanceId = $currentInstance.InstanceId } } @@ -275,10 +279,10 @@ function Get-SqlDscInstalledComponent if ($isROpenRPackagesInstalled) { $installedComponents += [PSCustomObject] @{ - Feature = 'SQL_INST_MR' + Feature = 'SQL_INST_MR' #Version = $currentInstance.Version InstanceName = $currentInstance.InstanceName - InstanceId = $currentInstance.InstanceId + InstanceId = $currentInstance.InstanceId } } } diff --git a/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 b/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 index 93a4bab9b..3d72f632d 100644 --- a/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 +++ b/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 @@ -38,10 +38,10 @@ function Get-SqlDscMasterDataServicesSetting if (-not $mdsCoreFeatureSettings) { - $missingIntegrationServiceMessage = $script:localizedData.MasterDataServicesSetting_Get_NotInstalled -f $Version.ToString() + $missingMasterDataServicesMessage = $script:localizedData.MasterDataServicesSetting_Get_NotInstalled -f $Version.ToString() $writeErrorParameters = @{ - Message = $missingIntegrationServiceMessage + Message = $missingMasterDataServicesMessage Category = 'InvalidOperation' ErrorId = 'GISS0001' # cspell: disable-line TargetObject = $Version diff --git a/source/Public/Get-SqlDscServiceType.ps1 b/source/Public/Get-SqlDscServiceType.ps1 new file mode 100644 index 000000000..8eadcdd0a --- /dev/null +++ b/source/Public/Get-SqlDscServiceType.ps1 @@ -0,0 +1,54 @@ +<# + .SYNOPSIS + Returns all the registered service types. + + .DESCRIPTION + Returns all the registered service types. + + .OUTPUTS + `[System.Object[]]` + + .EXAMPLE + Get-SqlDscServiceType + + Returns all service types. +#> +function Get-SqlDscServiceType +{ + [CmdletBinding()] + [OutputType([System.Object[]])] + param () + + $registeredServiceTypes = @() + + $registeredServiceType = Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Services' + + foreach ($currentServiceType in $registeredServiceType) + { + $foundServiceType = [PSCustomObject]@{ + DisplayName = $currentServiceType.PSChildName + } + + $properties = $currentServiceType.GetValueNames() + + foreach ($property in $properties) + { + $foundServiceType | + Add-Member -MemberType 'NoteProperty' -Name $property -Value $currentServiceType.GetValue($property) + } + + $managedServiceType = [Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType]::Parse([Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType], $currentServiceType.GetValue('Type')) + + $foundServiceType | + Add-Member -MemberType 'NoteProperty' -Name 'ManagedServiceType' -Value $managedServiceType + + $foundServiceType | + Add-Member -MemberType 'NoteProperty' -Name 'NormalizedServiceType' -Value ( + ConvertFrom-ManagedServiceType -ServiceType $managedServiceType -ErrorAction 'SilentlyContinue' + ) + + $registeredServiceTypes += $foundServiceType + } + + return $registeredServiceTypes +} diff --git a/source/en-US/SqlServerDsc.strings.psd1 b/source/en-US/SqlServerDsc.strings.psd1 index 470a91bff..620f7e318 100644 --- a/source/en-US/SqlServerDsc.strings.psd1 +++ b/source/en-US/SqlServerDsc.strings.psd1 @@ -194,4 +194,7 @@ PreferredModule_ModuleVersionNotFound = No preferred Powershell module with vers ## Get-SqlDscMasterDataServicesSetting MasterDataServicesSetting_Get_NotInstalled = There are no Master Data Services installed with version {0}. + + ## Get-SqlDscDatabaseEngineSetting + DatabaseEngineSetting_Get_NotInstalled = There are no Database Engine installed with version {0}. '@ From f568f52ce2b90f2caf7e23c1d0a06c7d75631420 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Sat, 10 Jun 2023 16:03:29 +0200 Subject: [PATCH 16/16] Modify and add commands --- ...t-SqlDscDatabaseEngineInstalledSetting.ps1 | 61 ++++++++++++++ .../Get-SqlDscDatabaseEngineSetting.ps1 | 58 ------------- .../Public/Get-SqlDscInstalledComponent.ps1 | 12 +-- ...scIntegrationServicesInstalledSetting.ps1} | 4 +- ...DscMasterDataServicesInstalledSetting.ps1} | 4 +- .../Test-SqlDscIsDatabaseEngineInstalled.ps1 | 84 +++++++++++++++++++ ...t-SqlDscIsIntegrationServicesInstalled.ps1 | 2 +- ...st-SqlDscIsMasterDataServicesInstalled.ps1 | 4 +- source/en-US/SqlServerDsc.strings.psd1 | 6 +- 9 files changed, 161 insertions(+), 74 deletions(-) create mode 100644 source/Public/Get-SqlDscDatabaseEngineInstalledSetting.ps1 delete mode 100644 source/Public/Get-SqlDscDatabaseEngineSetting.ps1 rename source/Public/{Get-SqlDscIntegrationServicesSetting.ps1 => Get-SqlDscIntegrationServicesInstalledSetting.ps1} (90%) rename source/Public/{Get-SqlDscMasterDataServicesSetting.ps1 => Get-SqlDscMasterDataServicesInstalledSetting.ps1} (93%) create mode 100644 source/Public/Test-SqlDscIsDatabaseEngineInstalled.ps1 diff --git a/source/Public/Get-SqlDscDatabaseEngineInstalledSetting.ps1 b/source/Public/Get-SqlDscDatabaseEngineInstalledSetting.ps1 new file mode 100644 index 000000000..46e843c80 --- /dev/null +++ b/source/Public/Get-SqlDscDatabaseEngineInstalledSetting.ps1 @@ -0,0 +1,61 @@ +<# + .SYNOPSIS + Returns the database engine settings. + + .DESCRIPTION + Returns the database engine settings. + + .PARAMETER InstanceId + Specifies the instance id on which to check if component is installed. + + .OUTPUTS + `[System.Management.Automation.PSCustomObject]` + + .EXAMPLE + Get-SqlDscDatabaseEngineInstalledSetting -InstanceId 'MSSQL13.SQL2016' + + Returns the settings for the database engine. +#> +function Get-SqlDscDatabaseEngineInstalledSetting +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [System.String] + $InstanceId + ) + + process + { + $databaseEngineSettings = $null + + $getItemPropertyParameters = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\Setup' -f $InstanceId + ErrorAction = 'SilentlyContinue' + } + + $setupSettings = Get-ItemProperty @getItemPropertyParameters + + if (-not $setupSettings) + { + $missingDatabaseEngineMessage = $script:localizedData.DatabaseEngineSetting_Get_NotInstalled -f $Version.ToString() + + $writeErrorParameters = @{ + Message = $missingDatabaseEngineMessage + Category = 'InvalidOperation' + ErrorId = 'GISS0001' # cspell: disable-line + TargetObject = $Version + } + + Write-Error @writeErrorParameters + } + else + { + $databaseEngineSettings = [InstalledComponentSetting]::Parse($setupSettings) + } + + return $databaseEngineSettings + } +} diff --git a/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 b/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 deleted file mode 100644 index 472734ca3..000000000 --- a/source/Public/Get-SqlDscDatabaseEngineSetting.ps1 +++ /dev/null @@ -1,58 +0,0 @@ -<# - .SYNOPSIS - Returns the database engine settings. - - .DESCRIPTION - Returns the database engine settings. - - .PARAMETER InstanceId - Specifies the instance id on which to check if component is installed. - - .OUTPUTS - `[System.Management.Automation.PSCustomObject]` - - .EXAMPLE - Get-SqlDscDatabaseEngineSetting -InstanceId 'MSSQL13.SQL2016' - - Returns the settings for the database engine. -#> -function Get-SqlDscDatabaseEngineSetting -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [Parameter(Mandatory = $true)] - [System.String] - $InstanceId - ) - - $databaseEngineSettings = $null - - $getItemPropertyParameters = @{ - Path = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{0}\Setup' -f $InstanceId - ErrorAction = 'SilentlyContinue' - } - - $setupSettings = Get-ItemProperty @getItemPropertyParameters - - if (-not $setupSettings) - { - $missingDatabaseEngineMessage = $script:localizedData.DatabaseEngineSetting_Get_NotInstalled -f $Version.ToString() - - $writeErrorParameters = @{ - Message = $missingDatabaseEngineMessage - Category = 'InvalidOperation' - ErrorId = 'GISS0001' # cspell: disable-line - TargetObject = $Version - } - - Write-Error @writeErrorParameters - } - else - { - $databaseEngineSettings = [InstalledComponentSetting]::Parse($setupSettings) - } - - return $databaseEngineSettings -} diff --git a/source/Public/Get-SqlDscInstalledComponent.ps1 b/source/Public/Get-SqlDscInstalledComponent.ps1 index 85403aa2b..02b1813e3 100644 --- a/source/Public/Get-SqlDscInstalledComponent.ps1 +++ b/source/Public/Get-SqlDscInstalledComponent.ps1 @@ -120,13 +120,13 @@ function Get-SqlDscInstalledComponent { $databaseLevelVersion = [System.Version] ('{0}.{1}' -f $databaseLevel.Substring(0, 2), $databaseLevel.Substring(2, 1)) - $integrationServicesSettings = Get-SqlDscIntegrationServicesSetting -Version $databaseLevelVersion -ErrorAction 'SilentlyContinue' + $isIntegrationServicesInstalled = Test-SqlDscIsIntegrationServicesInstalled -Version $databaseLevelVersion - if ($integrationServicesSettings) + if ($isIntegrationServicesInstalled) { $installedComponents += [PSCustomObject] @{ Feature = 'IS' - Version = $integrationServicesSettings.Version + Version = $databaseLevelVersion } } @@ -186,13 +186,13 @@ function Get-SqlDscInstalledComponent } # Look for installed version of Master Data Services. - $masterDataServicesSettings = Get-SqlDscMasterDataServicesSetting -Version $databaseLevelVersion -ErrorAction 'SilentlyContinue' + $masterDataServicesSettings = Test-SqlDscIsMasterDataServicesInstalled -Version $databaseLevelVersion if ($masterDataServicesSettings) { $installedComponents += [PSCustomObject] @{ Feature = 'MDS' - Version = $masterDataServicesSettings.Version + Version = $databaseLevelVersion } } @@ -225,7 +225,7 @@ function Get-SqlDscInstalledComponent foreach ($currentInstance in $installedDatabaseEngineInstance) { # Look for installed version of Database Engine. - $databaseEngineSettings = Get-SqlDscDatabaseEngineSetting -InstanceId $currentInstance.InstanceId -ErrorAction 'SilentlyContinue' + $databaseEngineSettings = Get-SqlDscDatabaseEngineInstalledSetting -InstanceId $currentInstance.InstanceId -ErrorAction 'SilentlyContinue' if ($databaseEngineSettings) { diff --git a/source/Public/Get-SqlDscIntegrationServicesSetting.ps1 b/source/Public/Get-SqlDscIntegrationServicesInstalledSetting.ps1 similarity index 90% rename from source/Public/Get-SqlDscIntegrationServicesSetting.ps1 rename to source/Public/Get-SqlDscIntegrationServicesInstalledSetting.ps1 index 96d766e13..4d8e9c26d 100644 --- a/source/Public/Get-SqlDscIntegrationServicesSetting.ps1 +++ b/source/Public/Get-SqlDscIntegrationServicesInstalledSetting.ps1 @@ -12,11 +12,11 @@ `[System.Management.Automation.PSCustomObject]` .EXAMPLE - Get-SqlDscIntegrationServicesSetting -Version ([System.Version] '16.0') + Get-SqlDscIntegrationServicesInstalledSetting -Version ([System.Version] '16.0') Returns the settings for the Integration Services. #> -function Get-SqlDscIntegrationServicesSetting +function Get-SqlDscIntegrationServicesInstalledSetting { [CmdletBinding()] [OutputType([System.Boolean])] diff --git a/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 b/source/Public/Get-SqlDscMasterDataServicesInstalledSetting.ps1 similarity index 93% rename from source/Public/Get-SqlDscMasterDataServicesSetting.ps1 rename to source/Public/Get-SqlDscMasterDataServicesInstalledSetting.ps1 index 3d72f632d..de0872a0f 100644 --- a/source/Public/Get-SqlDscMasterDataServicesSetting.ps1 +++ b/source/Public/Get-SqlDscMasterDataServicesInstalledSetting.ps1 @@ -12,11 +12,11 @@ `[System.Management.Automation.PSCustomObject]` .EXAMPLE - Get-SqlDscIntegrationServicesSetting -Version ([System.Version] '16.0') + Get-SqlDscMasterDataServicesInstalledSetting -Version ([System.Version] '16.0') Returns the settings for the integration services. #> -function Get-SqlDscMasterDataServicesSetting +function Get-SqlDscMasterDataServicesInstalledSetting { [CmdletBinding()] [OutputType([System.Boolean])] diff --git a/source/Public/Test-SqlDscIsDatabaseEngineInstalled.ps1 b/source/Public/Test-SqlDscIsDatabaseEngineInstalled.ps1 new file mode 100644 index 000000000..8d8902349 --- /dev/null +++ b/source/Public/Test-SqlDscIsDatabaseEngineInstalled.ps1 @@ -0,0 +1,84 @@ +<# + .SYNOPSIS + Returns whether the Master Data Services are installed. + + .DESCRIPTION + Returns whether the Master Data Services are installed. + + .PARAMETER Version + Specifies the version for which to check if component is installed. + + .PARAMETER InstanceName + Specifies the instance name on which to check if component is installed. + + .PARAMETER InstanceId + Specifies the instance id on which to check if component is installed. + + .OUTPUTS + [System.Boolean] + + .EXAMPLE + Test-SqlDscIsDatabaseEngineInstalled -Version ([System.Version] '16.0') + + Returns $true if Database Engine with version 16 is installed. + + .NOTES + The parameters are all mutually exclusive. +#> +function Test-SqlDscIsDatabaseEngineInstalled +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [System.Version] + $Version, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceId + ) + + $commandParameter = (Remove-CommonParameter -Hashtable $PSCmdlet.MyInvocation.MyCommand.Parameters).Keys + + foreach ($currentParameterName in $commandParameter) + { + $assertBoundParameterParameters = @{ + BoundParameterList = $PSBoundParameters + MutuallyExclusiveList1 = $currentParameterName + MutuallyExclusiveList2 = @([System.String[]] $commandParameter.Where({ $_ -ne $currentParameterName })) + } + + Assert-BoundParameter @assertBoundParameterParameters + } + + $getSqlDscInstalledInstanceParameters = @{ + ServiceType = 'DatabaseEngine' + } + + $installedInstances = Get-SqlDscInstalledInstance @getSqlDscInstalledInstanceParameters -ErrorAction 'SilentlyContinue' + + $result = $false + + if ($PSBoundParameters.ContainsKey('InstanceId')) + { + $result = $installedInstances.InstanceId -contains $InstanceId + } + elseif ($PSBoundParameters.ContainsKey('InstanceName')) + { + $result = $installedInstances.InstanceName -contains $InstanceName + } + elseif ($PSBoundParameters.ContainsKey('Version')) + { + $result = ($installedInstances.InstanceId | Get-SqlDscDatabaseEngineInstalledSetting).Version.Major -contains $Version.Major + } + + return $result +} diff --git a/source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 b/source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 index d96793846..03e22e631 100644 --- a/source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 +++ b/source/Public/Test-SqlDscIsIntegrationServicesInstalled.ps1 @@ -29,7 +29,7 @@ function Test-SqlDscIsIntegrationServicesInstalled $result = $false - if ((Get-SqlDscIntegrationServicesSetting -Version $Version -ErrorAction 'SilentlyContinue')) + if ((Get-SqlDscIntegrationServicesInstalledSetting -Version $Version -ErrorAction 'SilentlyContinue')) { $result = $true } diff --git a/source/Public/Test-SqlDscIsMasterDataServicesInstalled.ps1 b/source/Public/Test-SqlDscIsMasterDataServicesInstalled.ps1 index adea3d4f5..207842e14 100644 --- a/source/Public/Test-SqlDscIsMasterDataServicesInstalled.ps1 +++ b/source/Public/Test-SqlDscIsMasterDataServicesInstalled.ps1 @@ -12,7 +12,7 @@ [System.Boolean] .EXAMPLE - IsMasterDataServicesInstalled -Version ([System.Version] '16.0') + Test-SqlDscIsMasterDataServicesInstalled -Version ([System.Version] '16.0') Returns $true if Master Data Services are installed. #> @@ -29,7 +29,7 @@ function Test-SqlDscIsMasterDataServicesInstalled $result = $false - if ((Get-SqlDscMasterDataServicesSetting -Version $Version -ErrorAction 'SilentlyContinue')) + if ((Get-SqlDscMasterDataServicesInstalledSetting -Version $Version -ErrorAction 'SilentlyContinue')) { $result = $true } diff --git a/source/en-US/SqlServerDsc.strings.psd1 b/source/en-US/SqlServerDsc.strings.psd1 index 620f7e318..9375d2bfd 100644 --- a/source/en-US/SqlServerDsc.strings.psd1 +++ b/source/en-US/SqlServerDsc.strings.psd1 @@ -189,12 +189,12 @@ PreferredModule_ModuleVersionNotFound = No preferred Powershell module with vers ## Test-IsManagementStudioAdvancedInstalled IsManagementStudioAdvancedInstalled_Test_NotSupportedVersion = SQL Server Management Studio Advanced is not supported for the provided version. - ## Get-SqlDscIntegrationServicesSetting + ## Get-SqlDscIntegrationServicesInstalledSetting IntegrationServicesSetting_Get_NotInstalled = There are no Integration Services installed with version {0}. - ## Get-SqlDscMasterDataServicesSetting + ## Get-SqlDscMasterDataServicesInstalledSetting MasterDataServicesSetting_Get_NotInstalled = There are no Master Data Services installed with version {0}. - ## Get-SqlDscDatabaseEngineSetting + ## Get-SqlDscDatabaseEngineInstalledSetting DatabaseEngineSetting_Get_NotInstalled = There are no Database Engine installed with version {0}. '@