From 69ebf57bce4c293590930bbcee06d31ae5ab2a53 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 26 Nov 2020 18:51:26 +0100 Subject: [PATCH 01/28] Initial version of new resource SqlTraceFlag --- CHANGELOG.md | 5 + .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 437 ++++++++++++ .../DSC_SqlTraceFlag.schema.mof | 11 + .../DSCResources/DSC_SqlTraceFlag/README.md | 16 + .../en-US/DSC_SqlTraceFlag.strings.psd1 | 10 + .../SqlTraceFlag/1-SetTraceFlags.ps1 | 30 + .../2-SetTraceFlagsIncludeExclude.ps1 | 31 + .../SqlTraceFlag/3-RemoveTraceFlags.ps1 | 29 + tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 644 ++++++++++++++++++ tests/Unit/Stubs/SMO.cs | 14 + 10 files changed, 1227 insertions(+) create mode 100644 source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 create mode 100644 source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof create mode 100644 source/DSCResources/DSC_SqlTraceFlag/README.md create mode 100644 source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 create mode 100644 source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 create mode 100644 source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 create mode 100644 source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 create mode 100644 tests/Unit/DSC_SqlTraceFlag.Tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index a86094dc9..20763d944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- SqlTraceFlag + - Added new resource to set or changes TraceFlags on Sql Server. + - This resource is based on zuldans code but with SqlServerDsc integrated SMO + - Credits:(https://github.com/Zuldan/cSQLServerTraceFlag) + - Added a lot of test scripts to validated the code. - WaitForAG - BREAKING CHANGE: Fix for issue ([issue #1569](https://github.com/dsccommunity/SqlServerDsc/issues/1569)) The resource now waits for the Availability Group to become Available. diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 new file mode 100644 index 000000000..d6a063d27 --- /dev/null +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -0,0 +1,437 @@ +$script:sqlServerDscHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\SqlServerDsc.Common' +$script:resourceHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' + +Import-Module -Name $script:sqlServerDscHelperModulePath +Import-Module -Name $script:resourceHelperModulePath + +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' + +<# + .SYNOPSIS + This function gets the actual sql server TraceFlags. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName + ) + + Write-Verbose -Message ( + $script:localizedData.GetConfiguration -f $Name + ) + + $SQLManagement = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $ServerName + + $ServiceNames = Get-SqlServiceName -InstanceName $InstanceName + + if($SQLManagement) + { + $WMIService = $SQLManagement.Services | + Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLEngineName } + + if ($WMIService) + { + $ActualTraceFlags = $WMIService.StartupParameters.Split(';') | + Where-Object -FilterScript { $PSItem -like '-T*' } | + ForEach-Object { + $PSItem.TrimStart('-T') + } + } + else + { + $errorMessage = $script:localizedData.NotConnectedToWMI -f $InstanceName, $ServerName + New-InvalidOperationException -Message $errorMessage + } + } + else + { + $errorMessage = $script:localizedData.NotConnectedToComputerManagement -f $ServerName + New-InvalidOperationException -Message $errorMessage + } + + return @{ + ServerName = $ServerName + InstanceName = $InstanceName + ActualTraceFlags = $ActualTraceFlags + } +} + +<# + .SYNOPSIS + This function sets the sql server TraceFlags. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER TraceFlags + The TraceFlags the SQL server engine startup parameters should contain. + This parameter can not be used together with TraceFlagsToInclude and TraceFlagsToExclude. + + .PARAMETER TraceFlagsToInclude + The TraceFlags the SQL server engine startup parameters should include. + This parameter can not be used together with TraceFlags. + + .PARAMETER TraceFlagsToExclude + The TraceFlags the SQL server engine startup parameters should exclude. + This parameter can not be used together with TraceFlags. + + .PARAMETER Ensure + When set to 'Present', the TraceFlags will be created/added. + When set to 'Absent', all the TraceFlags will be removed. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter()] + [System.Uint32[]] + $TraceFlags, + + [Parameter()] + [System.Uint32[]] + $TraceFlagsToInclude, + + [Parameter()] + [System.Uint32[]] + $TraceFlagsToExclude, + + [Parameter()] + [System.Boolean] + $RestartInstance = $false, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [ValidateNotNullOrEmpty()] + [System.String] + $Ensure = 'Present' + ) + + Write-Verbose -Message ( + $script:localizedData.SetConfiguration -f $Name, $RetryCount, ($RetryIntervalSec * $RetryCount) + ) + + $assertBoundParameterParameters = @{ + BoundParameterList = $PSBoundParameters + MutuallyExclusiveList1 = @( + 'TraceFlags' + ) + MutuallyExclusiveList2 = @( + 'TraceFlagsToInclude', 'TraceFlagsToExclude' + ) + } + + Assert-BoundParameter @assertBoundParameterParameters + + $getTargetResourceParameters = @{ + ServerName = $ServerName + InstanceName = $InstanceName + } + + if ($Ensure -eq 'Present') + { + $wishTraceFlags = [System.Collections.ArrayList]::new() + + if ($TraceFlags) + { + $wishTraceFlags.AddRange($TraceFlags) + } + else + { + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + $wishTraceFlags.AddRange($getTargetResourceResult.ActualTraceFlags) + + if ($TraceFlagsToInclude) + { + foreach ($traceFlagToInclude in $TraceFlagsToInclude) + { + if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) + { + $wishTraceFlags.Add($traceFlagToInclude) + } + } + } + + if ($TraceFlagsToExclude) + { + foreach ($traceFlagToExclude in $TraceFlagsToExclude) + { + if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) + { + $wishTraceFlags.Remove([string]$traceFlagToExclude) + } + } + } + } + + # Add '-T' dash to flag + $traceFlagList = $wishTraceFlags | ForEach-Object { + "-T$PSItem" + } + } + else + { + #when ensure <> present, TraceFlagList should be empty, + #this wil remove all traceFlags from the startupParameters + $traceFlagList = $null + } + + $ServiceNames = Get-SqlServiceName -InstanceName $InstanceName + + $SQLManagement = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $ServerName + + if ($SQLManagement) + { + $WMIService = $SQLManagement.Services | + Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLEngineName } + + if($WMIService) + { + # Extract startup parameters + [System.Collections.ArrayList]$parameterList = $wmiService.StartupParameters.Split(';') + + # Removing flags that are not wanted + foreach ($parameter in $wmiService.StartupParameters.Split(';')) { + if ($parameter -like '-T*' -and $parameter -notin $traceFlagList) { + $parameterList.Remove($parameter) | Out-Null + } + } + + # Add missing flags + foreach ($Flag in $traceFlagList) { + if ($Flag -notin $parameterList) { + $parameterList.Add($Flag) | Out-Null + } + } + + # Merge flags back into startup parameters + $wmiService.StartupParameters = $parameterList -join ';' + $wmiService.Alter() + + if ($RestartInstance) + { + #Get the current status of the sql agent. After restart of the instance, the status of the agent should be the same. + $AgentServiceStatus = ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).ServiceState + + $wmiService.Stop() + Start-Sleep -Seconds 10 + $wmiService.Start() + + if ($AgentServiceStatus -ne 'Stopped') + { + ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).Start() + } + } + } + } +} + +<# + .SYNOPSIS + This function tests the sql server TraceFlags. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER TraceFlags + The TraceFlags the SQL server engine startup parameters should contain. + This parameter can not be used together with TraceFlagsToInclude and TraceFlagsToExclude. + + .PARAMETER TraceFlagsToInclude + The TraceFlags the SQL server engine startup parameters should include. + This parameter can not be used together with TraceFlags. + + .PARAMETER TraceFlagsToExclude + The TraceFlags the SQL server engine startup parameters should exclude. + This parameter can not be used together with TraceFlags. + + .PARAMETER Ensure + When set to 'Present', the TraceFlags will be created/added. + When set to 'Absent', all TraceFlags will be removed. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter()] + [System.Uint32[]] + $TraceFlags, + + [Parameter()] + [System.Uint32[]] + $TraceFlagsToInclude, + + [Parameter()] + [System.Uint32[]] + $TraceFlagsToExclude, + + [Parameter()] + [System.Boolean] + $RestartInstance = $false, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [ValidateNotNullOrEmpty()] + [System.String] + $Ensure = 'Present' + ) + + Write-Verbose -Message ( + $script:localizedData.TestConfiguration -f $Name + ) + + $assertBoundParameterParameters = @{ + BoundParameterList = $PSBoundParameters + MutuallyExclusiveList1 = @( + 'TraceFlags' + ) + MutuallyExclusiveList2 = @( + 'TraceFlagsToInclude', 'TraceFlagsToExclude' + ) + } + + Assert-BoundParameter @assertBoundParameterParameters + + $getTargetResourceParameters = @{ + ServerName = $ServerName + InstanceName = $InstanceName + } + + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + + $isInDesiredState = $true + if ($Ensure -eq 'Present') + { + if ($TraceFlags) + { + if ( $null -ne (Compare-Object -ReferenceObject $getTargetResourceResult.ActualTraceFlags -DifferenceObject $TraceFlags)) + { + Write-Verbose -Message ( + $script:localizedData.DesiredTraceFlagNotPresent ` + -f $ServerRoleName + ) + + $isInDesiredState = $false + } + } + else + { + if ($TraceFlagsToInclude) + { + foreach ($traceFlagToInclude in $TraceFlagsToInclude) + { + if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) + { + Write-Verbose -Message ( + $script:localizedData.TraceFlagNotPresent ` + -f $traceFlagToInclude + ) + + $isInDesiredState = $false + } + } + } + + if ($TraceFlagsToExclude) + { + foreach ($traceFlagToExclude in $TraceFlagsToExclude) + { + if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) + { + Write-Verbose -Message ( + $script:localizedData.TraceFlagPresent ` + -f $traceFlagToExclude + ) + + $isInDesiredState = $false + } + } + } + } + } + else + { + if ($getTargetResourceResult.ActualTraceFlags.Count -gt 0) + { + $isInDesiredState = $false + } + } + return $isInDesiredState +} + +Export-ModuleMember -Function *-TargetResource + + +<# + .SYNOPSIS + This function returns the serviceNames of an sql instance. +#> +Function Get-SqlServiceName +{ + Param + ( + [Parameter(Position = 1)] + [System.String] + $InstanceName = 'MSSQLServer' + ) + + if ($InstanceName -eq 'MSSQLSERVER') + { + $SQLEngineName = 'MSSQLSERVER' + $SQLAgentName = 'SQLSERVERAGENT' + } + else + { + $SQLEngineName = 'MSSQL${0}' -f $InstanceName + $SQLAgentName = 'SQLAgent${0}' -f $InstanceName + } + + return @{ + SQLEngineName = $SQLEngineName + SQLAgentName = $SQLAgentName + } +} \ No newline at end of file diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof new file mode 100644 index 000000000..730485cc4 --- /dev/null +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -0,0 +1,11 @@ +[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerDatabaseEngineStartupOption")] +class DSC_SqlTraceFlag : OMI_BaseResource +{ + [Key, Description("The host name of the _SQL Server_ to be configured. Default value is `$env:COMPUTERNAME`.")] String ServerName; + [Key, Description("The name of the _SQL Server_ instance to be configured.")] String InstanceName; + [Write, Description("An array of trace flags that startup options should have")] Uint32[] TraceFlags; + [Write, Description("An array of trace flags to be added to the existing trace flags")] Uint32[] TraceFlagsToInclude; + [Write, Description("An array of trace flags to be removed from the existing trace flags")] Uint32[] TraceFlagsToExclude; + [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartInstance; + [Write, Description("When set to `'Present'`, the TraceFlags will be set. When set to `'Absent'`, All TraceFlags will be Removed. Default value is `'Present'`."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; +}; \ No newline at end of file diff --git a/source/DSCResources/DSC_SqlTraceFlag/README.md b/source/DSCResources/DSC_SqlTraceFlag/README.md new file mode 100644 index 000000000..fc54fa45b --- /dev/null +++ b/source/DSCResources/DSC_SqlTraceFlag/README.md @@ -0,0 +1,16 @@ +# Description + +The `SqlTraceFlag` DSC resource will set TraceFlags on a sql server engine. + +## Requirements + +* Target machine must be running Windows Server 2012 or later. +* Target machine must be running SQL Server Database Engine 2012 or later. + +## Security Requirements + +* Target machine must have admin access to the Windows Server. + +## 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+SqlTraceFlag). diff --git a/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 b/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 new file mode 100644 index 000000000..a45a9a305 --- /dev/null +++ b/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 @@ -0,0 +1,10 @@ +ConvertFrom-StringData @' + GetConfiguration = Get the current TraceFlags that are set. + SetConfiguration = Set the TraceFlags that are needed. + TestConfiguration = Determines the current state of the TraceFlags Compared to the desired TraceFlags '{0}'. + NotConnectedToComputerManagement = Was unable to connect to ComputerManagement '{0}'. + NotConnectedToWMI = Was unable to connect to WMI information '{0}' in '{1}'. + DesiredTraceFlagNotPresent = TraceFlag does not match the actual TraceFlags on the instance. + TraceFlagPresent = traceflag {0} is present. + TraceFlagNotPresent = traceflag {0} is not present. +'@ diff --git a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 new file mode 100644 index 000000000..d45a32da4 --- /dev/null +++ b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 @@ -0,0 +1,30 @@ +<# + .DESCRIPTION + This example shows how to set TraceFlags where all existing + TraceFlags are overwriten by these +#> +Configuration Example +{ + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost + { + SqlTraceFlag 'Set_SqlTraceFlags' + { + ServerName = 'sqltest.company.local' + InstanceName = 'DSC' + TraceFlags = 834, 1117, 1118, 2371, 3226 + RestartService = $true + Ensure = 'Present' + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} diff --git a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 new file mode 100644 index 000000000..0bd9d9fa6 --- /dev/null +++ b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 @@ -0,0 +1,31 @@ +<# + .DESCRIPTION + This example shows how to set TraceFlags where all existing + TraceFlags are overwriten by these +#> +Configuration Example +{ + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost + { + SqlTraceFlag 'Set_SqlTraceFlagsIncludeExclude' + { + ServerName = 'sqltest.company.local' + InstanceName = 'DSC' + TraceFlagsToInclude = 834, 1117, 1118, 2371, 3226 + TraceFlagsToExclude = 1112 + RestartService = $true + Ensure = 'Present' + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} diff --git a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 new file mode 100644 index 000000000..47f29009e --- /dev/null +++ b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 @@ -0,0 +1,29 @@ +<# + .DESCRIPTION + This example shows how to set TraceFlags where all existing + TraceFlags are overwriten by these +#> +Configuration Example +{ + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost + { + SqlTraceFlag 'Set_SqlTraceFlagsRemove' + { + ServerName = 'sqltest.company.local' + InstanceName = 'DSC' + RestartService = $true + Ensure = 'Absent' + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 new file mode 100644 index 000000000..f079e13cc --- /dev/null +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -0,0 +1,644 @@ +<# + .SYNOPSIS + Automated unit test for DSC_SqlTraceFlag DSC resource. + +#> + +Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\TestHelpers\CommonTestHelper.psm1') + +if (-not (Test-BuildCategory -Type 'Unit')) +{ + return +} + +$script:dscModuleName = 'SqlServerDsc' +$script:dscResourceName = 'DSC_SqlTraceFlag' + +function Invoke-TestSetup +{ + try + { + Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + } + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Unit' +} + +function Invoke-TestCleanup +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} + +Invoke-TestSetup + +Write-Host (Get-Module pester).Version + +try +{ + InModuleScope $script:dscResourceName { + $mockServerName = 'TestServer' + $mockFakeServerName = 'FakeServer' + $mockInstanceName1 = 'MSSQLSERVER' + $mockInstanceName1Agent = 'SQLSERVERAGENT' + $mockInstanceName2 = 'INST00' + $mockInstanceName2Agent = 'SQLAgent$INST00' + $mockInstanceName3 = 'INST01' + $mockInstanceName3Agent = 'SQLAgent$INST01' + + $mockInvalidOperationForAlterMethod = $false + $mockInvalidOperationForStopMethod = $false + $mockInvalidOperationForStartMethod = $false + + $mockServerInstances = [System.Collections.ArrayList]::new() + $mockServerInstances.Add($mockInstanceName1) | Out-Null + $mockServerInstances.Add($mockInstanceName2) | Out-Null + + + + + #The Trailing spaces in this here string are ment to be there. Do not remove! + $mockStartupParametersInstance1 = @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802 +"@ + $mockStartupParametersInstance2 = @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf +"@ + + # Default parameters that are used for the It-blocks + $mockDefaultParameters1 = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockServerName + } + + $mockInst00Parameters = @{ + InstanceName = $mockInstanceName2 + ServerName = $mockServerName + } + + $mockInst01Parameters = @{ + InstanceName = $mockInstanceName3 + ServerName = $mockServerName + } + + $mockNonExistServerParameters = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockFakeServerName + } + + $mockNewObject_ParameterFilter_RealServerName = { + $ServerName -eq $mockServerName + } + + $mockNewObject_ParameterFilter_FakeServerName = { + $ServerName -eq $mockFakeServerName + } + + $script:mockMethodAlterRan = $false + $script:mockMethodStopRan = $false + $script:mockMethodStartRan = $false + $script:mockMethodAlterValue = '' + + #region Function mocks + $mockSmoWmiManagedComputer = { + $mockServerObjectHashtable = @{ + State = "Existing" + Name = $mockServerName + ServerInstances = $mockServerInstances + } + + class service + { + [string]$Name + [string]$ServiceState + [string]$StartupParameters + } + + $Services = [System.Collections.ArrayList]::new() + + $service1 = [service]::new() + $service1.Name = $mockInstanceName1 + $service1.ServiceState = "Running" + $service1.StartupParameters = $mockStartupParametersInstance1 + + $Services.Add($service1) | Out-Null + + $service2 = [service]::new() + $service2.Name = $mockInstanceName1Agent + $service2.ServiceState = "Running" + $service2.StartupParameters = "" + + $Services.Add($service2) | Out-Null + + $service3 = [service]::new() + $service3.Name = 'MSSQL${0}' -f $mockInstanceName2 + $service3.ServiceState = "Running" + $service3.StartupParameters = $mockStartupParametersInstance2 + + $Services.Add($service3) | Out-Null + + $service4 = [service]::new() + $service4.Name = 'SQLAgent${0}' -f $mockInstanceName2Agent + $service4.ServiceState = "Stopped" + $service4.StartupParameters = "" + + $Services.Add($service4) | Out-Null + + $ServerServices = [System.Collections.ArrayList]::new() + + foreach ($mockService in $Services) + { + $mockService | Add-Member -MemberType ScriptMethod -Name Alter -Value { + $script:mockMethodAlterRan = $true + $script:mockMethodAlterValue = $this.StartupParameters + } -PassThru | + Add-Member -MemberType ScriptMethod -Name Stop -Value { + $script:mockMethodStopRan = $true + } -PassThru | + Add-Member -MemberType ScriptMethod -Name Start -Value { + $script:mockMethodStartRan = $true + } + + $ServerServices.Add( $mockService) | Out-Null + } + + $mockServerObjectHashtable += @{ + Services = $ServerServices + } + $mockServerObject = [PSCustomObject]$mockServerObjectHashtable + + return @($mockServerObject) + } + + Describe "DSC_SqlTraceFlag\Get-TargetResource" -Tag 'Get' { + BeforeAll { + Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -ParameterFilter $mockNewObject_ParameterFilter_RealServerName -Verifiable + } + + Context 'For the default instance' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + + $result = Get-TargetResource @testParameters + } + It 'Should return a ManagedComputer object with the correct servername' { + $result.ServerName | Should -Be $mockServerName + } + It 'Should return a ManagedComputer object with the correct InstanceName' { + $result.InstanceName | Should -Be $mockInstanceName1 + } + It 'Should return a ManagedComputer object with the correct TraceFlags' { + $result.ActualTraceFlags | Should -Be '3226' ,'1802' + } + It 'Should return a ManagedComputer object with the correct number of TraceFlags' { + $result.ActualTraceFlags.Count | Should -Be 2 + } + It 'Should not throw' { + {Get-TargetResource @testParameters} | Should -Not -Throw + } + } + + Context 'For a named instance' { + BeforeAll { + $testParameters = $mockInst00Parameters + + $result = Get-TargetResource @testParameters + } + It 'Should return a ManagedComputer object with the correct servername' { + $result.ServerName | Should -Be $mockServerName + } + It 'Should return a ManagedComputer object with the correct InstanceName' { + $result.InstanceName | Should -Be $mockInstanceName2 + } + It 'Should return a ManagedComputer object with the correct TraceFlags' { + $result.ActualTraceFlags | Should -BeNullOrEmpty + } + It 'Should return a ManagedComputer object with the correct number of TraceFlags' { + $result.ActualTraceFlags.Count | Should -Be 0 + } + It 'Should not throw' { + {Get-TargetResource @testParameters} | Should -Not -Throw + } + } + + Context 'For a nonexist instance' { + BeforeAll { + $testParameters = $mockInst01Parameters + } + It 'Should throw for incorect parameters' { + {Get-TargetResource @testParameters} | + Should -Throw -ExpectedMessage ("Was unable to connect to WMI information '{0}' in '{1}'." -f $mockInstanceName3, $mockServerName) + } + } + + Context 'For a nonexist server' { + BeforeAll { + $testParameters = $mockNonExistServerParameters + Mock -CommandName New-Object -MockWith { + return $null + } -ParameterFilter $mockNewObject_ParameterFilter_FakeServerName -Verifiable + } + It 'Should throw for incorect parameters' { + {Get-TargetResource @testParameters} | + Should -Throw -ExpectedMessage ("Was unable to connect to ComputerManagement '{0}'." -f $mockFakeServerName) + } + } + } + + Describe "DSC_SqlTraceFlag\Test-TargetResource" -Tag 'Test' { + BeforeAll { + #Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable + Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable + } + + Context 'When the system is not in the desired state and ensure is set to Absent' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Absent' + } + + $result = Test-TargetResource @testParameters + } + + It 'Should return false when Traceflags on the instance exist' { + $result | Should -BeFalse + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + Context 'When the system is in the desired state and ensure is set to Absent' { + BeforeAll { + $testParameters = $mockInst00Parameters + $testParameters += @{ + Ensure = 'Absent' + } + + $result = Test-TargetResource @testParameters + } + + It 'Should return true when no Traceflags on the instance exist' { + $result | Should -BeTrue + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlags = '3228' + } + + $result = Test-TargetResource @testParameters + } + + It 'Should return false when Traceflags do not match the actual TraceFlags' { + $result | Should -BeFalse + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude are not in the actual TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlagsToInclude = '3228' + } + + $result = Test-TargetResource @testParameters + } + + It 'Should return false when TraceflagsToInclude are not in the actual TraceFlags' { + $result | Should -BeFalse + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + Context 'When the system is in the desired state and ensure is set to Present and `$TraceFlagsToInclude are in the actual TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlagsToInclude = '3226' + } + + $result = Test-TargetResource @testParameters + } + + It 'Should return false when TraceflagsToInclude are in the actual TraceFlags' { + $result | Should -BeTrue + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToExclude are in the actual TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlagsToExclude = '3226' + } + + $result = Test-TargetResource @testParameters + } + + It 'Should return false when TraceflagsToExclude are in the actual TraceFlags' { + $result | Should -BeFalse + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + Context 'When the system is in the desired state and ensure is set to Present and `$TraceFlagsToExclude are not in the actual TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlagsToExclude = '3228' + } + + $result = Test-TargetResource @testParameters + } + + It 'Should return true when TraceflagsToExclude are not in the actual TraceFlags' { + $result | Should -BeTrue + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + + Context 'When both the parameters TraceFlags and TraceFlagsToInclude are assigned a value.' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlags = '3228' + TraceFlagsToInclude = '3228' + } + } + + It 'Should throw the correct error' { + { Test-TargetResource @testParameters } | Should -Throw '(DRC0010)' + } + + It 'Should not be executed' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 0 -Scope Context + } + } + + Context 'When both the parameters TraceFlags and TraceFlagsToExclude are assigned a value.' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlags = '3228' + TraceFlagsToExclude = '3228' + } + } + + It 'Should throw the correct error' { + { Test-TargetResource @testParameters } | Should -Throw '(DRC0010)' + } + + It 'Should not be executed' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 0 -Scope Context + } + } + + } + +#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 259 $errorMessage = $script:localizedData... +#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 260 New-InvalidOperationException -Messag... +#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 265 $errorMessage = $script:localizedData... +#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 266 New-InvalidOperationException -Messag... + + + Describe "DSC_SqlTraceFlag\Set-TargetResource" -Tag 'Set' { + BeforeAll { + #Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable + Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable + } + + Context 'When the system is not in the desired state and ensure is set to Absent' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Absent' + } + } + + It 'Should not throw when calling the alter method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodStopRan | Should -BeFalse + $script:mockMethodStartRan | Should -BeFalse + $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf +"@ + + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It + } + + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlags = '3228' + } + } + + It 'Should not throw when calling the alter method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodStopRan | Should -BeFalse + $script:mockMethodStartRan | Should -BeFalse + $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 +"@ + + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude is not in TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlagsToInclude = '3228' + } + } + + It 'Should not throw when calling the alter method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodStopRan | Should -BeFalse + $script:mockMethodStartRan | Should -BeFalse + $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802;-T3228 +"@ + + Assert-MockCalled -CommandName New-Object -Exactly -Times 2 -Scope It + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToExclude is in TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlagsToExclude = '1802' + } + } + + It 'Should not throw when calling the alter method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodStopRan | Should -BeFalse + $script:mockMethodStartRan | Should -BeFalse + $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226 +"@ + + Assert-MockCalled -CommandName New-Object -Exactly -Times 2 -Scope It + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlags = '3228' + RestartInstance = $true + } + } + + It 'Should not throw when calling the restart method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodStopRan | Should -BeTrue + $script:mockMethodStartRan | Should -BeTrue + $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 +"@ + + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It + } + } + + Context 'When both the parameters TraceFlags and TraceFlagsToInclude are assigned a value.' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlags = '3228' + TraceFlagsToInclude = '3228' + } + } + + It 'Should throw the correct error' { + { Set-TargetResource @testParameters} | Should -Throw '(DRC0010)' + } + + It 'Should not be executed' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 0 -Scope Context + } + } + + Context 'When both the parameters TraceFlags and TraceFlagsToExclude are assigned a value.' { + BeforeAll { + $testParameters = $mockDefaultParameters1 + $testParameters += @{ + Ensure = 'Present' + TraceFlags = '3228' + TraceFlagsToExclude = '3228' + } + } + + It 'Should throw the correct error' { + { Set-TargetResource @testParameters } | Should -Throw '(DRC0010)' + } + + It 'Should not be executed' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 0 -Scope Context + } + } + + Context 'For a nonexist instance' { + BeforeAll { + $testParameters = $mockInst01Parameters + } + It 'Should throw for incorect parameters' { + {Set-TargetResource @testParameters} | + Should -Throw -ExpectedMessage ("Was unable to connect to WMI information '{0}' in '{1}'." -f $mockInstanceName3, $mockServerName) + } + } + + Context 'For a nonexist server' { + BeforeAll { + $testParameters = $mockNonExistServerParameters + Mock -CommandName New-Object -MockWith { + return $null + } -ParameterFilter $mockNewObject_ParameterFilter_FakeServerName -Verifiable + } + It 'Should throw for incorect parameters' { + {Set-TargetResource @testParameters} | + Should -Throw -ExpectedMessage ("Was unable to connect to ComputerManagement '{0}'." -f $mockFakeServerName) + } + } + } + + } +} +finally +{ + Invoke-TestCleanup +} \ No newline at end of file diff --git a/tests/Unit/Stubs/SMO.cs b/tests/Unit/Stubs/SMO.cs index d6149f15d..470b5c8e3 100644 --- a/tests/Unit/Stubs/SMO.cs +++ b/tests/Unit/Stubs/SMO.cs @@ -969,4 +969,18 @@ public enum ManagedServiceType } #endregion + + #region Public Classes + + // TypeName: Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType + // Used by: + // DSC_SqlTraceFlag.Tests.ps1 + public class ManagedComputer + { + public string Name; + public string State; + public ArrayList ServerInstances; + public ArrayList Services; + } + #endregion } From e1cc2da0b67362f3ce7fc214cd83fa3a5abf2dc3 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 26 Nov 2020 19:03:18 +0100 Subject: [PATCH 02/28] small change to trigger pipline --- source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 1 - 1 file changed, 1 deletion(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index d6a063d27..f967a0123 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -405,7 +405,6 @@ function Test-TargetResource Export-ModuleMember -Function *-TargetResource - <# .SYNOPSIS This function returns the serviceNames of an sql instance. From f7cab74159181b1ea80d29c3d10c64c693121cf2 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 26 Nov 2020 19:51:47 +0100 Subject: [PATCH 03/28] Change Schema friendliname --- .../DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof index 730485cc4..2f82e5e8e 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -1,4 +1,4 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerDatabaseEngineStartupOption")] +[ClassVersion("1.0.0.0"), FriendlyName("SqlTraceFlag")] class DSC_SqlTraceFlag : OMI_BaseResource { [Key, Description("The host name of the _SQL Server_ to be configured. Default value is `$env:COMPUTERNAME`.")] String ServerName; @@ -8,4 +8,4 @@ class DSC_SqlTraceFlag : OMI_BaseResource [Write, Description("An array of trace flags to be removed from the existing trace flags")] Uint32[] TraceFlagsToExclude; [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartInstance; [Write, Description("When set to `'Present'`, the TraceFlags will be set. When set to `'Absent'`, All TraceFlags will be Removed. Default value is `'Present'`."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; -}; \ No newline at end of file +}; From 105dd1b93b692c327c3bfc768a70797bc7ff8fb1 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 26 Nov 2020 23:42:05 +0100 Subject: [PATCH 04/28] schema change --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof | 8 ++++---- .../Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof index 2f82e5e8e..b7fa465d4 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -1,11 +1,11 @@ [ClassVersion("1.0.0.0"), FriendlyName("SqlTraceFlag")] class DSC_SqlTraceFlag : OMI_BaseResource { - [Key, Description("The host name of the _SQL Server_ to be configured. Default value is `$env:COMPUTERNAME`.")] String ServerName; + [Write, Description("The host name of the _SQL Server_ to be configured. Default value is `$env:COMPUTERNAME`.")] String ServerName; [Key, Description("The name of the _SQL Server_ instance to be configured.")] String InstanceName; - [Write, Description("An array of trace flags that startup options should have")] Uint32[] TraceFlags; - [Write, Description("An array of trace flags to be added to the existing trace flags")] Uint32[] TraceFlagsToInclude; - [Write, Description("An array of trace flags to be removed from the existing trace flags")] Uint32[] TraceFlagsToExclude; + [Write, Description("An array of trace flags that startup options should have")] Uint32 TraceFlags[]; + [Write, Description("An array of trace flags to be added to the existing trace flags")] Uint32 TraceFlagsToInclude[]; + [Write, Description("An array of trace flags to be removed from the existing trace flags")] Uint32 TraceFlagsToExclude[]; [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartInstance; [Write, Description("When set to `'Present'`, the TraceFlags will be set. When set to `'Absent'`, All TraceFlags will be Removed. Default value is `'Present'`."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; }; diff --git a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 index 47f29009e..c74d2cabb 100644 --- a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 @@ -16,7 +16,7 @@ Configuration Example node localhost { - SqlTraceFlag 'Set_SqlTraceFlagsRemove' + SqlTraceFlag 'Remove_SqlTraceFlags' { ServerName = 'sqltest.company.local' InstanceName = 'DSC' From c5346a2872b729243553e540a259b80bf3687487 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 26 Nov 2020 23:58:22 +0100 Subject: [PATCH 05/28] some HQRM fixes --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 22 +++++++++++-------- .../SqlTraceFlag/1-SetTraceFlags.ps1 | 2 +- .../2-SetTraceFlagsIncludeExclude.ps1 | 2 +- .../SqlTraceFlag/3-RemoveTraceFlags.ps1 | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index f967a0123..66f8c3253 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -40,7 +40,7 @@ function Get-TargetResource $ServiceNames = Get-SqlServiceName -InstanceName $InstanceName - if($SQLManagement) + if ($SQLManagement) { $WMIService = $SQLManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLEngineName } @@ -214,21 +214,25 @@ function Set-TargetResource $WMIService = $SQLManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLEngineName } - if($WMIService) + if ($WMIService) { # Extract startup parameters [System.Collections.ArrayList]$parameterList = $wmiService.StartupParameters.Split(';') # Removing flags that are not wanted - foreach ($parameter in $wmiService.StartupParameters.Split(';')) { - if ($parameter -like '-T*' -and $parameter -notin $traceFlagList) { + foreach ($parameter in $wmiService.StartupParameters.Split(';')) + { + if ($parameter -like '-T*' -and $parameter -notin $traceFlagList) + { $parameterList.Remove($parameter) | Out-Null } } # Add missing flags - foreach ($Flag in $traceFlagList) { - if ($Flag -notin $parameterList) { + foreach ($Flag in $traceFlagList) + { + if ($Flag -notin $parameterList) + { $parameterList.Add($Flag) | Out-Null } } @@ -409,9 +413,9 @@ Export-ModuleMember -Function *-TargetResource .SYNOPSIS This function returns the serviceNames of an sql instance. #> -Function Get-SqlServiceName +function Get-SqlServiceName { - Param + param ( [Parameter(Position = 1)] [System.String] @@ -433,4 +437,4 @@ Function Get-SqlServiceName SQLEngineName = $SQLEngineName SQLAgentName = $SQLAgentName } -} \ No newline at end of file +} diff --git a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 index d45a32da4..318282b57 100644 --- a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 @@ -21,7 +21,7 @@ Configuration Example ServerName = 'sqltest.company.local' InstanceName = 'DSC' TraceFlags = 834, 1117, 1118, 2371, 3226 - RestartService = $true + RestartInstance = $true Ensure = 'Present' PsDscRunAsCredential = $SqlAdministratorCredential diff --git a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 index 0bd9d9fa6..bc72653a5 100644 --- a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 @@ -22,7 +22,7 @@ Configuration Example InstanceName = 'DSC' TraceFlagsToInclude = 834, 1117, 1118, 2371, 3226 TraceFlagsToExclude = 1112 - RestartService = $true + RestartInstance = $true Ensure = 'Present' PsDscRunAsCredential = $SqlAdministratorCredential diff --git a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 index c74d2cabb..3b099247b 100644 --- a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 @@ -20,7 +20,7 @@ Configuration Example { ServerName = 'sqltest.company.local' InstanceName = 'DSC' - RestartService = $true + RestartInstance = $true Ensure = 'Absent' PsDscRunAsCredential = $SqlAdministratorCredential From 8125732ee48738f476910afd9b05ead422531c71 Mon Sep 17 00:00:00 2001 From: Fiander Date: Fri, 27 Nov 2020 16:49:42 +0100 Subject: [PATCH 06/28] first batch of fixes --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 52 +++++++++++-------- tests/Unit/Stubs/SMO.cs | 2 +- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 66f8c3253..580afab88 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -66,9 +66,12 @@ function Get-TargetResource } return @{ - ServerName = $ServerName - InstanceName = $InstanceName - ActualTraceFlags = $ActualTraceFlags + ServerName = $ServerName + InstanceName = $InstanceName + ActualTraceFlags = $ActualTraceFlags + TraceFlags = $null + TraceFlagsToInclude = $null + TraceFlagsToExclude = $null } } @@ -161,7 +164,7 @@ function Set-TargetResource { $wishTraceFlags = [System.Collections.ArrayList]::new() - if ($TraceFlags) + if ($PSBoundParameters.ContainsKey('TraceFlags')) { $wishTraceFlags.AddRange($TraceFlags) } @@ -170,7 +173,7 @@ function Set-TargetResource $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters $wishTraceFlags.AddRange($getTargetResourceResult.ActualTraceFlags) - if ($TraceFlagsToInclude) + if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) { foreach ($traceFlagToInclude in $TraceFlagsToInclude) { @@ -181,7 +184,7 @@ function Set-TargetResource } } - if ($TraceFlagsToExclude) + if ($PSBoundParameters.ContainsKey('TraceFlagsToExclude')) { foreach ($traceFlagToExclude in $TraceFlagsToExclude) { @@ -241,18 +244,21 @@ function Set-TargetResource $wmiService.StartupParameters = $parameterList -join ';' $wmiService.Alter() - if ($RestartInstance) + if ($PSBoundParameters.ContainsKey('RestartInstance')) { - #Get the current status of the sql agent. After restart of the instance, the status of the agent should be the same. - $AgentServiceStatus = ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).ServiceState + if ($RestartInstance -eq $true) + { + #Get the current status of the sql agent. After restart of the instance, the status of the agent should be the same. + $AgentServiceStatus = ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).ServiceState - $wmiService.Stop() - Start-Sleep -Seconds 10 - $wmiService.Start() + $wmiService.Stop() + Start-Sleep -Seconds 10 + $wmiService.Start() - if ($AgentServiceStatus -ne 'Stopped') - { - ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).Start() + if ($AgentServiceStatus -ne 'Stopped') + { + ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).Start() + } } } } @@ -350,9 +356,11 @@ function Test-TargetResource $isInDesiredState = $true if ($Ensure -eq 'Present') { - if ($TraceFlags) + if ($PSBoundParameters.ContainsKey('TraceFlags')) { - if ( $null -ne (Compare-Object -ReferenceObject $getTargetResourceResult.ActualTraceFlags -DifferenceObject $TraceFlags)) + #Compare $TraceFlags to ActualTraceFlags to see if they are the same. + $nullIfTheSame = Compare-Object -ReferenceObject $getTargetResourceResult.ActualTraceFlags -DifferenceObject $TraceFlags + if ( $null -ne $nullIfTheSame) { Write-Verbose -Message ( $script:localizedData.DesiredTraceFlagNotPresent ` @@ -364,7 +372,7 @@ function Test-TargetResource } else { - if ($TraceFlagsToInclude) + if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) { foreach ($traceFlagToInclude in $TraceFlagsToInclude) { @@ -380,7 +388,7 @@ function Test-TargetResource } } - if ($TraceFlagsToExclude) + if ($PSBoundParameters.ContainsKey('TraceFlagsToExclude')) { foreach ($traceFlagToExclude in $TraceFlagsToExclude) { @@ -407,17 +415,17 @@ function Test-TargetResource return $isInDesiredState } -Export-ModuleMember -Function *-TargetResource - <# .SYNOPSIS This function returns the serviceNames of an sql instance. + + .PARAMETER InstanceName + The name of the SQL instance of whoose service names are beeing returned. #> function Get-SqlServiceName { param ( - [Parameter(Position = 1)] [System.String] $InstanceName = 'MSSQLServer' ) diff --git a/tests/Unit/Stubs/SMO.cs b/tests/Unit/Stubs/SMO.cs index 470b5c8e3..de84deb51 100644 --- a/tests/Unit/Stubs/SMO.cs +++ b/tests/Unit/Stubs/SMO.cs @@ -972,7 +972,7 @@ public enum ManagedServiceType #region Public Classes - // TypeName: Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType + // TypeName: Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer // Used by: // DSC_SqlTraceFlag.Tests.ps1 public class ManagedComputer From 5ff9a8760c6016b73c92afbbf80937a93c9bb475 Mon Sep 17 00:00:00 2001 From: Fiander Date: Fri, 27 Nov 2020 17:53:20 +0100 Subject: [PATCH 07/28] Removed to much --- source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 1 + 1 file changed, 1 insertion(+) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 580afab88..9cd8be904 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -426,6 +426,7 @@ function Get-SqlServiceName { param ( + [Parameter()] [System.String] $InstanceName = 'MSSQLServer' ) From 7e9228001f5eec0e49d59030f9a059616e1ada64 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Fri, 27 Nov 2020 16:07:59 +0100 Subject: [PATCH 08/28] Style guideline fixes and move change log entries --- CHANGELOG.md | 51 +++++----- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 92 +++++++++++-------- 2 files changed, 79 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20763d944..ab9918fdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,33 +5,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- SqlTraceFlag - - Added new resource to set or changes TraceFlags on Sql Server. - - This resource is based on zuldans code but with SqlServerDsc integrated SMO - - Credits:(https://github.com/Zuldan/cSQLServerTraceFlag) - - Added a lot of test scripts to validated the code. -- WaitForAG - - BREAKING CHANGE: Fix for issue ([issue #1569](https://github.com/dsccommunity/SqlServerDsc/issues/1569)) - The resource now waits for the Availability Group to become Available. - - Two parameters where added to test get and set resource at instance level. -- SqlRole - - Major overhaul of resource. - - BREAKING CHANGE: Removed decision making from get-TargetResource; this - prevented a simple solution for issue #550. it now just tels if a role - exists or not. And what members are in that role. MembersToInclude and - MembersToExclude now always return $null. - - Added sanitize function (`Get-CorrectedMemberParameters`) to make it - so for the sysadmin role SA does not get altered ([issue #550](https://github.com/dsccommunity/SqlServerDsc/issues/550)). - - Added lots of tests. -- SqlSetup - - Added a note to the documentation that the parameter `BrowserSvcStartupType` - cannot be used for configurations that utilize the `'InstallFailoverCluster'` - action ([issue #1627](https://github.com/dsccommunity/SqlServerDsc/issues/1627)). - - Minor change to the evaluation of the parameter `BrowserSvcStartupType`, - if it has an assigned a value or not. - ### Added +- SqlServerDsc + - Added new resource SqlTraceFlag to set or changes TraceFlags on SQL Server. + This resource is based on @Zuldans code but with SqlServerDsc integrated SMO. + Credits: https://github.com/Zuldan/cSQLServerTraceFlag + - Added a lot of test scripts to validated the code. - SqlEndpoint - Added support for the Service Broker Endpoint ([issue #498](https://github.com/dsccommunity/SqlServerDsc/issues/498)). - SqlDatabaseRole @@ -51,8 +31,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SqlReplication - The resource are now using the helper function `Get-SqlInstanceMajorVersion` ([issue #1408](https://github.com/dsccommunity/SqlServerDsc/issues/1408)). +- SqlRole + - Major overhaul of resource. + - BREAKING CHANGE: Removed decision making from get-TargetResource; this + prevented a simple solution for issue #550. it now just tels if a role + exists or not. And what members are in that role. MembersToInclude and + MembersToExclude now always return $null. + - Added sanitize function (`Get-CorrectedMemberParameters`) to make it + so for the sysadmin role SA does not get altered ([issue #550](https://github.com/dsccommunity/SqlServerDsc/issues/550)). + - Added lots of tests. +- SqlWaitForAG + - BREAKING CHANGE: Fix for issue ([issue #1569](https://github.com/dsccommunity/SqlServerDsc/issues/1569)) + The resource now waits for the Availability Group to become Available. + - Two parameters where added to test get and set resource at instance level. +- SqlSetup + - Minor change to the evaluation of the parameter `BrowserSvcStartupType`, + if it has an assigned a value or not. ### Fixed + - SqlDatabaseRole - Fixed check to see if the role and user existed in the database. The previous logic would always indicate the role or user was not found unless @@ -62,6 +59,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SqlAlwaysOnService - Updated Get-TargetResource to return all defined schema properties ([issue #150](https://github.com/dsccommunity/SqlServerDsc/issues/1501)). +- SqlSetup + - Added a note to the documentation that the parameter `BrowserSvcStartupType` + cannot be used for configurations that utilize the `'InstallFailoverCluster'` + action ([issue #1627](https://github.com/dsccommunity/SqlServerDsc/issues/1627)). ## [14.2.1] - 2020-08-14 diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 9cd8be904..170b91e63 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -36,22 +36,22 @@ function Get-TargetResource $script:localizedData.GetConfiguration -f $Name ) - $SQLManagement = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $ServerName + $sqlManagement = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer' -ArgumentList $ServerName - $ServiceNames = Get-SqlServiceName -InstanceName $InstanceName + $serviceNames = Get-SqlServiceName -InstanceName $InstanceName - if ($SQLManagement) + if ($sqlManagement) { - $WMIService = $SQLManagement.Services | - Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLEngineName } + $wmiService = $sqlManagement.Services | + Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLEngineName } - if ($WMIService) + if ($wmiService) { - $ActualTraceFlags = $WMIService.StartupParameters.Split(';') | + $actualTraceFlags = $wmiService.StartupParameters.Split(';') | Where-Object -FilterScript { $PSItem -like '-T*' } | ForEach-Object { $PSItem.TrimStart('-T') - } + } } else { @@ -68,7 +68,7 @@ function Get-TargetResource return @{ ServerName = $ServerName InstanceName = $InstanceName - ActualTraceFlags = $ActualTraceFlags + ActualTraceFlags = $actualTraceFlags TraceFlags = $null TraceFlagsToInclude = $null TraceFlagsToExclude = $null @@ -117,15 +117,15 @@ function Set-TargetResource $InstanceName, [Parameter()] - [System.Uint32[]] + [System.UInt32[]] $TraceFlags, [Parameter()] - [System.Uint32[]] + [System.UInt32[]] $TraceFlagsToInclude, [Parameter()] - [System.Uint32[]] + [System.UInt32[]] $TraceFlagsToExclude, [Parameter()] @@ -144,7 +144,7 @@ function Set-TargetResource ) $assertBoundParameterParameters = @{ - BoundParameterList = $PSBoundParameters + BoundParameterList = $PSBoundParameters MutuallyExclusiveList1 = @( 'TraceFlags' ) @@ -171,6 +171,7 @@ function Set-TargetResource else { $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + $wishTraceFlags.AddRange($getTargetResourceResult.ActualTraceFlags) if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) @@ -197,30 +198,33 @@ function Set-TargetResource } # Add '-T' dash to flag - $traceFlagList = $wishTraceFlags | ForEach-Object { - "-T$PSItem" - } + $traceFlagList = $wishTraceFlags | + ForEach-Object { + "-T$PSItem" + } } else { - #when ensure <> present, TraceFlagList should be empty, - #this wil remove all traceFlags from the startupParameters + <# + When ensure <> present, TraceFlagList should be empty, + this will remove all traceFlags from the startupParameters + #> $traceFlagList = $null } - $ServiceNames = Get-SqlServiceName -InstanceName $InstanceName + $serviceNames = Get-SqlServiceName -InstanceName $InstanceName - $SQLManagement = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $ServerName + $sqlManagement = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer' -ArgumentList $ServerName - if ($SQLManagement) + if ($sqlManagement) { - $WMIService = $SQLManagement.Services | - Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLEngineName } + $wmiService = $sqlManagement.Services | + Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLEngineName } - if ($WMIService) + if ($wmiService) { # Extract startup parameters - [System.Collections.ArrayList]$parameterList = $wmiService.StartupParameters.Split(';') + [System.Collections.ArrayList] $parameterList = $wmiService.StartupParameters.Split(';') # Removing flags that are not wanted foreach ($parameter in $wmiService.StartupParameters.Split(';')) @@ -232,11 +236,11 @@ function Set-TargetResource } # Add missing flags - foreach ($Flag in $traceFlagList) + foreach ($flag in $traceFlagList) { - if ($Flag -notin $parameterList) + if ($flag -notin $parameterList) { - $parameterList.Add($Flag) | Out-Null + $parameterList.Add($flag) | Out-Null } } @@ -248,16 +252,24 @@ function Set-TargetResource { if ($RestartInstance -eq $true) { - #Get the current status of the sql agent. After restart of the instance, the status of the agent should be the same. - $AgentServiceStatus = ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).ServiceState + # Get the current status of the sql agent. After restart of the instance, the status of the agent should be the same. + $agentServiceStatus = ( + $sqlManagement.Services | + Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLAgentName } + ).ServiceState $wmiService.Stop() + Start-Sleep -Seconds 10 + $wmiService.Start() - if ($AgentServiceStatus -ne 'Stopped') + if ($agentServiceStatus -ne 'Stopped') { - ($sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $ServiceNames.SQLAgentName }).Start() + ( + $sqlManagement.Services | + Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLAgentName } + ).Start() } } } @@ -335,7 +347,7 @@ function Test-TargetResource ) $assertBoundParameterParameters = @{ - BoundParameterList = $PSBoundParameters + BoundParameterList = $PSBoundParameters MutuallyExclusiveList1 = @( 'TraceFlags' ) @@ -354,6 +366,7 @@ function Test-TargetResource $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters $isInDesiredState = $true + if ($Ensure -eq 'Present') { if ($PSBoundParameters.ContainsKey('TraceFlags')) @@ -412,6 +425,7 @@ function Test-TargetResource $isInDesiredState = $false } } + return $isInDesiredState } @@ -433,17 +447,17 @@ function Get-SqlServiceName if ($InstanceName -eq 'MSSQLSERVER') { - $SQLEngineName = 'MSSQLSERVER' - $SQLAgentName = 'SQLSERVERAGENT' + $sqlEngineName = 'MSSQLSERVER' + $sqlAgentName = 'SQLSERVERAGENT' } else { - $SQLEngineName = 'MSSQL${0}' -f $InstanceName - $SQLAgentName = 'SQLAgent${0}' -f $InstanceName + $sqlEngineName = 'MSSQL${0}' -f $InstanceName + $sqlAgentName = 'SQLAgent${0}' -f $InstanceName } return @{ - SQLEngineName = $SQLEngineName - SQLAgentName = $SQLAgentName + SQLEngineName = $sqlEngineName + SQLAgentName = $sqlAgentName } } From a7fbcf3ca50593bbae2066b5f13cc28bd8cba7a5 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Fri, 27 Nov 2020 16:13:44 +0100 Subject: [PATCH 09/28] Fix examples --- source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 | 2 +- .../Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 | 2 +- source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 index 318282b57..a12b4cf9c 100644 --- a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 @@ -21,7 +21,7 @@ Configuration Example ServerName = 'sqltest.company.local' InstanceName = 'DSC' TraceFlags = 834, 1117, 1118, 2371, 3226 - RestartInstance = $true + RestartInstance = $true Ensure = 'Present' PsDscRunAsCredential = $SqlAdministratorCredential diff --git a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 index bc72653a5..ff6480c09 100644 --- a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 @@ -22,7 +22,7 @@ Configuration Example InstanceName = 'DSC' TraceFlagsToInclude = 834, 1117, 1118, 2371, 3226 TraceFlagsToExclude = 1112 - RestartInstance = $true + RestartInstance = $true Ensure = 'Present' PsDscRunAsCredential = $SqlAdministratorCredential diff --git a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 index 3b099247b..8f044f0cd 100644 --- a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 @@ -20,7 +20,7 @@ Configuration Example { ServerName = 'sqltest.company.local' InstanceName = 'DSC' - RestartInstance = $true + RestartInstance = $true Ensure = 'Absent' PsDscRunAsCredential = $SqlAdministratorCredential From 06d505de37a1f91da1c894e6c8472f3c0a877a62 Mon Sep 17 00:00:00 2001 From: Fiander Date: Sat, 28 Nov 2020 19:05:50 +0100 Subject: [PATCH 10/28] Removed "Envorce" also in all tests --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 148 ++++++++---------- .../DSC_SqlTraceFlag.schema.mof | 1 - tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 31 +--- 3 files changed, 67 insertions(+), 113 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 170b91e63..ffa056e6c 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -96,10 +96,6 @@ function Get-TargetResource .PARAMETER TraceFlagsToExclude The TraceFlags the SQL server engine startup parameters should exclude. This parameter can not be used together with TraceFlags. - - .PARAMETER Ensure - When set to 'Present', the TraceFlags will be created/added. - When set to 'Absent', all the TraceFlags will be removed. #> function Set-TargetResource { @@ -130,13 +126,7 @@ function Set-TargetResource [Parameter()] [System.Boolean] - $RestartInstance = $false, - - [Parameter()] - [ValidateSet('Present', 'Absent')] - [ValidateNotNullOrEmpty()] - [System.String] - $Ensure = 'Present' + $RestartInstance = $false ) Write-Verbose -Message ( @@ -160,55 +150,49 @@ function Set-TargetResource InstanceName = $InstanceName } - if ($Ensure -eq 'Present') - { - $wishTraceFlags = [System.Collections.ArrayList]::new() + $wishTraceFlags = [System.Collections.ArrayList]::new() - if ($PSBoundParameters.ContainsKey('TraceFlags')) - { - $wishTraceFlags.AddRange($TraceFlags) - } - else - { - $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + if ($PSBoundParameters.ContainsKey('TraceFlags')) + { + $wishTraceFlags.AddRange($TraceFlags) + } + else + { + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - $wishTraceFlags.AddRange($getTargetResourceResult.ActualTraceFlags) + $wishTraceFlags.AddRange($getTargetResourceResult.ActualTraceFlags) - if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) + if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) + { + foreach ($traceFlagToInclude in $TraceFlagsToInclude) { - foreach ($traceFlagToInclude in $TraceFlagsToInclude) + if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) { - if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) - { - $wishTraceFlags.Add($traceFlagToInclude) - } + $wishTraceFlags.Add($traceFlagToInclude) } } + } - if ($PSBoundParameters.ContainsKey('TraceFlagsToExclude')) + if ($PSBoundParameters.ContainsKey('TraceFlagsToExclude')) + { + foreach ($traceFlagToExclude in $TraceFlagsToExclude) { - foreach ($traceFlagToExclude in $TraceFlagsToExclude) + if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) { - if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) - { - $wishTraceFlags.Remove([string]$traceFlagToExclude) - } + $wishTraceFlags.Remove([string]$traceFlagToExclude) } } } - - # Add '-T' dash to flag - $traceFlagList = $wishTraceFlags | - ForEach-Object { - "-T$PSItem" - } } - else + + # Add '-T' dash to flag + $traceFlagList = $wishTraceFlags | + ForEach-Object { + "-T$PSItem" + } + + if ($traceFlagList -eq '') { - <# - When ensure <> present, TraceFlagList should be empty, - this will remove all traceFlags from the startupParameters - #> $traceFlagList = $null } @@ -298,10 +282,6 @@ function Set-TargetResource .PARAMETER TraceFlagsToExclude The TraceFlags the SQL server engine startup parameters should exclude. This parameter can not be used together with TraceFlags. - - .PARAMETER Ensure - When set to 'Present', the TraceFlags will be created/added. - When set to 'Absent', all TraceFlags will be removed. #> function Test-TargetResource { @@ -333,13 +313,7 @@ function Test-TargetResource [Parameter()] [System.Boolean] - $RestartInstance = $false, - - [Parameter()] - [ValidateSet('Present', 'Absent')] - [ValidateNotNullOrEmpty()] - [System.String] - $Ensure = 'Present' + $RestartInstance = $false ) Write-Verbose -Message ( @@ -367,11 +341,18 @@ function Test-TargetResource $isInDesiredState = $true - if ($Ensure -eq 'Present') + if ($PSBoundParameters.ContainsKey('TraceFlags')) { - if ($PSBoundParameters.ContainsKey('TraceFlags')) + if ($TraceFlags.Length -eq 0) { - #Compare $TraceFlags to ActualTraceFlags to see if they are the same. + if ($getTargetResourceResult.ActualTraceFlags.Count -gt 0) + { + $isInDesiredState = $false + } + } + else + { + #Compare $TraceFlags to ActualTraceFlags to see if they contain the same values. $nullIfTheSame = Compare-Object -ReferenceObject $getTargetResourceResult.ActualTraceFlags -DifferenceObject $TraceFlags if ( $null -ne $nullIfTheSame) { @@ -383,48 +364,41 @@ function Test-TargetResource $isInDesiredState = $false } } - else + } + else + { + if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) { - if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) + foreach ($traceFlagToInclude in $TraceFlagsToInclude) { - foreach ($traceFlagToInclude in $TraceFlagsToInclude) + if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) { - if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) - { - Write-Verbose -Message ( - $script:localizedData.TraceFlagNotPresent ` - -f $traceFlagToInclude - ) + Write-Verbose -Message ( + $script:localizedData.TraceFlagNotPresent ` + -f $traceFlagToInclude + ) - $isInDesiredState = $false - } + $isInDesiredState = $false } } + } - if ($PSBoundParameters.ContainsKey('TraceFlagsToExclude')) + if ($PSBoundParameters.ContainsKey('TraceFlagsToExclude')) + { + foreach ($traceFlagToExclude in $TraceFlagsToExclude) { - foreach ($traceFlagToExclude in $TraceFlagsToExclude) + if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) { - if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) - { - Write-Verbose -Message ( - $script:localizedData.TraceFlagPresent ` - -f $traceFlagToExclude - ) + Write-Verbose -Message ( + $script:localizedData.TraceFlagPresent ` + -f $traceFlagToExclude + ) - $isInDesiredState = $false - } + $isInDesiredState = $false } } } } - else - { - if ($getTargetResourceResult.ActualTraceFlags.Count -gt 0) - { - $isInDesiredState = $false - } - } return $isInDesiredState } diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof index b7fa465d4..e9368edcc 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -7,5 +7,4 @@ class DSC_SqlTraceFlag : OMI_BaseResource [Write, Description("An array of trace flags to be added to the existing trace flags")] Uint32 TraceFlagsToInclude[]; [Write, Description("An array of trace flags to be removed from the existing trace flags")] Uint32 TraceFlagsToExclude[]; [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartInstance; - [Write, Description("When set to `'Present'`, the TraceFlags will be set. When set to `'Absent'`, All TraceFlags will be Removed. Default value is `'Present'`."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; }; diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index f079e13cc..6d9c5018f 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -262,11 +262,11 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable } - Context 'When the system is not in the desired state and ensure is set to Absent' { + Context 'When the system is not in the desired state and TraceFlags is empty' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Absent' + TraceFlags = @() } $result = Test-TargetResource @testParameters @@ -281,17 +281,18 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } } - Context 'When the system is in the desired state and ensure is set to Absent' { + Context 'When the system is in the desired state and TraceFlags is empty' { BeforeAll { $testParameters = $mockInst00Parameters $testParameters += @{ - Ensure = 'Absent' + TraceFlags = @() } $result = Test-TargetResource @testParameters } It 'Should return true when no Traceflags on the instance exist' { + $result | Should -BeTrue } @@ -304,7 +305,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlags = '3228' } @@ -324,7 +324,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlagsToInclude = '3228' } @@ -344,7 +343,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlagsToInclude = '3226' } @@ -364,7 +362,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlagsToExclude = '3226' } @@ -384,7 +381,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlagsToExclude = '3228' } @@ -405,7 +401,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlags = '3228' TraceFlagsToInclude = '3228' } @@ -424,7 +419,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlags = '3228' TraceFlagsToExclude = '3228' } @@ -441,15 +435,8 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } -#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 259 $errorMessage = $script:localizedData... -#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 260 New-InvalidOperationException -Messag... -#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 265 $errorMessage = $script:localizedData... -#DSCResources\DSC_SqlTraceFlag\DSC_SqlTraceFlag.psm1 Set-TargetResource 266 New-InvalidOperationException -Messag... - - Describe "DSC_SqlTraceFlag\Set-TargetResource" -Tag 'Set' { BeforeAll { - #Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable } @@ -457,7 +444,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Absent' + TraceFlags = @() } } @@ -481,7 +468,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlags = '3228' } } @@ -505,7 +491,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlagsToInclude = '3228' } } @@ -529,7 +514,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802;-T3228 BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlagsToExclude = '1802' } } @@ -553,7 +537,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226 BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlags = '3228' RestartInstance = $true } @@ -578,7 +561,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlags = '3228' TraceFlagsToInclude = '3228' } @@ -597,7 +579,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ - Ensure = 'Present' TraceFlags = '3228' TraceFlagsToExclude = '3228' } From 8cd697027d3619f8f8ee0ba77dd8a2b19af62f81 Mon Sep 17 00:00:00 2001 From: Fiander Date: Sat, 28 Nov 2020 19:07:40 +0100 Subject: [PATCH 11/28] Remove Ensure from examples --- source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 | 1 - .../Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 | 1 - source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 index a12b4cf9c..1f08e9bfb 100644 --- a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 @@ -22,7 +22,6 @@ Configuration Example InstanceName = 'DSC' TraceFlags = 834, 1117, 1118, 2371, 3226 RestartInstance = $true - Ensure = 'Present' PsDscRunAsCredential = $SqlAdministratorCredential } diff --git a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 index ff6480c09..6417a0d75 100644 --- a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 @@ -23,7 +23,6 @@ Configuration Example TraceFlagsToInclude = 834, 1117, 1118, 2371, 3226 TraceFlagsToExclude = 1112 RestartInstance = $true - Ensure = 'Present' PsDscRunAsCredential = $SqlAdministratorCredential } diff --git a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 index 8f044f0cd..ff3a24729 100644 --- a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 @@ -21,7 +21,7 @@ Configuration Example ServerName = 'sqltest.company.local' InstanceName = 'DSC' RestartInstance = $true - Ensure = 'Absent' + TraceFlags = @() PsDscRunAsCredential = $SqlAdministratorCredential } From ba872f2bddb99e11f77e71f314d3721fd29e7ba1 Mon Sep 17 00:00:00 2001 From: Fiander Date: Sun, 29 Nov 2020 10:26:23 +0100 Subject: [PATCH 12/28] first batch of fixes. --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 49 ++++++++++++------- .../DSC_SqlTraceFlag.schema.mof | 7 +-- .../DSCResources/DSC_SqlTraceFlag/README.md | 4 +- .../en-US/DSC_SqlTraceFlag.strings.psd1 | 4 +- .../2-SetTraceFlagsIncludeExclude.ps1 | 4 +- .../SqlTraceFlag/3-RemoveTraceFlags.ps1 | 3 +- 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index ffa056e6c..c62bfb293 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -33,7 +33,7 @@ function Get-TargetResource ) Write-Verbose -Message ( - $script:localizedData.GetConfiguration -f $Name + $script:localizedData.GetConfiguration -f $InstanceName ) $sqlManagement = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer' -ArgumentList $ServerName @@ -42,12 +42,12 @@ function Get-TargetResource if ($sqlManagement) { - $wmiService = $sqlManagement.Services | + $databaseEngineService = $sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLEngineName } - if ($wmiService) + if ($databaseEngineService) { - $actualTraceFlags = $wmiService.StartupParameters.Split(';') | + $actualTraceFlags = $databaseEngineService.StartupParameters.Split(';') | Where-Object -FilterScript { $PSItem -like '-T*' } | ForEach-Object { $PSItem.TrimStart('-T') @@ -72,6 +72,7 @@ function Get-TargetResource TraceFlags = $null TraceFlagsToInclude = $null TraceFlagsToExclude = $null + RestartInstance = $null } } @@ -88,6 +89,7 @@ function Get-TargetResource .PARAMETER TraceFlags The TraceFlags the SQL server engine startup parameters should contain. This parameter can not be used together with TraceFlagsToInclude and TraceFlagsToExclude. + This parameter will replace all the current trace flags with the specified trace flags. .PARAMETER TraceFlagsToInclude The TraceFlags the SQL server engine startup parameters should include. @@ -96,6 +98,10 @@ function Get-TargetResource .PARAMETER TraceFlagsToExclude The TraceFlags the SQL server engine startup parameters should exclude. This parameter can not be used together with TraceFlags. + + .PARAMETER RestartInstance + If set, the sql server instance gets a reset after setting parameters. + after restart the sql server agent is in the original state as before restart. #> function Set-TargetResource { @@ -130,7 +136,7 @@ function Set-TargetResource ) Write-Verbose -Message ( - $script:localizedData.SetConfiguration -f $Name, $RetryCount, ($RetryIntervalSec * $RetryCount) + $script:localizedData.SetConfiguration -f $InstanceName ) $assertBoundParameterParameters = @{ @@ -185,7 +191,7 @@ function Set-TargetResource } } - # Add '-T' dash to flag + # Add '-T' dash to flag. $traceFlagList = $wishTraceFlags | ForEach-Object { "-T$PSItem" @@ -202,16 +208,16 @@ function Set-TargetResource if ($sqlManagement) { - $wmiService = $sqlManagement.Services | + $databaseEngineService = $sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLEngineName } - if ($wmiService) + if ($databaseEngineService) { - # Extract startup parameters - [System.Collections.ArrayList] $parameterList = $wmiService.StartupParameters.Split(';') + # Extract startup parameters. + [System.Collections.ArrayList] $parameterList = $databaseEngineService.StartupParameters.Split(';') # Removing flags that are not wanted - foreach ($parameter in $wmiService.StartupParameters.Split(';')) + foreach ($parameter in $databaseEngineService.StartupParameters.Split(';')) { if ($parameter -like '-T*' -and $parameter -notin $traceFlagList) { @@ -219,7 +225,7 @@ function Set-TargetResource } } - # Add missing flags + # Add missing flags. foreach ($flag in $traceFlagList) { if ($flag -notin $parameterList) @@ -228,9 +234,9 @@ function Set-TargetResource } } - # Merge flags back into startup parameters - $wmiService.StartupParameters = $parameterList -join ';' - $wmiService.Alter() + # Merge flags back into startup parameters. + $databaseEngineService.StartupParameters = $parameterList -join ';' + $databaseEngineService.Alter() if ($PSBoundParameters.ContainsKey('RestartInstance')) { @@ -242,11 +248,11 @@ function Set-TargetResource Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLAgentName } ).ServiceState - $wmiService.Stop() + $databaseEngineService.Stop() Start-Sleep -Seconds 10 - $wmiService.Start() + $databaseEngineService.Start() if ($agentServiceStatus -ne 'Stopped') { @@ -274,6 +280,7 @@ function Set-TargetResource .PARAMETER TraceFlags The TraceFlags the SQL server engine startup parameters should contain. This parameter can not be used together with TraceFlagsToInclude and TraceFlagsToExclude. + This parameter will replace all the current trace flags with the specified trace flags. .PARAMETER TraceFlagsToInclude The TraceFlags the SQL server engine startup parameters should include. @@ -282,6 +289,10 @@ function Set-TargetResource .PARAMETER TraceFlagsToExclude The TraceFlags the SQL server engine startup parameters should exclude. This parameter can not be used together with TraceFlags. + + .PARAMETER RestartInstance + If set, the sql server instance gets a reset after setting parameters. + after restart the sql server agent is in the original state as before restart. #> function Test-TargetResource { @@ -352,9 +363,9 @@ function Test-TargetResource } else { - #Compare $TraceFlags to ActualTraceFlags to see if they contain the same values. + # Compare $TraceFlags to ActualTraceFlags to see if they contain the same values. $nullIfTheSame = Compare-Object -ReferenceObject $getTargetResourceResult.ActualTraceFlags -DifferenceObject $TraceFlags - if ( $null -ne $nullIfTheSame) + if ($null -ne $nullIfTheSame) { Write-Verbose -Message ( $script:localizedData.DesiredTraceFlagNotPresent ` diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof index e9368edcc..0a41ceea5 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -3,8 +3,9 @@ class DSC_SqlTraceFlag : OMI_BaseResource { [Write, Description("The host name of the _SQL Server_ to be configured. Default value is `$env:COMPUTERNAME`.")] String ServerName; [Key, Description("The name of the _SQL Server_ instance to be configured.")] String InstanceName; - [Write, Description("An array of trace flags that startup options should have")] Uint32 TraceFlags[]; - [Write, Description("An array of trace flags to be added to the existing trace flags")] Uint32 TraceFlagsToInclude[]; - [Write, Description("An array of trace flags to be removed from the existing trace flags")] Uint32 TraceFlagsToExclude[]; + [Write, Description("An array of trace flags that startup options should have. This parameter will replace all the current trace flags with the specified trace flags.")] Uint32 TraceFlags[]; + [Write, Description("An array of trace flags to be added to the existing trace flags.")] Uint32 TraceFlagsToInclude[]; + [Write, Description("An array of trace flags to be removed from the existing trace flags.")] Uint32 TraceFlagsToExclude[]; [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartInstance; + [read, Description("Returns the actual trace flags as seen on the instance.")] String ActualTraceFlags; }; diff --git a/source/DSCResources/DSC_SqlTraceFlag/README.md b/source/DSCResources/DSC_SqlTraceFlag/README.md index fc54fa45b..e60bbff0e 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/README.md +++ b/source/DSCResources/DSC_SqlTraceFlag/README.md @@ -1,6 +1,6 @@ # Description -The `SqlTraceFlag` DSC resource will set TraceFlags on a sql server engine. +The `SqlTraceFlag` DSC resource will remove or set one or more trace flags on a sql server engine. ## Requirements @@ -9,7 +9,7 @@ The `SqlTraceFlag` DSC resource will set TraceFlags on a sql server engine. ## Security Requirements -* Target machine must have admin access to the Windows Server. +* The account running this resource must have admin access to the Windows Server. ## Known issues diff --git a/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 b/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 index a45a9a305..bc2b61fe9 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 +++ b/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 @@ -1,6 +1,6 @@ ConvertFrom-StringData @' - GetConfiguration = Get the current TraceFlags that are set. - SetConfiguration = Set the TraceFlags that are needed. + GetConfiguration = Get the current TraceFlags that are set on instance {0}. + SetConfiguration = Set the TraceFlags that are needed on instance {0}. TestConfiguration = Determines the current state of the TraceFlags Compared to the desired TraceFlags '{0}'. NotConnectedToComputerManagement = Was unable to connect to ComputerManagement '{0}'. NotConnectedToWMI = Was unable to connect to WMI information '{0}' in '{1}'. diff --git a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 index 6417a0d75..5963f35db 100644 --- a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 @@ -1,7 +1,7 @@ <# .DESCRIPTION - This example shows how to set TraceFlags where all existing - TraceFlags are overwriten by these + This example shows how to set TraceFlags while keeping all existing + traceflags. Also one existing traceflag is removed. #> Configuration Example { diff --git a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 index ff3a24729..6b2088fd4 100644 --- a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 @@ -1,7 +1,6 @@ <# .DESCRIPTION - This example shows how to set TraceFlags where all existing - TraceFlags are overwriten by these + This example shows how to clear all TraceFlags. #> Configuration Example { From ca656552e2f6bf860b3477d4d5ab9edbbf457f31 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 3 Dec 2020 15:25:43 +0100 Subject: [PATCH 13/28] removed readonly parameters, changed to Restart-SqlService, adjusted all test for this. --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 42 ++----- .../DSC_SqlTraceFlag.schema.mof | 1 - tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 108 ++++++------------ tests/Unit/Stubs/New File.ps1 | 0 4 files changed, 46 insertions(+), 105 deletions(-) create mode 100644 tests/Unit/Stubs/New File.ps1 diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index c62bfb293..5b488685d 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -68,8 +68,7 @@ function Get-TargetResource return @{ ServerName = $ServerName InstanceName = $InstanceName - ActualTraceFlags = $actualTraceFlags - TraceFlags = $null + TraceFlags = $actualTraceFlags TraceFlagsToInclude = $null TraceFlagsToExclude = $null RestartInstance = $null @@ -165,14 +164,14 @@ function Set-TargetResource else { $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - - $wishTraceFlags.AddRange($getTargetResourceResult.ActualTraceFlags) + $actualTraceFlags = $getTargetResourceResult.TraceFlags + $wishTraceFlags.AddRange($actualTraceFlags) if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) { foreach ($traceFlagToInclude in $TraceFlagsToInclude) { - if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) + if ($actualTraceFlags -notcontains $traceFlagToInclude) { $wishTraceFlags.Add($traceFlagToInclude) } @@ -183,7 +182,7 @@ function Set-TargetResource { foreach ($traceFlagToExclude in $TraceFlagsToExclude) { - if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) + if ($actualTraceFlags -contains $traceFlagToExclude) { $wishTraceFlags.Remove([string]$traceFlagToExclude) } @@ -242,25 +241,8 @@ function Set-TargetResource { if ($RestartInstance -eq $true) { - # Get the current status of the sql agent. After restart of the instance, the status of the agent should be the same. - $agentServiceStatus = ( - $sqlManagement.Services | - Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLAgentName } - ).ServiceState - - $databaseEngineService.Stop() - - Start-Sleep -Seconds 10 - - $databaseEngineService.Start() - - if ($agentServiceStatus -ne 'Stopped') - { - ( - $sqlManagement.Services | - Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLAgentName } - ).Start() - } + $RestartTimeout = 10 + Restart-SqlService -ServerName $ServerName -InstanceName $InstanceName -Timeout $RestartTimeout } } } @@ -349,14 +331,14 @@ function Test-TargetResource } $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - + $actualTraceFlags = $getTargetResourceResult.TraceFlags $isInDesiredState = $true if ($PSBoundParameters.ContainsKey('TraceFlags')) { if ($TraceFlags.Length -eq 0) { - if ($getTargetResourceResult.ActualTraceFlags.Count -gt 0) + if ($actualTraceFlags.Count -gt 0) { $isInDesiredState = $false } @@ -364,7 +346,7 @@ function Test-TargetResource else { # Compare $TraceFlags to ActualTraceFlags to see if they contain the same values. - $nullIfTheSame = Compare-Object -ReferenceObject $getTargetResourceResult.ActualTraceFlags -DifferenceObject $TraceFlags + $nullIfTheSame = Compare-Object -ReferenceObject $actualTraceFlags -DifferenceObject $TraceFlags if ($null -ne $nullIfTheSame) { Write-Verbose -Message ( @@ -382,7 +364,7 @@ function Test-TargetResource { foreach ($traceFlagToInclude in $TraceFlagsToInclude) { - if ($getTargetResourceResult.ActualTraceFlags -notcontains $traceFlagToInclude) + if ($actualTraceFlags -notcontains $traceFlagToInclude) { Write-Verbose -Message ( $script:localizedData.TraceFlagNotPresent ` @@ -398,7 +380,7 @@ function Test-TargetResource { foreach ($traceFlagToExclude in $TraceFlagsToExclude) { - if ($getTargetResourceResult.ActualTraceFlags -contains $traceFlagToExclude) + if ($actualTraceFlags -contains $traceFlagToExclude) { Write-Verbose -Message ( $script:localizedData.TraceFlagPresent ` diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof index 0a41ceea5..e629ed9fb 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -7,5 +7,4 @@ class DSC_SqlTraceFlag : OMI_BaseResource [Write, Description("An array of trace flags to be added to the existing trace flags.")] Uint32 TraceFlagsToInclude[]; [Write, Description("An array of trace flags to be removed from the existing trace flags.")] Uint32 TraceFlagsToExclude[]; [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartInstance; - [read, Description("Returns the actual trace flags as seen on the instance.")] String ActualTraceFlags; }; diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index 6d9c5018f..af1faff34 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -39,8 +39,6 @@ function Invoke-TestCleanup Invoke-TestSetup -Write-Host (Get-Module pester).Version - try { InModuleScope $script:dscResourceName { @@ -54,17 +52,14 @@ try $mockInstanceName3Agent = 'SQLAgent$INST01' $mockInvalidOperationForAlterMethod = $false - $mockInvalidOperationForStopMethod = $false - $mockInvalidOperationForStartMethod = $false +# $mockInvalidOperationForStopMethod = $false +# $mockInvalidOperationForStartMethod = $false $mockServerInstances = [System.Collections.ArrayList]::new() $mockServerInstances.Add($mockInstanceName1) | Out-Null $mockServerInstances.Add($mockInstanceName2) | Out-Null - - - - #The Trailing spaces in this here string are ment to be there. Do not remove! + # The Trailing spaces in these here strings are ment to be there. Do not remove! $mockStartupParametersInstance1 = @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL @@ -106,8 +101,8 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } $script:mockMethodAlterRan = $false - $script:mockMethodStopRan = $false - $script:mockMethodStartRan = $false +# $script:mockMethodStopRan = $false +# $script:mockMethodStartRan = $false $script:mockMethodAlterValue = '' #region Function mocks @@ -162,14 +157,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $mockService | Add-Member -MemberType ScriptMethod -Name Alter -Value { $script:mockMethodAlterRan = $true $script:mockMethodAlterValue = $this.StartupParameters - } -PassThru | - Add-Member -MemberType ScriptMethod -Name Stop -Value { - $script:mockMethodStopRan = $true - } -PassThru | - Add-Member -MemberType ScriptMethod -Name Start -Value { - $script:mockMethodStartRan = $true - } - + } -PassThru $ServerServices.Add( $mockService) | Out-Null } @@ -189,20 +177,14 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Context 'For the default instance' { BeforeAll { $testParameters = $mockDefaultParameters1 - - $result = Get-TargetResource @testParameters - } - It 'Should return a ManagedComputer object with the correct servername' { - $result.ServerName | Should -Be $mockServerName } - It 'Should return a ManagedComputer object with the correct InstanceName' { - $result.InstanceName | Should -Be $mockInstanceName1 - } - It 'Should return a ManagedComputer object with the correct TraceFlags' { - $result.ActualTraceFlags | Should -Be '3226' ,'1802' - } - It 'Should return a ManagedComputer object with the correct number of TraceFlags' { - $result.ActualTraceFlags.Count | Should -Be 2 + It 'Should return a ManagedComputer object.' { + $result = Get-TargetResource @testParameters + + $result.ServerName | Should -Be $mockServerName -Because 'ServerName must be correct' + $result.InstanceName | Should -Be $mockInstanceName1 -Because 'InstanceName must be correct' + $result.TraceFlags | Should -Be '3226' ,'1802' -Because 'TraceFlags must be correct' + $result.TraceFlags.Count | Should -Be 2 -Because 'number of TraceFlags must be correct' } It 'Should not throw' { {Get-TargetResource @testParameters} | Should -Not -Throw @@ -212,21 +194,16 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Context 'For a named instance' { BeforeAll { $testParameters = $mockInst00Parameters - - $result = Get-TargetResource @testParameters - } - It 'Should return a ManagedComputer object with the correct servername' { - $result.ServerName | Should -Be $mockServerName - } - It 'Should return a ManagedComputer object with the correct InstanceName' { - $result.InstanceName | Should -Be $mockInstanceName2 - } - It 'Should return a ManagedComputer object with the correct TraceFlags' { - $result.ActualTraceFlags | Should -BeNullOrEmpty } - It 'Should return a ManagedComputer object with the correct number of TraceFlags' { - $result.ActualTraceFlags.Count | Should -Be 0 + It 'Should return a ManagedComputer object.' { + $result = Get-TargetResource @testParameters + + $result.ServerName | Should -Be $mockServerName -Because 'ServerName must be correct' + $result.InstanceName | Should -Be $mockInstanceName2 -Because 'InstanceName must be correct' + $result.TraceFlags | Should -BeNullOrEmpty -Because 'TraceFlags must be correct' + $result.TraceFlags.Count | Should -Be 0 -Because 'number of TraceFlags must be correct' } + It 'Should not throw' { {Get-TargetResource @testParameters} | Should -Not -Throw } @@ -258,7 +235,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Describe "DSC_SqlTraceFlag\Test-TargetResource" -Tag 'Test' { BeforeAll { - #Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable } @@ -268,11 +244,10 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $testParameters += @{ TraceFlags = @() } - - $result = Test-TargetResource @testParameters } It 'Should return false when Traceflags on the instance exist' { + $result = Test-TargetResource @testParameters $result | Should -BeFalse } @@ -287,12 +262,10 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $testParameters += @{ TraceFlags = @() } - - $result = Test-TargetResource @testParameters } It 'Should return true when no Traceflags on the instance exist' { - + $result = Test-TargetResource @testParameters $result | Should -BeTrue } @@ -307,11 +280,10 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $testParameters += @{ TraceFlags = '3228' } - - $result = Test-TargetResource @testParameters } It 'Should return false when Traceflags do not match the actual TraceFlags' { + $result = Test-TargetResource @testParameters $result | Should -BeFalse } @@ -326,11 +298,10 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $testParameters += @{ TraceFlagsToInclude = '3228' } - - $result = Test-TargetResource @testParameters } It 'Should return false when TraceflagsToInclude are not in the actual TraceFlags' { + $result = Test-TargetResource @testParameters $result | Should -BeFalse } @@ -345,11 +316,10 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $testParameters += @{ TraceFlagsToInclude = '3226' } - - $result = Test-TargetResource @testParameters } It 'Should return false when TraceflagsToInclude are in the actual TraceFlags' { + $result = Test-TargetResource @testParameters $result | Should -BeTrue } @@ -364,11 +334,10 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $testParameters += @{ TraceFlagsToExclude = '3226' } - - $result = Test-TargetResource @testParameters } It 'Should return false when TraceflagsToExclude are in the actual TraceFlags' { + $result = Test-TargetResource @testParameters $result | Should -BeFalse } @@ -383,11 +352,10 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf $testParameters += @{ TraceFlagsToExclude = '3228' } - - $result = Test-TargetResource @testParameters } It 'Should return true when TraceflagsToExclude are not in the actual TraceFlags' { + $result = Test-TargetResource @testParameters $result | Should -BeTrue } @@ -438,6 +406,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Describe "DSC_SqlTraceFlag\Set-TargetResource" -Tag 'Set' { BeforeAll { Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable + Mock -CommandName Restart-SqlService -ModuleName $script:dscResourceName -Verifiable } Context 'When the system is not in the desired state and ensure is set to Absent' { @@ -450,14 +419,12 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf It 'Should not throw when calling the alter method' { { Set-TargetResource @testParameters } | Should -Not -Throw - $script:mockMethodStopRan | Should -BeFalse - $script:mockMethodStartRan | Should -BeFalse - $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterRan | Should -BeTrue -Because 'Alter should run' $script:mockMethodAlterValue | Should -Be @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf -"@ +"@ -Because 'Alter must change the value correct' Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It } @@ -474,14 +441,12 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf It 'Should not throw when calling the alter method' { { Set-TargetResource @testParameters } | Should -Not -Throw - $script:mockMethodStopRan | Should -BeFalse - $script:mockMethodStartRan | Should -BeFalse - $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterRan | Should -BeTrue -Because 'Alter should run' $script:mockMethodAlterValue | Should -Be @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 -"@ +"@ -Because 'Alter must change the value correct' Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It } @@ -497,8 +462,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 It 'Should not throw when calling the alter method' { { Set-TargetResource @testParameters } | Should -Not -Throw - $script:mockMethodStopRan | Should -BeFalse - $script:mockMethodStartRan | Should -BeFalse $script:mockMethodAlterRan | Should -BeTrue $script:mockMethodAlterValue | Should -Be @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL @@ -520,8 +483,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802;-T3228 It 'Should not throw when calling the alter method' { { Set-TargetResource @testParameters } | Should -Not -Throw - $script:mockMethodStopRan | Should -BeFalse - $script:mockMethodStartRan | Should -BeFalse $script:mockMethodAlterRan | Should -BeTrue $script:mockMethodAlterValue | Should -Be @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL @@ -544,8 +505,6 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226 It 'Should not throw when calling the restart method' { { Set-TargetResource @testParameters } | Should -Not -Throw - $script:mockMethodStopRan | Should -BeTrue - $script:mockMethodStartRan | Should -BeTrue $script:mockMethodAlterRan | Should -BeTrue $script:mockMethodAlterValue | Should -Be @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL @@ -553,6 +512,7 @@ Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 "@ + Assert-MockCalled -CommandName Restart-SqlService -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It } } diff --git a/tests/Unit/Stubs/New File.ps1 b/tests/Unit/Stubs/New File.ps1 new file mode 100644 index 000000000..e69de29bb From 36eb33caeaa99bfc015f8ca2c425bfdd555b3138 Mon Sep 17 00:00:00 2001 From: Fiander Date: Fri, 4 Dec 2020 20:04:38 +0100 Subject: [PATCH 14/28] last fixes ( i hope ) --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 14 +- tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 437 ++++++++++++++---- tests/Unit/Stubs/New File.ps1 | 0 3 files changed, 345 insertions(+), 106 deletions(-) delete mode 100644 tests/Unit/Stubs/New File.ps1 diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 5b488685d..b39c87db2 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -42,7 +42,7 @@ function Get-TargetResource if ($sqlManagement) { - $databaseEngineService = $sqlManagement.Services | + $databaseEngineService = $sqlManagement.Services | Where-Object -FilterScript { $PSItem.Name -eq $serviceNames.SQLEngineName } if ($databaseEngineService) @@ -310,7 +310,7 @@ function Test-TargetResource ) Write-Verbose -Message ( - $script:localizedData.TestConfiguration -f $Name + $script:localizedData.TestConfiguration -f $InstanceName ) $assertBoundParameterParameters = @{ @@ -331,14 +331,14 @@ function Test-TargetResource } $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - $actualTraceFlags = $getTargetResourceResult.TraceFlags + $isInDesiredState = $true if ($PSBoundParameters.ContainsKey('TraceFlags')) { if ($TraceFlags.Length -eq 0) { - if ($actualTraceFlags.Count -gt 0) + if ($getTargetResourceResult.TraceFlags.Count -gt 0) { $isInDesiredState = $false } @@ -346,7 +346,7 @@ function Test-TargetResource else { # Compare $TraceFlags to ActualTraceFlags to see if they contain the same values. - $nullIfTheSame = Compare-Object -ReferenceObject $actualTraceFlags -DifferenceObject $TraceFlags + $nullIfTheSame = Compare-Object -ReferenceObject $getTargetResourceResult.TraceFlags -DifferenceObject $TraceFlags if ($null -ne $nullIfTheSame) { Write-Verbose -Message ( @@ -364,7 +364,7 @@ function Test-TargetResource { foreach ($traceFlagToInclude in $TraceFlagsToInclude) { - if ($actualTraceFlags -notcontains $traceFlagToInclude) + if ($getTargetResourceResult.TraceFlags -notcontains $traceFlagToInclude) { Write-Verbose -Message ( $script:localizedData.TraceFlagNotPresent ` @@ -380,7 +380,7 @@ function Test-TargetResource { foreach ($traceFlagToExclude in $TraceFlagsToExclude) { - if ($actualTraceFlags -contains $traceFlagToExclude) + if ($getTargetResourceResult.TraceFlags -contains $traceFlagToExclude) { Write-Verbose -Message ( $script:localizedData.TraceFlagPresent ` diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index af1faff34..c978389fa 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -42,135 +42,130 @@ Invoke-TestSetup try { InModuleScope $script:dscResourceName { - $mockServerName = 'TestServer' - $mockFakeServerName = 'FakeServer' - $mockInstanceName1 = 'MSSQLSERVER' - $mockInstanceName1Agent = 'SQLSERVERAGENT' - $mockInstanceName2 = 'INST00' - $mockInstanceName2Agent = 'SQLAgent$INST00' - $mockInstanceName3 = 'INST01' - $mockInstanceName3Agent = 'SQLAgent$INST01' - - $mockInvalidOperationForAlterMethod = $false -# $mockInvalidOperationForStopMethod = $false -# $mockInvalidOperationForStartMethod = $false - - $mockServerInstances = [System.Collections.ArrayList]::new() - $mockServerInstances.Add($mockInstanceName1) | Out-Null - $mockServerInstances.Add($mockInstanceName2) | Out-Null - - # The Trailing spaces in these here strings are ment to be there. Do not remove! - $mockStartupParametersInstance1 = @" + Describe "DSC_SqlTraceFlag\Get-TargetResource" -Tag 'Get' { + BeforeAll { + $mockServerName = 'TestServer' + $mockFakeServerName = 'FakeServer' + $mockInstanceName1 = 'MSSQLSERVER' + $mockInstanceName1Agent = 'SQLSERVERAGENT' + $mockInstanceName2 = 'INST00' + $mockInstanceName2Agent = 'SQLAgent$INST00' + $mockInstanceName3 = 'INST01' + $mockInstanceName3Agent = 'SQLAgent$INST01' + + $mockInvalidOperationForAlterMethod = $false + + $mockServerInstances = [System.Collections.ArrayList]::new() + $mockServerInstances.Add($mockInstanceName1) | Out-Null + $mockServerInstances.Add($mockInstanceName2) | Out-Null + + # The Trailing spaces in these here strings are ment to be there. Do not remove! + $mockStartupParametersInstance1 = @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802 "@ - $mockStartupParametersInstance2 = @" + $mockStartupParametersInstance2 = @" -dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf "@ - # Default parameters that are used for the It-blocks - $mockDefaultParameters1 = @{ - InstanceName = $mockInstanceName1 - ServerName = $mockServerName - } + # Default parameters that are used for the It-blocks + $mockDefaultParameters1 = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockServerName + } - $mockInst00Parameters = @{ - InstanceName = $mockInstanceName2 - ServerName = $mockServerName - } + $mockInst00Parameters = @{ + InstanceName = $mockInstanceName2 + ServerName = $mockServerName + } - $mockInst01Parameters = @{ - InstanceName = $mockInstanceName3 - ServerName = $mockServerName - } + $mockInst01Parameters = @{ + InstanceName = $mockInstanceName3 + ServerName = $mockServerName + } - $mockNonExistServerParameters = @{ - InstanceName = $mockInstanceName1 - ServerName = $mockFakeServerName - } + $mockNonExistServerParameters = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockFakeServerName + } - $mockNewObject_ParameterFilter_RealServerName = { - $ServerName -eq $mockServerName - } + $mockNewObject_ParameterFilter_RealServerName = { + $ServerName -eq $mockServerName + } - $mockNewObject_ParameterFilter_FakeServerName = { - $ServerName -eq $mockFakeServerName - } + $mockNewObject_ParameterFilter_FakeServerName = { + $ServerName -eq $mockFakeServerName + } - $script:mockMethodAlterRan = $false -# $script:mockMethodStopRan = $false -# $script:mockMethodStartRan = $false - $script:mockMethodAlterValue = '' - - #region Function mocks - $mockSmoWmiManagedComputer = { - $mockServerObjectHashtable = @{ - State = "Existing" - Name = $mockServerName - ServerInstances = $mockServerInstances - } + $script:mockMethodAlterRan = $false + $script:mockMethodAlterValue = '' - class service - { - [string]$Name - [string]$ServiceState - [string]$StartupParameters - } + #region Function mocks + $mockSmoWmiManagedComputer = { + $mockServerObjectHashtable = @{ + State = "Existing" + Name = $mockServerName + ServerInstances = $mockServerInstances + } - $Services = [System.Collections.ArrayList]::new() + class service + { + [string]$Name + [string]$ServiceState + [string]$StartupParameters + } - $service1 = [service]::new() - $service1.Name = $mockInstanceName1 - $service1.ServiceState = "Running" - $service1.StartupParameters = $mockStartupParametersInstance1 + $Services = [System.Collections.ArrayList]::new() - $Services.Add($service1) | Out-Null + $service1 = [service]::new() + $service1.Name = $mockInstanceName1 + $service1.ServiceState = "Running" + $service1.StartupParameters = $mockStartupParametersInstance1 - $service2 = [service]::new() - $service2.Name = $mockInstanceName1Agent - $service2.ServiceState = "Running" - $service2.StartupParameters = "" + $Services.Add($service1) | Out-Null - $Services.Add($service2) | Out-Null + $service2 = [service]::new() + $service2.Name = $mockInstanceName1Agent + $service2.ServiceState = "Running" + $service2.StartupParameters = "" - $service3 = [service]::new() - $service3.Name = 'MSSQL${0}' -f $mockInstanceName2 - $service3.ServiceState = "Running" - $service3.StartupParameters = $mockStartupParametersInstance2 + $Services.Add($service2) | Out-Null - $Services.Add($service3) | Out-Null + $service3 = [service]::new() + $service3.Name = 'MSSQL${0}' -f $mockInstanceName2 + $service3.ServiceState = "Running" + $service3.StartupParameters = $mockStartupParametersInstance2 - $service4 = [service]::new() - $service4.Name = 'SQLAgent${0}' -f $mockInstanceName2Agent - $service4.ServiceState = "Stopped" - $service4.StartupParameters = "" + $Services.Add($service3) | Out-Null - $Services.Add($service4) | Out-Null + $service4 = [service]::new() + $service4.Name = 'SQLAgent${0}' -f $mockInstanceName2Agent + $service4.ServiceState = "Stopped" + $service4.StartupParameters = "" - $ServerServices = [System.Collections.ArrayList]::new() + $Services.Add($service4) | Out-Null - foreach ($mockService in $Services) - { - $mockService | Add-Member -MemberType ScriptMethod -Name Alter -Value { - $script:mockMethodAlterRan = $true - $script:mockMethodAlterValue = $this.StartupParameters - } -PassThru - $ServerServices.Add( $mockService) | Out-Null - } + $ServerServices = [System.Collections.ArrayList]::new() - $mockServerObjectHashtable += @{ - Services = $ServerServices - } - $mockServerObject = [PSCustomObject]$mockServerObjectHashtable + foreach ($mockService in $Services) + { + $mockService | Add-Member -MemberType ScriptMethod -Name Alter -Value { + $script:mockMethodAlterRan = $true + $script:mockMethodAlterValue = $this.StartupParameters + } -PassThru + $ServerServices.Add( $mockService) | Out-Null + } - return @($mockServerObject) - } + $mockServerObjectHashtable += @{ + Services = $ServerServices + } + $mockServerObject = [PSCustomObject]$mockServerObjectHashtable - Describe "DSC_SqlTraceFlag\Get-TargetResource" -Tag 'Get' { - BeforeAll { + return @($mockServerObject) + } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -ParameterFilter $mockNewObject_ParameterFilter_RealServerName -Verifiable } @@ -235,6 +230,128 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Describe "DSC_SqlTraceFlag\Test-TargetResource" -Tag 'Test' { BeforeAll { + $mockServerName = 'TestServer' + $mockFakeServerName = 'FakeServer' + $mockInstanceName1 = 'MSSQLSERVER' + $mockInstanceName1Agent = 'SQLSERVERAGENT' + $mockInstanceName2 = 'INST00' + $mockInstanceName2Agent = 'SQLAgent$INST00' + $mockInstanceName3 = 'INST01' + $mockInstanceName3Agent = 'SQLAgent$INST01' + + $mockInvalidOperationForAlterMethod = $false + + $mockServerInstances = [System.Collections.ArrayList]::new() + $mockServerInstances.Add($mockInstanceName1) | Out-Null + $mockServerInstances.Add($mockInstanceName2) | Out-Null + + # The Trailing spaces in these here strings are ment to be there. Do not remove! + $mockStartupParametersInstance1 = @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802 +"@ + $mockStartupParametersInstance2 = @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf +"@ + + # Default parameters that are used for the It-blocks + $mockDefaultParameters1 = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockServerName + } + + $mockInst00Parameters = @{ + InstanceName = $mockInstanceName2 + ServerName = $mockServerName + } + + $mockInst01Parameters = @{ + InstanceName = $mockInstanceName3 + ServerName = $mockServerName + } + + $mockNonExistServerParameters = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockFakeServerName + } + + $mockNewObject_ParameterFilter_RealServerName = { + $ServerName -eq $mockServerName + } + + $mockNewObject_ParameterFilter_FakeServerName = { + $ServerName -eq $mockFakeServerName + } + + $script:mockMethodAlterRan = $false + $script:mockMethodAlterValue = '' + + #region Function mocks + $mockSmoWmiManagedComputer = { + $mockServerObjectHashtable = @{ + State = "Existing" + Name = $mockServerName + ServerInstances = $mockServerInstances + } + + class service + { + [string]$Name + [string]$ServiceState + [string]$StartupParameters + } + + $Services = [System.Collections.ArrayList]::new() + + $service1 = [service]::new() + $service1.Name = $mockInstanceName1 + $service1.ServiceState = "Running" + $service1.StartupParameters = $mockStartupParametersInstance1 + + $Services.Add($service1) | Out-Null + + $service2 = [service]::new() + $service2.Name = $mockInstanceName1Agent + $service2.ServiceState = "Running" + $service2.StartupParameters = "" + + $Services.Add($service2) | Out-Null + + $service3 = [service]::new() + $service3.Name = 'MSSQL${0}' -f $mockInstanceName2 + $service3.ServiceState = "Running" + $service3.StartupParameters = $mockStartupParametersInstance2 + + $Services.Add($service3) | Out-Null + + $service4 = [service]::new() + $service4.Name = 'SQLAgent${0}' -f $mockInstanceName2Agent + $service4.ServiceState = "Stopped" + $service4.StartupParameters = "" + + $Services.Add($service4) | Out-Null + + $ServerServices = [System.Collections.ArrayList]::new() + + foreach ($mockService in $Services) + { + $mockService | Add-Member -MemberType ScriptMethod -Name Alter -Value { + $script:mockMethodAlterRan = $true + $script:mockMethodAlterValue = $this.StartupParameters + } -PassThru + $ServerServices.Add( $mockService) | Out-Null + } + + $mockServerObjectHashtable += @{ + Services = $ServerServices + } + $mockServerObject = [PSCustomObject]$mockServerObjectHashtable + + return @($mockServerObject) + } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable } @@ -405,6 +522,128 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Describe "DSC_SqlTraceFlag\Set-TargetResource" -Tag 'Set' { BeforeAll { + $mockServerName = 'TestServer' + $mockFakeServerName = 'FakeServer' + $mockInstanceName1 = 'MSSQLSERVER' + $mockInstanceName1Agent = 'SQLSERVERAGENT' + $mockInstanceName2 = 'INST00' + $mockInstanceName2Agent = 'SQLAgent$INST00' + $mockInstanceName3 = 'INST01' + $mockInstanceName3Agent = 'SQLAgent$INST01' + + $mockInvalidOperationForAlterMethod = $false + + $mockServerInstances = [System.Collections.ArrayList]::new() + $mockServerInstances.Add($mockInstanceName1) | Out-Null + $mockServerInstances.Add($mockInstanceName2) | Out-Null + + # The Trailing spaces in these here strings are ment to be there. Do not remove! + $mockStartupParametersInstance1 = @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802 +"@ + $mockStartupParametersInstance2 = @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf +"@ + + # Default parameters that are used for the It-blocks + $mockDefaultParameters1 = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockServerName + } + + $mockInst00Parameters = @{ + InstanceName = $mockInstanceName2 + ServerName = $mockServerName + } + + $mockInst01Parameters = @{ + InstanceName = $mockInstanceName3 + ServerName = $mockServerName + } + + $mockNonExistServerParameters = @{ + InstanceName = $mockInstanceName1 + ServerName = $mockFakeServerName + } + + $mockNewObject_ParameterFilter_RealServerName = { + $ServerName -eq $mockServerName + } + + $mockNewObject_ParameterFilter_FakeServerName = { + $ServerName -eq $mockFakeServerName + } + + $script:mockMethodAlterRan = $false + $script:mockMethodAlterValue = '' + + #region Function mocks + $mockSmoWmiManagedComputer = { + $mockServerObjectHashtable = @{ + State = "Existing" + Name = $mockServerName + ServerInstances = $mockServerInstances + } + + class service + { + [string]$Name + [string]$ServiceState + [string]$StartupParameters + } + + $Services = [System.Collections.ArrayList]::new() + + $service1 = [service]::new() + $service1.Name = $mockInstanceName1 + $service1.ServiceState = "Running" + $service1.StartupParameters = $mockStartupParametersInstance1 + + $Services.Add($service1) | Out-Null + + $service2 = [service]::new() + $service2.Name = $mockInstanceName1Agent + $service2.ServiceState = "Running" + $service2.StartupParameters = "" + + $Services.Add($service2) | Out-Null + + $service3 = [service]::new() + $service3.Name = 'MSSQL${0}' -f $mockInstanceName2 + $service3.ServiceState = "Running" + $service3.StartupParameters = $mockStartupParametersInstance2 + + $Services.Add($service3) | Out-Null + + $service4 = [service]::new() + $service4.Name = 'SQLAgent${0}' -f $mockInstanceName2Agent + $service4.ServiceState = "Stopped" + $service4.StartupParameters = "" + + $Services.Add($service4) | Out-Null + + $ServerServices = [System.Collections.ArrayList]::new() + + foreach ($mockService in $Services) + { + $mockService | Add-Member -MemberType ScriptMethod -Name Alter -Value { + $script:mockMethodAlterRan = $true + $script:mockMethodAlterValue = $this.StartupParameters + } -PassThru + $ServerServices.Add( $mockService) | Out-Null + } + + $mockServerObjectHashtable += @{ + Services = $ServerServices + } + $mockServerObject = [PSCustomObject]$mockServerObjectHashtable + + return @($mockServerObject) + } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable Mock -CommandName Restart-SqlService -ModuleName $script:dscResourceName -Verifiable } diff --git a/tests/Unit/Stubs/New File.ps1 b/tests/Unit/Stubs/New File.ps1 deleted file mode 100644 index e69de29bb..000000000 From 8b603c3f47f5ba58f7f20ef06ffadc0450effd4d Mon Sep 17 00:00:00 2001 From: Fiander Date: Sat, 5 Dec 2020 12:15:15 +0100 Subject: [PATCH 15/28] last fixes --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 28 +++++++++---------- .../DSC_SqlTraceFlag.schema.mof | 2 +- .../en-US/DSC_SqlTraceFlag.strings.psd1 | 2 +- tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index b39c87db2..39e587d71 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -47,7 +47,7 @@ function Get-TargetResource if ($databaseEngineService) { - $actualTraceFlags = $databaseEngineService.StartupParameters.Split(';') | + $traceFlags = $databaseEngineService.StartupParameters.Split(';') | Where-Object -FilterScript { $PSItem -like '-T*' } | ForEach-Object { $PSItem.TrimStart('-T') @@ -68,7 +68,7 @@ function Get-TargetResource return @{ ServerName = $ServerName InstanceName = $InstanceName - TraceFlags = $actualTraceFlags + TraceFlags = $traceFlags TraceFlagsToInclude = $null TraceFlagsToExclude = $null RestartInstance = $null @@ -131,7 +131,7 @@ function Set-TargetResource [Parameter()] [System.Boolean] - $RestartInstance = $false + $RestartService = $false ) Write-Verbose -Message ( @@ -164,14 +164,14 @@ function Set-TargetResource else { $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - $actualTraceFlags = $getTargetResourceResult.TraceFlags - $wishTraceFlags.AddRange($actualTraceFlags) + + $wishTraceFlags.AddRange($getTargetResourceResult.TraceFlags) if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) { foreach ($traceFlagToInclude in $TraceFlagsToInclude) { - if ($actualTraceFlags -notcontains $traceFlagToInclude) + if ($getTargetResourceResult.TraceFlags -notcontains $traceFlagToInclude) { $wishTraceFlags.Add($traceFlagToInclude) } @@ -182,7 +182,7 @@ function Set-TargetResource { foreach ($traceFlagToExclude in $TraceFlagsToExclude) { - if ($actualTraceFlags -contains $traceFlagToExclude) + if ($getTargetResourceResult.TraceFlags -contains $traceFlagToExclude) { $wishTraceFlags.Remove([string]$traceFlagToExclude) } @@ -237,11 +237,11 @@ function Set-TargetResource $databaseEngineService.StartupParameters = $parameterList -join ';' $databaseEngineService.Alter() - if ($PSBoundParameters.ContainsKey('RestartInstance')) + if ($PSBoundParameters.ContainsKey('RestartService')) { - if ($RestartInstance -eq $true) + if ($RestartService -eq $true) { - $RestartTimeout = 10 + $RestartTimeout = 120 Restart-SqlService -ServerName $ServerName -InstanceName $InstanceName -Timeout $RestartTimeout } } @@ -272,7 +272,7 @@ function Set-TargetResource The TraceFlags the SQL server engine startup parameters should exclude. This parameter can not be used together with TraceFlags. - .PARAMETER RestartInstance + .PARAMETER RestartService If set, the sql server instance gets a reset after setting parameters. after restart the sql server agent is in the original state as before restart. #> @@ -306,7 +306,7 @@ function Test-TargetResource [Parameter()] [System.Boolean] - $RestartInstance = $false + $RestartService = $false ) Write-Verbose -Message ( @@ -345,13 +345,13 @@ function Test-TargetResource } else { - # Compare $TraceFlags to ActualTraceFlags to see if they contain the same values. + # Compare $TraceFlags to the Actual TraceFlags ($getTargetResourceResult.TraceFlags) to see if they contain the same values. $nullIfTheSame = Compare-Object -ReferenceObject $getTargetResourceResult.TraceFlags -DifferenceObject $TraceFlags if ($null -ne $nullIfTheSame) { Write-Verbose -Message ( $script:localizedData.DesiredTraceFlagNotPresent ` - -f $ServerRoleName + -f $($TraceFlags -join ','), $($getTargetResourceResult.TraceFlags -join ',') ) $isInDesiredState = $false diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof index e629ed9fb..0433f0564 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -6,5 +6,5 @@ class DSC_SqlTraceFlag : OMI_BaseResource [Write, Description("An array of trace flags that startup options should have. This parameter will replace all the current trace flags with the specified trace flags.")] Uint32 TraceFlags[]; [Write, Description("An array of trace flags to be added to the existing trace flags.")] Uint32 TraceFlagsToInclude[]; [Write, Description("An array of trace flags to be removed from the existing trace flags.")] Uint32 TraceFlagsToExclude[]; - [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartInstance; + [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartService; }; diff --git a/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 b/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 index bc2b61fe9..d96c193ea 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 +++ b/source/DSCResources/DSC_SqlTraceFlag/en-US/DSC_SqlTraceFlag.strings.psd1 @@ -4,7 +4,7 @@ ConvertFrom-StringData @' TestConfiguration = Determines the current state of the TraceFlags Compared to the desired TraceFlags '{0}'. NotConnectedToComputerManagement = Was unable to connect to ComputerManagement '{0}'. NotConnectedToWMI = Was unable to connect to WMI information '{0}' in '{1}'. - DesiredTraceFlagNotPresent = TraceFlag does not match the actual TraceFlags on the instance. + DesiredTraceFlagNotPresent = TraceFlag does not match the actual TraceFlags on the instance. Expected '{0}', but was '{1}'. TraceFlagPresent = traceflag {0} is present. TraceFlagNotPresent = traceflag {0} is not present. '@ diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index c978389fa..5254d7aac 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -821,4 +821,4 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 finally { Invoke-TestCleanup -} \ No newline at end of file +} From ba5ff81fc49515f39ee211202b180c92f51c6885 Mon Sep 17 00:00:00 2001 From: Fiander Date: Sat, 5 Dec 2020 13:50:41 +0100 Subject: [PATCH 16/28] Last changes. ( i hope ;-) ) --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 25 +++++++++++++++---- .../DSC_SqlTraceFlag.schema.mof | 1 + .../SqlTraceFlag/1-SetTraceFlags.ps1 | 2 +- .../2-SetTraceFlagsIncludeExclude.ps1 | 2 +- tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 2 +- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 39e587d71..bffbdbe5d 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -71,7 +71,7 @@ function Get-TargetResource TraceFlags = $traceFlags TraceFlagsToInclude = $null TraceFlagsToExclude = $null - RestartInstance = $null + RestartService = $null } } @@ -98,9 +98,13 @@ function Get-TargetResource The TraceFlags the SQL server engine startup parameters should exclude. This parameter can not be used together with TraceFlags. - .PARAMETER RestartInstance + .PARAMETER RestartService If set, the sql server instance gets a reset after setting parameters. after restart the sql server agent is in the original state as before restart. + + .PARAMETER RestartTimeout + The time the resource waits while the sql server services are restarted. + Defaults to 120 seconds. #> function Set-TargetResource { @@ -131,7 +135,11 @@ function Set-TargetResource [Parameter()] [System.Boolean] - $RestartService = $false + $RestartService = $false, + + [Parameter()] + [System.UInt32] + $RestartTimeout = 120 ) Write-Verbose -Message ( @@ -241,7 +249,6 @@ function Set-TargetResource { if ($RestartService -eq $true) { - $RestartTimeout = 120 Restart-SqlService -ServerName $ServerName -InstanceName $InstanceName -Timeout $RestartTimeout } } @@ -275,6 +282,10 @@ function Set-TargetResource .PARAMETER RestartService If set, the sql server instance gets a reset after setting parameters. after restart the sql server agent is in the original state as before restart. + + .PARAMETER RestartTimeout + The time the resource waits while the sql server services are restarted. + Defaults to 120 seconds. #> function Test-TargetResource { @@ -306,7 +317,11 @@ function Test-TargetResource [Parameter()] [System.Boolean] - $RestartService = $false + $RestartService = $false, + + [Parameter()] + [System.UInt32] + $RestartTimeout = 120 ) Write-Verbose -Message ( diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof index 0433f0564..f8d1bc58b 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.schema.mof @@ -7,4 +7,5 @@ class DSC_SqlTraceFlag : OMI_BaseResource [Write, Description("An array of trace flags to be added to the existing trace flags.")] Uint32 TraceFlagsToInclude[]; [Write, Description("An array of trace flags to be removed from the existing trace flags.")] Uint32 TraceFlagsToExclude[]; [Write, Description("Forces a restart of the Database Engine service and dependent services after the desired state is set. Default values is $false.")] Boolean RestartService; + [Write, Description("The time the resource waits while the sql server services are restarted. Defaults to 120 seconds")] Uint32 RestartTimeout; }; diff --git a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 index 1f08e9bfb..1bfa1f336 100644 --- a/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/1-SetTraceFlags.ps1 @@ -21,7 +21,7 @@ Configuration Example ServerName = 'sqltest.company.local' InstanceName = 'DSC' TraceFlags = 834, 1117, 1118, 2371, 3226 - RestartInstance = $true + RestartService = $true PsDscRunAsCredential = $SqlAdministratorCredential } diff --git a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 index 5963f35db..9e9a3ab6f 100644 --- a/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/2-SetTraceFlagsIncludeExclude.ps1 @@ -22,7 +22,7 @@ Configuration Example InstanceName = 'DSC' TraceFlagsToInclude = 834, 1117, 1118, 2371, 3226 TraceFlagsToExclude = 1112 - RestartInstance = $true + RestartService = $true PsDscRunAsCredential = $SqlAdministratorCredential } diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index 5254d7aac..7d5375c9f 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -738,7 +738,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226 $testParameters = $mockDefaultParameters1 $testParameters += @{ TraceFlags = '3228' - RestartInstance = $true + RestartService = $true } } From bd76c226e18a220572c4915ce86237a073f66c57 Mon Sep 17 00:00:00 2001 From: Fiander Date: Sat, 5 Dec 2020 14:52:49 +0100 Subject: [PATCH 17/28] mised a RestartService --- source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 index 6b2088fd4..41fb01f9d 100644 --- a/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 +++ b/source/Examples/Resources/SqlTraceFlag/3-RemoveTraceFlags.ps1 @@ -19,7 +19,7 @@ Configuration Example { ServerName = 'sqltest.company.local' InstanceName = 'DSC' - RestartInstance = $true + RestartService = $true TraceFlags = @() PsDscRunAsCredential = $SqlAdministratorCredential From 281d19bb69a0d89c66532360254e8a15e4e5fbb6 Mon Sep 17 00:00:00 2001 From: Fiander Date: Sat, 5 Dec 2020 19:58:47 +0100 Subject: [PATCH 18/28] Adden to SqlServerDsc and SqlTraceFlag get missed a return value --- source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 1 + source/SqlServerDsc.psd1 | 1 + 2 files changed, 2 insertions(+) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index bffbdbe5d..a766decb7 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -72,6 +72,7 @@ function Get-TargetResource TraceFlagsToInclude = $null TraceFlagsToExclude = $null RestartService = $null + RestartTimeout = $null } } diff --git a/source/SqlServerDsc.psd1 b/source/SqlServerDsc.psd1 index 5efb99c50..73234f008 100644 --- a/source/SqlServerDsc.psd1 +++ b/source/SqlServerDsc.psd1 @@ -74,6 +74,7 @@ 'SqlSecureConnection' 'SqlServiceAccount' 'SqlSetup' + 'SqlTraceFlag' 'SqlWaitForAG' 'SqlWindowsFirewall' ) From 5ac0c800754564f6a89c89b3cb512983f1da0ed1 Mon Sep 17 00:00:00 2001 From: Fiander Date: Fri, 29 Jan 2021 11:36:00 +0100 Subject: [PATCH 19/28] Fixed Assembly not loaded error #1680 --- CHANGELOG.md | 3 +++ source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9918fdd..ea37f0b64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- SqlTraceFlag + - Fixed Assembly not loaded error #1680 + ### Added - SqlServerDsc diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index a766decb7..614e5d72e 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -32,6 +32,9 @@ function Get-TargetResource $InstanceName ) + #Import SqlServer module but suppress verbose message. + Import-SQLPSModule 4>$null + Write-Verbose -Message ( $script:localizedData.GetConfiguration -f $InstanceName ) @@ -143,6 +146,9 @@ function Set-TargetResource $RestartTimeout = 120 ) + #Import SqlServer module but suppress verbose message. + Import-SQLPSModule 4>$null + Write-Verbose -Message ( $script:localizedData.SetConfiguration -f $InstanceName ) From c3ec2e28f8de3a261b4026e0ebf2005d2d1a122a Mon Sep 17 00:00:00 2001 From: Fiander Date: Fri, 29 Jan 2021 11:48:38 +0100 Subject: [PATCH 20/28] fix 1680 --- source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 24c0bdf28..fc0173b21 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -33,6 +33,9 @@ function Get-TargetResource $InstanceName ) + #Import SqlServer module but suppress verbose message. + Import-SQLPSModule 4>$null + Write-Verbose -Message ( $script:localizedData.GetConfiguration -f $InstanceName ) @@ -145,6 +148,9 @@ function Set-TargetResource $RestartTimeout = 120 ) + #Import SqlServer module but suppress verbose message. + Import-SQLPSModule 4>$null + Write-Verbose -Message ( $script:localizedData.SetConfiguration -f $InstanceName ) From df5f0f47a713551e1efa34aab0c10d1019fc4bd4 Mon Sep 17 00:00:00 2001 From: Fiander Date: Fri, 29 Jan 2021 20:29:52 +0100 Subject: [PATCH 21/28] Some small style fixes and a mock in test --- CHANGELOG.md | 3 ++- .../DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 8 ++++---- tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9240d4b60..8131255ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - SqlTraceFlag - - Fixed Assembly not loaded error. + - Fixed Assembly not loaded error ([issue #1680](https://github.com/dsccommunity/SqlServerDsc/issues/1680)). + ### Changed - SqlLogin diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index fc0173b21..63e3b61df 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -33,8 +33,8 @@ function Get-TargetResource $InstanceName ) - #Import SqlServer module but suppress verbose message. - Import-SQLPSModule 4>$null + # Import SqlServer module. + Import-SQLPSModule Write-Verbose -Message ( $script:localizedData.GetConfiguration -f $InstanceName @@ -148,8 +148,8 @@ function Set-TargetResource $RestartTimeout = 120 ) - #Import SqlServer module but suppress verbose message. - Import-SQLPSModule 4>$null + # Import SqlServer module. + Import-SQLPSModule Write-Verbose -Message ( $script:localizedData.SetConfiguration -f $InstanceName diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index 7d5375c9f..2516ed687 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -167,6 +167,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf return @($mockServerObject) } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -ParameterFilter $mockNewObject_ParameterFilter_RealServerName -Verifiable + Mock -CommandName Import-SQLPSModule -MockWith {return} } Context 'For the default instance' { @@ -353,6 +354,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf return @($mockServerObject) } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable + Mock -CommandName Import-SQLPSModule -MockWith {return} } Context 'When the system is not in the desired state and TraceFlags is empty' { From bb482621dde792186aa1e63032ceaa1fb0f212b0 Mon Sep 17 00:00:00 2001 From: Fiander Date: Sat, 30 Jan 2021 11:19:42 +0100 Subject: [PATCH 22/28] Fix in mock --- tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index 2516ed687..a8c8e4a54 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -167,7 +167,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf return @($mockServerObject) } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -ParameterFilter $mockNewObject_ParameterFilter_RealServerName -Verifiable - Mock -CommandName Import-SQLPSModule -MockWith {return} + Mock -CommandName Import-SQLPSModule } Context 'For the default instance' { @@ -354,7 +354,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf return @($mockServerObject) } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable - Mock -CommandName Import-SQLPSModule -MockWith {return} + Mock -CommandName Import-SQLPSModule } Context 'When the system is not in the desired state and TraceFlags is empty' { @@ -648,6 +648,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } Mock -CommandName New-Object -MockWith $mockSmoWmiManagedComputer -Verifiable Mock -CommandName Restart-SqlService -ModuleName $script:dscResourceName -Verifiable + Mock -CommandName Import-SQLPSModule } Context 'When the system is not in the desired state and ensure is set to Absent' { From 8c290fc558d1f9e80bac00a2557e3599b71b774b Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 11 Feb 2021 00:13:35 +0100 Subject: [PATCH 23/28] Fix for #1688 and aditional tests to find the problem. --- CHANGELOG.md | 2 + .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 14 ++++- tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 63 +++++++++++++++++-- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8131255ec..f39cb8c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SqlTraceFlag - Fixed Assembly not loaded error ([issue #1680](https://github.com/dsccommunity/SqlServerDsc/issues/1680)). + - Fixed $nul reference error when no actual traceflags are present + ([issue #1688](https://github.com/dsccommunity/SqlServerDsc/issues/1688)). ### Changed diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 63e3b61df..10a3e6e20 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -370,8 +370,20 @@ function Test-TargetResource } else { + $reference = [System.Collections.ArrayList]::new() + + if ($getTargetResourceResult.TraceFlags -ne $null) { + $reference.AddRange($getTargetResourceResult.TraceFlags) + } + + $difference = [System.Collections.ArrayList]::new() + + if ($TraceFlags -ne $null) { + $difference.AddRange($TraceFlags) + } + # Compare $TraceFlags to the Actual TraceFlags ($getTargetResourceResult.TraceFlags) to see if they contain the same values. - $nullIfTheSame = Compare-Object -ReferenceObject $getTargetResourceResult.TraceFlags -DifferenceObject $TraceFlags + $nullIfTheSame = Compare-Object -ReferenceObject $reference -DifferenceObject $difference if ($null -ne $nullIfTheSame) { Write-Verbose -Message ( diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index a8c8e4a54..5279894b1 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -357,7 +357,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Mock -CommandName Import-SQLPSModule } - Context 'When the system is not in the desired state and TraceFlags is empty' { + Context 'When the system is not in the desired state and TraceFlags is empty with existing traceflag' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ @@ -375,7 +375,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } } - Context 'When the system is in the desired state and TraceFlags is empty' { + Context 'When the system is in the desired state and TraceFlags is empty without existing traceflag' { BeforeAll { $testParameters = $mockInst00Parameters $testParameters += @{ @@ -393,7 +393,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } } - Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags' { + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags with existing traceflag' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ @@ -411,7 +411,25 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } } - Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude are not in the actual TraceFlags' { + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags without existing traceflag' { + BeforeAll { + $testParameters = $mockInst00Parameters + $testParameters += @{ + TraceFlags = '3228' + } + } + + It 'Should return false when Traceflags do not match the actual TraceFlags' { + $result = Test-TargetResource @testParameters + $result | Should -BeFalse + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude are not in the actual TraceFlags with existing traceflag' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ @@ -429,6 +447,24 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } } + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude are not in the actual TraceFlags without existing traceflag' { + BeforeAll { + $testParameters = $mockInst00Parameters + $testParameters += @{ + TraceFlagsToInclude = '3228' + } + } + + It 'Should return false when TraceflagsToInclude are not in the actual TraceFlags' { + $result = Test-TargetResource @testParameters + $result | Should -BeFalse + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } + Context 'When the system is in the desired state and ensure is set to Present and `$TraceFlagsToInclude are in the actual TraceFlags' { BeforeAll { $testParameters = $mockDefaultParameters1 @@ -465,7 +501,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } } - Context 'When the system is in the desired state and ensure is set to Present and `$TraceFlagsToExclude are not in the actual TraceFlags' { + Context 'When the system is in the desired state and ensure is set to Present and `$TraceFlagsToExclude are not in the actual TraceFlags with existing traceflag' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ @@ -483,6 +519,23 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf } } + Context 'When the system is in the desired state and ensure is set to Present and `$TraceFlagsToExclude are not in the actual TraceFlags without existing traceflag' { + BeforeAll { + $testParameters = $mockInst00Parameters + $testParameters += @{ + TraceFlagsToExclude = '3228' + } + } + + It 'Should return true when TraceflagsToExclude are not in the actual TraceFlags' { + $result = Test-TargetResource @testParameters + $result | Should -BeTrue + } + + It 'Should be executed once' { + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope Context + } + } Context 'When both the parameters TraceFlags and TraceFlagsToInclude are assigned a value.' { BeforeAll { From 16aff4ae64501e1d590def0455165e98cda8f9f7 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 11 Feb 2021 00:18:53 +0100 Subject: [PATCH 24/28] added entry for changelog.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa2f9f1d9..7a15e1c45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- SqlTraceFlag + - Fixed $nul reference error when no actual traceflags are present + ([issue #1688](https://github.com/dsccommunity/SqlServerDsc/issues/1688)). + ### Changed - SqlServerDsc From 50801adee5675a98848948bd3ee18234c7ac87d0 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 11 Feb 2021 00:32:44 +0100 Subject: [PATCH 25/28] beter changelog entry --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a15e1c45..b564f1be5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - SqlTraceFlag - - Fixed $nul reference error when no actual traceflags are present + - Fixed $nul reference error when no actual traceflags are present. + Added two arrays to prevent a $nul reference at compare-object. ([issue #1688](https://github.com/dsccommunity/SqlServerDsc/issues/1688)). ### Changed From c6fc0938e8397e3878941dddb30cb810908f6b56 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 11 Feb 2021 09:13:46 +0100 Subject: [PATCH 26/28] some HQRM fixes --- .../DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 | 16 +++-- tests/Unit/DSC_SqlTraceFlag.Tests.ps1 | 68 ++++++++++++++++++- 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 index 158d97e1b..f785b1b29 100644 --- a/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 +++ b/source/DSCResources/DSC_SqlTraceFlag/DSC_SqlTraceFlag.psm1 @@ -176,13 +176,19 @@ function Set-TargetResource if ($PSBoundParameters.ContainsKey('TraceFlags')) { - $wishTraceFlags.AddRange($TraceFlags) + if ($null -ne $TraceFlags) + { + $wishTraceFlags.AddRange($TraceFlags) + } } else { $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - $wishTraceFlags.AddRange($getTargetResourceResult.TraceFlags) + if ($null -ne $getTargetResourceResult.TraceFlags) + { + $wishTraceFlags.AddRange($getTargetResourceResult.TraceFlags) + } if ($PSBoundParameters.ContainsKey('TraceFlagsToInclude')) { @@ -373,13 +379,15 @@ function Test-TargetResource { $reference = [System.Collections.ArrayList]::new() - if ($getTargetResourceResult.TraceFlags -ne $null) { + if ($null -ne $getTargetResourceResult.TraceFlags) + { $reference.AddRange($getTargetResourceResult.TraceFlags) } $difference = [System.Collections.ArrayList]::new() - if ($TraceFlags -ne $null) { + if ($null -ne $TraceFlags) + { $difference.AddRange($TraceFlags) } diff --git a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 index 5279894b1..b1d923be5 100644 --- a/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 +++ b/tests/Unit/DSC_SqlTraceFlag.Tests.ps1 @@ -704,7 +704,7 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Mock -CommandName Import-SQLPSModule } - Context 'When the system is not in the desired state and ensure is set to Absent' { + Context 'When the system is not in the desired state and ensure is set to Absent with existing traceflag' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ @@ -723,10 +723,30 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It } + } + + Context 'When the system is not in the desired state and ensure is set to Absent without existing traceflag' { + BeforeAll { + $testParameters = $mockInst00Parameters + $testParameters += @{ + TraceFlags = '3228' + } + } + It 'Should not throw when calling the alter method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodAlterRan | Should -BeTrue -Because 'Alter should run' + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 +"@ -Because 'Alter must change the value correct' + + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It + } } - Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags' { + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags with existing traceflag' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ @@ -747,7 +767,28 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 } } - Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude is not in TraceFlags' { + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlags does not match the actual TraceFlags without existing traceflag' { + BeforeAll { + $testParameters = $mockInst00Parameters + $testParameters += @{ + TraceFlags = '3228' + } + } + + It 'Should not throw when calling the alter method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodAlterRan | Should -BeTrue -Because 'Alter should run' + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 +"@ -Because 'Alter must change the value correct' + + Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It + } + } + + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude is not in TraceFlags with existing traceflag' { BeforeAll { $testParameters = $mockDefaultParameters1 $testParameters += @{ @@ -768,6 +809,27 @@ Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3226;-T1802;-T3228 } } + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToInclude is not in TraceFlags without existing traceflag' { + BeforeAll { + $testParameters = $mockInst00Parameters + $testParameters += @{ + TraceFlagsToInclude = '3228' + } + } + + It 'Should not throw when calling the alter method' { + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodAlterRan | Should -BeTrue + $script:mockMethodAlterValue | Should -Be @" +-dC:\Program Files\Microsoft SQL Server\MSSQL15.INST00\MSSQL\DATA\master.mdf;-eC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\Log\ERRORLOG;-lC:\Program Files\Microsoft SQL +Server\MSSQL15.INST00\MSSQL\DATA\mastlog.ldf;-T3228 +"@ + + Assert-MockCalled -CommandName New-Object -Exactly -Times 2 -Scope It + } + } + Context 'When the system is not in the desired state and ensure is set to Present and `$TraceFlagsToExclude is in TraceFlags' { BeforeAll { $testParameters = $mockDefaultParameters1 From d1c5769bf771911a0a4a1dade215840208abd582 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 11 Feb 2021 18:39:28 +0100 Subject: [PATCH 27/28] fix changelog.md --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b564f1be5..f9524b3bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed $nul reference error when no actual traceflags are present. Added two arrays to prevent a $nul reference at compare-object. ([issue #1688](https://github.com/dsccommunity/SqlServerDsc/issues/1688)). +- SqlServerDsc + - Removed a left-over comment in the file `analyzersettings.psd1`. + +## [15.1.0] - 2021-02-02 + +### Added + +- SqlServerDsc + - Added a new script analyzer rule to verify that `Import-SQLPSModule` or `Connect-SQL` + (that implicitly calls `Import-SQLPSModule`) is present in each `Get-`, `Test-`, + and `Set-TargetResource` function. If neither command is not needed then the + analyzer rule should be overridden ([issue #1683](https://github.com/dsccommunity/SqlServerDsc/issues/1683)). + - Added a new pipeline job that runs Script Analyzer on all PowerShell scripts + in the source folder. The rules are defined by the Script Analyzer settings + file `.vscode\analyzersettings.psd1` (which also the Visual Studio Code + PowerShell extension uses). + - Added unit tests and integration tests for SQL Server 2019 + ([issue #1310](https://github.com/dsccommunity/SqlServerDsc/issues/1310)). ### Changed From c250c97efff5cedcde63cbb14232c5371965b9b1 Mon Sep 17 00:00:00 2001 From: Fiander Date: Thu, 11 Feb 2021 18:40:44 +0100 Subject: [PATCH 28/28] take two --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9524b3bd..4ff3b6a12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + - SqlTraceFlag - Fixed $nul reference error when no actual traceflags are present. Added two arrays to prevent a $nul reference at compare-object.