From fe33a9df8d9498bf6bc9658f2244dae0ad095833 Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Fri, 25 Jun 2021 17:35:10 -0500 Subject: [PATCH 1/8] initial sync and core configuration --- source/ConfigMgrCBDsc.psd1 | 3 +- .../DSC_CMEmailNotificationComponent.psm1 | 400 +++++++++++ ...SC_CMEmailNotificationComponent.schema.mof | 12 + ..._CMEmailNotificationComponent.strings.psd1 | 16 + .../CMEmailNotificationComponent_Absent.ps1 | 17 + .../CMEmailNotificationComponent_Present.ps1 | 23 + .../CMEmailNotificationComponent.tests.ps1 | 665 ++++++++++++++++++ 7 files changed, 1135 insertions(+), 1 deletion(-) create mode 100644 source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 create mode 100644 source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof create mode 100644 source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 create mode 100644 source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 create mode 100644 source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Present.ps1 create mode 100644 tests/Unit/CMEmailNotificationComponent.tests.ps1 diff --git a/source/ConfigMgrCBDsc.psd1 b/source/ConfigMgrCBDsc.psd1 index 0b088ba..f5ba66d 100644 --- a/source/ConfigMgrCBDsc.psd1 +++ b/source/ConfigMgrCBDsc.psd1 @@ -79,6 +79,7 @@ 'CMSoftwareDistributionComponent' 'CMMaintenanceWindows' 'CMFileReplication' + 'CMEmailNotificationComponent' ) <# @@ -97,7 +98,7 @@ 'ServiceConnectionPoint','NetworkDiscovery','ReportingServicePoint','SystemDiscovery','PXEDistributionPoint','PullDistributionPoint', 'SiteMaintenance','AdministrativeUser','DistributionGroup','SiteSystemServer','StatusReportingComponent','CollectionMembershipEvaluationComponent', 'DistributionPointGroupMembers','SecurityScopes','UserDiscovery','SecurityRoles','ClientPushSettings','SoftwareDistributionComponent', - 'MaintenanceWindows','FileReplication') + 'MaintenanceWindows','FileReplication','EmailNotificationComponent') # A URL to the license for this module. LicenseUri = 'https://github.com/dsccommunity/ConfigMgrCBDsc/blob/master/LICENSE' diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 new file mode 100644 index 0000000..5387693 --- /dev/null +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 @@ -0,0 +1,400 @@ +$script:dscResourceCommonPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' +$script:configMgrResourcehelper = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\ConfigMgrCBDsc.ResourceHelper' + +Import-Module -Name $script:dscResourceCommonPath +Import-Module -Name $script:configMgrResourcehelper + +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' + +<# + .SYNOPSIS + This will return a hashtable of results. + + .PARAMETER SiteCode + Specifies the SiteCode for the Configuration Manager site. + + .PARAMETER Enabled + Specifies if email notifications are enable or disable. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter(Mandatory = $true)] + [Boolean] + $Enabled + ) + + Write-Verbose -Message $script:localizedData.RetrieveSettingValue + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + + $emailProps = (Get-CMEmailNotificationComponent -SiteCode $SiteCode).Props + + if (($emailProps.Where({$_.PropertyName -eq 'EnableSmtpSetting'})).Value -eq 1) + { + foreach ($emailProp in $emailProps) + { + switch ($emailProp.PropertyName) + { + 'Port' { $portValue = $emailProp.Value } + 'SendFrom' { $sendFromValue = $emailProp.Value1 } + 'ServerFqdn' { $smtpServerFqdnValue = $emailProp.Value1 } + 'AuthenticationMethod' { $authValue = @('Anonymous','DefaultServiceAccount','Other')[($emailProp.Value)] } + 'UseSsl' { [boolean]$useSslValue = $emailProp.Value } + } + } + + if ($authValue -eq 'Other') + { + $userNameValue = ($emailProps.Where({$_.PropertyName -eq 'UserName'})).Value1 + } + + $enabledValue = $true + } + else + { + $enabledValue = $false + } + + return @{ + SiteCode = $SiteCode + UserName = $userNameValue + Port = $portValue + SendFrom = $sendFromValue + SmtpServerFqdn = $smtpServerFqdnValue + TypeOfAuthentication = $authValue + UseSsl = $useSslValue + Enabled = $enabledValue + } +} + +<# + .SYNOPSIS + This will set the desired state. + + .PARAMETER SiteCode + Specifies the SiteCode for the Configuration Manager site. + + .PARAMETER Enabled + Specifies if email notifications are enable or disable. + + .PARAMETER ServerFqdn + Specifies the FQDN of the site server that will send e-mail. + + .PARAMETER SendFrom + Specifies the address used to send mail. + + .PARAMETER Port + Specifies the port used to send mail. + + .PARAMETER UserName + Specifies the username for authenticating against an SMTP server. + + .PARAMETER UseSSL + Specifies whether to use SSL for email alerts. If omitted, the assumed intent is that SSL is not to be used. + + .PARAMETER TypeOfAuthentication + Specifies the method by which Configuration Manager authenticates the site server to the SMTP Server. + The acceptable values for this parameter are: Anonymous, DefaultServiceAccount, Other +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter(Mandatory = $true)] + [Boolean] + $Enabled, + + [Parameter()] + [String] + $SmtpServerFqdn, + + [Parameter()] + [String] + $SendFrom, + + [Parameter()] + [UInt32] + $Port, + + [Parameter()] + [String] + $Username, + + [Parameter()] + [Boolean] + $UseSsL, + + [Parameter()] + [ValidateSet('Anonymous','DefaultServiceAccount','Other')] + [String] + $TypeOfAuthentication + ) + + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + $state = Get-TargetResource -SiteCode $SiteCode -Enabled $Enabled + + try + { + if ($Enabled -eq $true) + { + if ([string]::IsNullOrEmpty($SmtpServerFqdn) -or [string]::IsNullOrEmpty($TypeOfAuthentication) -or + [string]::IsNullOrEmpty($SendFrom)) + { + throw $script:localizedData.MissingParams + } + + if ($Username -and $TypeOfAuthentication -ne 'Other') + { + throw $script:localizedData.UserAuthNotOther + } + + if ($TypeOfAuthentication -eq 'Other' -and [string]::IsNullOrEmpty($Username)) + { + throw $script:localizedData.AuthOtherNoUser + } + + if ($PSBoundParameters.ContainsKey('UseSsl')) + { + if (($state.UseSSL -eq $false -and $useSSL -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) + { + Write-Warning -Message $script:localizedData.SSLTrueNoPort + } + + if (($state.UseSSL -eq $true -and $UseSsL -eq $false) -and -not $PSBoundParameters.ContainsKey('Port')) + { + Write-Warning -Message $script:localizedData.SSLFalseNoPort + } + + if ($UseSsL -eq $true -and $Port -eq 25) + { + throw $script:localizedData.SslBadPort + } + + if (($UseSsL -eq $false) -and ($Port -eq '465')) + { + throw $script:localizedData.NonSslBadPort + } + } + + foreach ($param in $PSBoundParameters.GetEnumerator()) + { + if ($param.Key -ne 'SiteCode') + { + if ($param.Value -ne $state[$param.key]) + { + Write-Verbose -Message ($script:localizedData.SettingValue -f $param.key, $param.Value) + } + + if ($param.Key -ne 'Enabled') + { + $buildingParams += @{ + $param.key = $param.Value + } + } + } + } + + if ($buildingParams) + { + if ($buildingParams.ContainsKey('UserName')) + { + $validateAccount = Get-CMAccount -UserName $Username -SiteCode $SiteCode + + if ([string]::IsNullOrEmpty($validateAccount)) + { + throw ($script:localizedData.AbsentUsername -f $Username) + } + } + + Set-CMEmailNotificationComponent -EnableEmailNotification @buildingParams + } + } + elseif ($state.Enabled -eq $true) + { + Write-Verbose -Message $script:localizedData.Disabled + Set-CMEmailNotificationComponent -DisableEmailNotification + } + } + catch + { + throw $_ + } + finally + { + Set-Location -Path $env:windir + } +} + +<# + .SYNOPSIS + This will test the desired state. + + .PARAMETER SiteCode + Specifies the SiteCode for the Configuration Manager site. + + .PARAMETER Enabled + Specifies if email notifications are enable or disable. + + .PARAMETER ServerFqdn + Specifies the FQDN of the site server that will send e-mail. + + .PARAMETER SendFrom + Specifies the address used to send mail. + + .PARAMETER Port + Specifies the port used to send mail. + + .PARAMETER UserName + Specifies the username for authenticating against an SMTP server. Only used when TypeOfAuthentication + equals Other. + + .PARAMETER UseSSL + Specifies whether to use SSL for email alerts. If omitted, the assumed intent is that SSL is not to be used. + + .PARAMETER TypeOfAuthentication + Specifies the method by which Configuration Manager authenticates the site server to the SMTP Server. + The acceptable values for this parameter are: Anonymous, DefaultServiceAccount, Other +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter(Mandatory = $true)] + [Boolean] + $Enabled, + + [Parameter()] + [String] + $SmtpServerFqdn, + + [Parameter()] + [String] + $SendFrom, + + [Parameter()] + [UInt32] + $Port, + + [Parameter()] + [String] + $Username, + + [Parameter()] + [Boolean] + $UseSsL, + + [Parameter()] + [ValidateSet('Anonymous','DefaultServiceAccount','Other')] + [String] + $TypeOfAuthentication + ) + + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + $state = Get-TargetResource -SiteCode $SiteCode -Enabled $Enabled + $result = $true + $testResult = $true + + if ($Enabled -eq $true) + { + if ([string]::IsNullOrEmpty($SmtpServerFqdn) -or [string]::IsNullOrEmpty($TypeOfAuthentication) -or + [string]::IsNullOrEmpty($SendFrom)) + { + Write-Warning -Message $script:localizedData.MissingParams + $result = $false + } + + if ($TypeOfAuthentication -ne 'Other' -and $Username) + { + Write-Warning -Message $script:localizedData.UserAuthNotOther + $result = $false + } + + if ($TypeOfAuthentication -eq 'Other' -and [string]::IsNullOrEmpty($Username)) + { + Write-Warning -Message $script:localizedData.AuthOtherNoUser + $result = $false + } + + if ($PSBoundParameters.ContainsKey('UseSsl')) + { + if (($state.UseSSL -eq $false -and $useSSL -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) + { + Write-Warning -Message $script:localizedData.SSLTrueNoPort + } + + if (($state.UseSSL -eq $true -and $UseSsL -eq $false) -and -not $PSBoundParameters.ContainsKey('Port')) + { + Write-Warning -Message $script:localizedData.SSLFalseNoPort + } + + if ($UseSsL -eq $true -and $Port -eq 25) + { + Write-Warning -Message $script:localizedData.SslBadPort + $result = $false + } + + if (($UseSsL -eq $false) -and ($Port -eq 465)) + { + Write-Warning -Message $script:localizedData.NonSslBadPort + $result = $false + } + } + + if ($state.Enabled -eq $false) + { + Write-Verbose -Message $script:localizedData.Enabled + $result = $false + } + else + { + $testParams = @{ + CurrentValues = $state + DesiredValues = $PSBoundParameters + ValuesToCheck = @('Enabled','SmtpServerFqdn','SendFrom','Port', + 'Username','UseSsL','TypeOfAuthentication') + } + + $testResult = Test-DscParameterState @testParams -Verbose -TurnOffTypeChecking + } + } + elseif ($state.Enabled -eq $true) + { + Write-Verbose -Message $script:localizedData.Disabled + $result = $false + } + + if ($result -eq $false -or $testResult -eq $false) + { + $finalResult = $false + } + else + { + $finalResult = $true + } + + Write-Verbose -Message ($script:localizedData.TestState -f $finalResult) + return $finalResult +} + +Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof new file mode 100644 index 0000000..264aae3 --- /dev/null +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof @@ -0,0 +1,12 @@ +[ClassVersion("1.0.0"), FriendlyName("CMEmailNotificationComponent")] +class DSC_CMEmailNotificationComponent : OMI_BaseResource +{ + [Key, Description("Specifies the SiteCode for the Configuration Manager site.")] String SiteCode; + [Key, Description("Specifies if email notifications are enable or disable.")] Boolean Enabled; + [Write, Description("Specifies the FQDN of the site server that will send e-mail.")] String SmtpServerFqdn; + [Write, Description("Specifies the address used to send mail.")] String SendFrom; + [Write, Description("Specifies the port used to send mail.")] UInt32 Port; + [Write, Description("Specifies the username for authenticating against an SMTP server. Only used when AuthenticationMethod equals Other")] String UserName; + [Write, Description("Specifies whether to use SSL for email alerts. If omitted, the assumed intent is that SSL is not to be used.")] Boolean UseSSL; + [Write, Description("Specifies the method by which Configuration Manager authenticates the site server to the SMTP Server."), ValueMap{"Anonymous","DefaultServiceAccount","Other"}, Values{"Anonymous","DefaultServiceAccount","Other"}] String TypeOfAuthentication; +}; diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 new file mode 100644 index 0000000..c281364 --- /dev/null +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 @@ -0,0 +1,16 @@ +ConvertFrom-StringData @' + RetrieveSettingValue = Getting results for Configuration Manager accounts. + DesiredState = Setting is already in desired state. + TestState = Test-TargetResource compliance check returned: {0}. + Enabled = NOTMATCH: Value for property Enabled does not match. Current State is False and desired state is True. + Disabled = NOTMATCH: Value for property Enabled does not match. Current State is True and desired state is False. + SettingValue = Setting value: {0} to {1}. + MissingParams = When specifying Enabled equals true you must specify SmtpServerFqdn, Sendfrom, and TypeOfAuthentication. + UserAuthNotOther = When specifying UserName you must set TypeOfAuthentication to Other. + AuthOtherNoUser = When setting TypeOfAuthentication to Other, you must specify UserName. + SslTrueNoPort = Changing UseSSL from false to true and no port was specified, the Port will automatically be changed to 465. + SslFalseNoPort = Chaning UseSSL from true to false and no port was specified, the Port will automatically be changed to 25 + SslBadPort = When using SSL, you must specify a port other than the default non-SSL port 25. + NonSslBadPort = When not using SSL, you must specify a port other than the default SSL port 465. + AbsentUsername = UserAccount specifed {0} does not exist in Configuration Manager and will need to be created prior to adding as the connection account. +'@ diff --git a/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 b/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 new file mode 100644 index 0000000..713f780 --- /dev/null +++ b/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 @@ -0,0 +1,17 @@ +<# + .SYNOPSIS + A DSC configuration script to disabled email notification component in Configuration Manager. +#> +Configuration Example +{ + Import-DscResource -ModuleName ConfigMgrCBDsc + + Node localhost + { + CMEmailNotificationComponent ExampleSettings + { + SiteCode = 'Lab' + Enabled = $false + } + } +} diff --git a/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Present.ps1 b/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Present.ps1 new file mode 100644 index 0000000..daded9a --- /dev/null +++ b/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Present.ps1 @@ -0,0 +1,23 @@ +<# + .SYNOPSIS + A DSC configuration script to enable email notification component in Configuration Manager. +#> +Configuration Example +{ + Import-DscResource -ModuleName ConfigMgrCBDsc + + Node localhost + { + CMEmailNotificationComponent ExampleSettings + { + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Other' + Port = 465 + UseSsl = $true + Enabled = $true + UserName = 'contoso\EmailUser' + } + } +} diff --git a/tests/Unit/CMEmailNotificationComponent.tests.ps1 b/tests/Unit/CMEmailNotificationComponent.tests.ps1 new file mode 100644 index 0000000..f1eac48 --- /dev/null +++ b/tests/Unit/CMEmailNotificationComponent.tests.ps1 @@ -0,0 +1,665 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param () + +$script:dscModuleName = 'ConfigMgrCBDsc' +$script:dscResourceName = 'DSC_CMEmailNotificationComponent' + +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' + + # Import Stub function + $script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\ConfigMgrCBDscStub.psm1') -Force -WarningAction SilentlyContinue +} + +function Invoke-TestCleanup +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} + +Invoke-TestSetup + +# Begin Testing +try +{ + InModuleScope $script:dscResourceName { + Describe 'ConfigMgrCBDsc - DSC_CMEmailNotificationComponent\Get-TargetResource' -Tag 'Get' { + BeforeAll { + Mock -CommandName Import-ConfigMgrPowerShellModule + Mock -CommandName Set-Location + } + + Context 'When retrieving email notification component' { + BeforeEach { + $getCMReturn = @{ + ItemName = 'SMS_ALERT_NOTIFICATION|SMS Site Server' + ItemType = 'Component' + Name = 'SMS Site Server' + SiteCode = 'LAB' + Props = @( + @{ + PropertyName = 'EnableSmtpSetting' + Value = 1 + } + @{ + PropertyName = 'Port' + Value = 25 + } + @{ + PropertyName = 'SendFrom' + Value1 = 'emailsender@contoso.com' + } + @{ + PropertyName = 'ServerFqdn' + Value1 = 'EmailServer.contoso.com' + } + @{ + PropertyName = 'AuthenticationMethod' + Value = 0 + } + @{ + PropertyName = 'UseSsl' + Value = $false + } + @{ + PropertyName = 'UserName' + Value1 = 'contoso\EmailUser' + } + ) + } + + $getCMReturnDisabled = @{ + ItemName = 'SMS_ALERT_NOTIFICATION|SMS Site Server' + ItemType = 'Component' + Name = 'SMS Site Server' + SiteCode = 'LAB' + Props = @( + @{ + PropertyName = 'EnableSmtpSetting' + Value = 0 + } + ) + } + + $getCMReturnOther = @{ + ItemName = 'SMS_ALERT_NOTIFICATION|SMS Site Server' + ItemType = 'Component' + Name = 'SMS Site Server' + SiteCode = 'LAB' + Props = @( + @{ + PropertyName = 'EnableSmtpSetting' + Value = 1 + } + @{ + PropertyName = 'Port' + Value = 446 + } + @{ + PropertyName = 'SendFrom' + Value1 = 'emailsender@contoso.com' + } + @{ + PropertyName = 'ServerFqdn' + Value1 = 'EmailServer.contoso.com' + } + @{ + PropertyName = 'AuthenticationMethod' + Value = 2 + } + @{ + PropertyName = 'UseSsl' + Value = $true + } + @{ + PropertyName = 'UserName' + Value1 = 'contoso\EmailUser' + } + ) + } + + $getInput = @{ + SiteCode = 'Lab' + Enabled = $true + } + } + + It 'Should return desired result when enabled and Type of Authentication equals Anonymous' { + Mock -CommandName Get-CMEmailNotificationComponent -MockWith { $getCMReturn } + + $result = Get-TargetResource @getInput + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.Enabled | Should -Be -ExpectedValue $true + $result.TypeOfAuthentication | Should -Be -ExpectedValue 'Anonymous' + $result.SmtpServerFqdn | Should -Be -ExpectedValue 'EmailServer.contoso.com' + $result.SendFrom | Should -Be -ExpectedValue 'emailsender@contoso.com' + $result.UserName | Should -Be -ExpectedValue $null + $result.Port | Should -Be -ExpectedValue 25 + $result.UseSsl | Should -Be -ExpectedValue $false + } + + It 'Should return desired result when enabled and Type of Authentication equals other' { + Mock -CommandName Get-CMEmailNotificationComponent -MockWith { $getCMReturnOther } + + $result = Get-TargetResource @getInput + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.Enabled | Should -Be -ExpectedValue $true + $result.TypeOfAuthentication | Should -Be -ExpectedValue 'Other' + $result.SmtpServerFqdn | Should -Be -ExpectedValue 'EmailServer.contoso.com' + $result.SendFrom | Should -Be -ExpectedValue 'emailsender@contoso.com' + $result.UserName | Should -Be -ExpectedValue 'contoso\EmailUser' + $result.Port | Should -Be -ExpectedValue 446 + $result.UseSsl | Should -Be -ExpectedValue $true + } + + It 'Should return desired result when disabled' { + Mock -CommandName Get-CMEmailNotificationComponent -MockWith { $getCMReturnDisabled } + + $result = Get-TargetResource @getInput + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.Enabled | Should -Be -ExpectedValue $false + $result.TypeOfAuthentication | Should -Be -ExpectedValue $null + $result.SmtpServerFqdn | Should -Be -ExpectedValue $null + $result.SendFrom | Should -Be -ExpectedValue $null + $result.UserName | Should -Be -ExpectedValue $null + $result.Port | Should -Be -ExpectedValue $null + $result.UseSsl | Should -Be -ExpectedValue $null + } + } + } + + Describe 'ConfigMgrCBDsc - DSC_CMEmailNotificationComponent\Set-TargetResource' -Tag 'Set' { + BeforeAll { + $getReturnPresentSsl = @{ + SiteCode = 'Lab' + UserName = 'contoso\EmailUser' + Port = 446 + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Other' + UseSsl = $true + Enabled = $true + } + + $getReturnPresentNonSsl = @{ + SiteCode = 'Lab' + UserName = $null + Port = 25 + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Anonymous' + UseSsl = $false + Enabled = $true + } + + $getReturnedAbsent = @{ + SiteCode = 'Lab' + UserName = $null + Port = $null + SendFrom = $null + SmtpServerFqdn = $null + TypeOfAuthentication = $null + UseSsl = $null + Enabled = $false + } + + $inputChangingAuth = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Other' + UserName = 'contoso\EmailUser' + Enabled = $true + } + + Mock -CommandName Import-ConfigMgrPowerShellModule + Mock -CommandName Set-Location + Mock -CommandName Set-CMEmailNotificationComponent + } + + Context 'When Set-TargetResource runs successfully' { + BeforeEach { + $inputAbsent = @{ + SiteCode = 'Lab' + Enabled = $false + } + + $inputPresent = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Anonymous' + Enabled = $true + } + + $inputSwitchSslToFalse = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + UseSsl = $false + Enabled = $true + } + + $inputSwitchSslToTrue = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + UseSsl = $true + Enabled = $true + } + + Mock -CommandName Get-CMAccount -MockWith { $true } + } + + It 'Should return desired result when disabling email notifcations settings' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Set-TargetResource @inputAbsent + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return desired result when enabling email notifications' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + Set-TargetResource @inputPresent + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return desired result when changing email notification settings' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Set-TargetResource @inputPresent + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return desired result when changing ssl settings to false and not specifying a port' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Set-TargetResource @inputSwitchSslToFalse + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return desired result when changing ssl settings to true and not specifying a port' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + + Set-TargetResource @inputSwitchSslToTrue + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return desired result when adding a UserName with correct TypeOfAuthentication' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + + Set-TargetResource @inputChangingAuth + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 1 -Scope It + } + } + + Context 'When Set-TargetResource throws' { + BeforeEach { + Mock -CommandName Get-CMAccount + $absentUsername = 'UserAccount specifed contoso\EmailUser does not exist in Configuration Manager and will need to be created prior to adding as the connection account.' + + $inputMissingCore = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + TypeOfAuthentication = 'Anonymous' + Enabled = $true + } + + $missingParams = 'When specifying Enabled equals true you must specify SmtpServerFqdn, Sendfrom, and TypeOfAuthentication.' + + $inputAuthenticationMisMatch = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Anonymous' + UserName = 'contoso\EmailUser' + Enabled = $true + } + + $userAuthNotOther = 'When specifying UserName you must set TypeOfAuthentication to Other.' + + $inputMissingUserName = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Other' + Enabled = $true + } + + $authOtherNoUser = 'When setting TypeOfAuthentication to Other, you must specify UserName.' + + $inputSslPortforSslFalse = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 465 + UseSsl = $false + Enabled = $true + } + + $nonSslBadPort = 'When not using SSL, you must specify a port other than the default SSL port 465.' + + $inputNoneSslPortforSslTrue = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 25 + UseSsl = $true + Enabled = $true + } + + $sslBadPort = 'When using SSL, you must specify a port other than the default non-SSL port 25.' + } + + It 'Should return throw Username specifed does not exist in Confiuration Manager' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + { Set-TargetResource @inputChangingAuth } | Should -Throw -ExpectedMessage $absentUsername + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 1 -Scope It + } + + It 'Should return throw when enabling and core components are not specified' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + { Set-TargetResource @inputMissingCore } | Should -Throw -ExpectedMessage $missingParams + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return throw when Username is specified and TypeOfAuthentication is not set to other' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + Mock -CommandName Get-CMAccount -MockWith { $null } + + { Set-TargetResource @inputAuthenticationMisMatch } | Should -Throw -ExpectedMessage $userAuthNotOther + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return throw when TypeOfAuthentication is set to other and Username is not specified' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + Mock -CommandName Get-CMAccount -MockWith { $null } + + { Set-TargetResource @inputMissingUserName } | Should -Throw -ExpectedMessage $authOtherNoUser + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return throw when setting SSL to true and specifying the default non SSL port' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + Mock -CommandName Get-CMAccount -MockWith { $null } + + { Set-TargetResource @inputNoneSslPortforSslTrue } | Should -Throw -ExpectedMessage $sslBadPort + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return throw when setting SSL to disabled and specifying the default SSL port' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + Mock -CommandName Get-CMAccount -MockWith { $null } + + { Set-TargetResource @inputSslPortforSslFalse } | Should -Throw -ExpectedMessage $nonSslBadPort + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + } + } + + Describe 'ConfigMgrCBDsc - DSC_CMEmailNotificationComponent\Test-TargetResource' -Tag 'Test' { + BeforeAll { + $getReturnPresentSsl = @{ + SiteCode = 'Lab' + UserName = 'contoso\EmailUser' + Port = 446 + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Other' + UseSsl = $true + Enabled = $true + } + + $getReturnPresentNonSsl = @{ + SiteCode = 'Lab' + UserName = $null + Port = 25 + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Anonymous' + UseSsl = $false + Enabled = $true + } + + $getReturnedAbsent = @{ + SiteCode = 'Lab' + UserName = $null + Port = $null + SendFrom = $null + SmtpServerFqdn = $null + TypeOfAuthentication = $null + UseSsl = $null + Enabled = $false + } + + Mock -CommandName Set-Location + Mock -CommandName Import-ConfigMgrPowerShellModule + } + + Context 'When running Test-TargetResource' { + BeforeEach { + $inputAbsent = @{ + SiteCode = 'Lab' + Enabled = $false + } + + $inputPresent = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Anonymous' + Enabled = $true + } + } + + It 'Should return desired result true when Enabled = false and desired is false' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + Test-TargetResource @inputAbsent | Should -Be $true + } + + It 'Should return desired result false when enabled = false and desired is true' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + Test-TargetResource @inputPresent | Should -Be $false + } + + It 'Should return desired result false when enabled = true and desired is false' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + + Test-TargetResource @inputAbsent | Should -Be $false + } + + It 'Should return desired result false when settings do not match' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Test-TargetResource @inputPresent | Should -Be $false + } + } + + Context 'When running Test-TargetResource for Write-Warning validations' { + BeforeEach { + $inputMissingCore = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + TypeOfAuthentication = 'Anonymous' + Enabled = $true + } + + $inputAuthenticationMisMatch = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Anonymous' + UserName = 'contoso\EmailUser' + Enabled = $true + } + + $inputMissingUserName = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Other' + Enabled = $true + } + + $inputSwitchSslToFalse = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + UseSsl = $false + Enabled = $true + } + + $inputSwitchSslToTrue = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + UseSsl = $true + Enabled = $true + } + + $inputSslPortforSslFalse = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 465 + UseSsl = $false + Enabled = $true + } + + $inputNoneSslPortforSslTrue = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 25 + UseSsl = $true + Enabled = $true + } + } + + It 'Should return desired result false when Enabled and missing core components for enabled equals True' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + Test-TargetResource @inputMissingCore | Should -Be $false + } + + It 'Should return desired result false when specifying Username and TypeOfAuthentication does not equal Other' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + Test-TargetResource @inputAuthenticationMisMatch | Should -Be $false + } + + It 'Should return desired result false when specifying TypeOfAuthentication as other and not specifying a UserName' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedAbsent } + + Test-TargetResource @inputMissingUserName | Should -Be $false + } + + It 'Should return desired result false when switching SSL to false and not specifying a port ' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Test-TargetResource @inputSwitchSslToFalse | Should -Be $false + } + + It 'Should return desired result false when switching SSL to true and not specifying a port' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + + Test-TargetResource @inputSwitchSslToTrue | Should -Be $false + } + + It 'Should return desired result false when setting SSL to false and specifying the default SSL port ' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Test-TargetResource @inputSslPortforSslFalse | Should -Be $false + } + + It 'Should return desired result false when setting SSL to true and specifying the default non SSL port' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Test-TargetResource @inputNoneSslPortforSslTrue | Should -Be $false + } + } + } + } +} +finally +{ + Invoke-TestCleanup +} From e38e20a088631ef7f56cf0e474e735971ccc5119 Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Tue, 29 Jun 2021 12:56:47 -0500 Subject: [PATCH 2/8] Updates to Changelog and Readme --- CHANGELOG.md | 1 + README.md | 25 +++++++++++++++++++ ...SC_CMEmailNotificationComponent.schema.mof | 8 +++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e08108c..581c674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added ConfigMgrCBDsc.ReverseDsc module +- Added CMEmailNotificationComponent ## [1.0.2] - 2021-05-12 diff --git a/README.md b/README.md index 5531183..47c501e 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,8 @@ Please check out common DSC Community [contributing guidelines](https://dsccommu maintenance windows for collections. - **CMFileReplication**: Provides a resource for creating, modifying, or deleting file replication settings in Configuration Manager. +- **CMEmailNotificationComponent**: Provides a resource for modifying email notification + component settings. ### xSccmPreReqs @@ -1336,6 +1338,29 @@ you are using apply and auto correct. - [CMFileReplication_Present](Source\Examples\Resources\CMFileReplication\CMFileReplication_Present.ps1) - [CMFileReplication_Absent](Source\Examples\Resources\CMFileReplication\CMFileReplication_Absent.ps1) +### CMEmailNotificationComponent + +- **[String] SiteCode** _(Key)_: Specifies the Site Code for the Configuration + Manager site. +- **[String] Enabled** _(Key)_: Specifies if email notifications are + enable or disable. +- **[String] SmtpServerFqdn** _(Write)_: Specifies the FQDN of the site server that + will send email. +- **[String] SendFrom** _(Write)_: Specifies the address used to send email. +- **[UInt32] Port** _(Write)_: Specifies the port used to send email. +- **[String] UserName** _(Write)_: Specifies the username for authenticating against + an SMTP server. Only used when AuthenticationMethod equals Other. +- **[Boolean] UseSsl** _(Write)_: Specifies whether to use SSL for email alerts. + If omitted, the assumed intent is that SSL is not to be used. +- **[String] TypeOfAuthentication** _(Write)_: Specifies the method by which + Configuration Manager authenticates the site server to the SMTP Server. + - Values include: {Anonymous|DefaultServiceAccount|Other} + +#### CMEmailNotificationComponent Examples + +- [CMEmailNotificationComponent_Present](Source\Examples\Resources\CMEmailNotificationComponent\CMEmailNotificationComponent_Present.ps1) +- [CMEmailNotificationComponent_Absent](Source\Examples\Resources\CMEmailNotificationComponent\CMEmailNotificationComponent_Absent.ps1) + ## ReverseDsc Most organizations using this module already have an existing Configuration Manager diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof index 264aae3..0c99f0e 100644 --- a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof @@ -3,10 +3,10 @@ class DSC_CMEmailNotificationComponent : OMI_BaseResource { [Key, Description("Specifies the SiteCode for the Configuration Manager site.")] String SiteCode; [Key, Description("Specifies if email notifications are enable or disable.")] Boolean Enabled; - [Write, Description("Specifies the FQDN of the site server that will send e-mail.")] String SmtpServerFqdn; - [Write, Description("Specifies the address used to send mail.")] String SendFrom; - [Write, Description("Specifies the port used to send mail.")] UInt32 Port; + [Write, Description("Specifies the FQDN of the site server that will send email.")] String SmtpServerFqdn; + [Write, Description("Specifies the address used to send email.")] String SendFrom; + [Write, Description("Specifies the port used to send email.")] UInt32 Port; [Write, Description("Specifies the username for authenticating against an SMTP server. Only used when AuthenticationMethod equals Other")] String UserName; - [Write, Description("Specifies whether to use SSL for email alerts. If omitted, the assumed intent is that SSL is not to be used.")] Boolean UseSSL; + [Write, Description("Specifies whether to use SSL for email alerts. If omitted, the assumed intent is that SSL is not to be used.")] Boolean UseSsl; [Write, Description("Specifies the method by which Configuration Manager authenticates the site server to the SMTP Server."), ValueMap{"Anonymous","DefaultServiceAccount","Other"}, Values{"Anonymous","DefaultServiceAccount","Other"}] String TypeOfAuthentication; }; From 95748abcf21965cbdeb3fe4ac5ee2bb9096d88e7 Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Tue, 29 Jun 2021 17:49:53 -0500 Subject: [PATCH 3/8] Updated ReverseDsc and added 2 additional Throws --- README.md | 1 + .../DSC_CMEmailNotificationComponent.psm1 | 34 +++++++ ..._CMEmailNotificationComponent.strings.psd1 | 2 + .../ConfigMgrCBDsc.ReverseDsc.psm1 | 78 ++++++++++++++-- .../CMEmailNotificationComponent.tests.ps1 | 80 +++++++++++++++++ .../Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 | 90 ++++++++++++++++++- 6 files changed, 276 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 47c501e..74f5f37 100644 --- a/README.md +++ b/README.md @@ -1413,6 +1413,7 @@ all of the modules and specify if it is currently supported by ReverseDSC. - DSC_CMDistributionGroup: Fully Supported - DSC_CMDistributionPoint: Fully Supported - DSC_CMDistributionPointGroupMembers: Fully Supported +- DSC_CMEmailNotificationComponent: Fully Supported - DSC_CMFallbackStatusPoint: Fully Supported - DSC_CMFileReplication: Not Supported - DSC_CMForestDiscovery: Fully Supported diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 index 5387693..f706eb9 100644 --- a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 @@ -167,6 +167,22 @@ function Set-TargetResource throw $script:localizedData.AuthOtherNoUser } + if ($SmtpServerFqdn) + { + if ($SmtpServerFqdn.Contains('@') -or -not $SmtpServerFqdn.Contains('.')) + { + throw ($script:localizedData.SmtpError -f $SmtpServerFqdn) + } + } + + if ($SendFrom) + { + if (-not $SendFrom.Contains('@') -or -not $SendFrom.Contains('.')) + { + throw ($script:localizedData.SendFromError -f $SendFrom) + } + } + if ($PSBoundParameters.ContainsKey('UseSsl')) { if (($state.UseSSL -eq $false -and $useSSL -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) @@ -336,6 +352,24 @@ function Test-TargetResource $result = $false } + if ($SmtpServerFqdn) + { + if ($SmtpServerFqdn.Contains('@') -or -not $SmtpServerFqdn.Contains('.')) + { + Write-Warning -Message ($script:localizedData.SmtpError -f $SmtpServerFqdn) + $result = $false + } + } + + if ($SendFrom) + { + if (-not $SendFrom.Contains('@') -or -not $SendFrom.Contains('.')) + { + Write-Warning -Message ($script:localizedData.SendFromError -f $SendFrom) + $result = $false + } + } + if ($PSBoundParameters.ContainsKey('UseSsl')) { if (($state.UseSSL -eq $false -and $useSSL -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 index c281364..b21db65 100644 --- a/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 @@ -13,4 +13,6 @@ ConvertFrom-StringData @' SslBadPort = When using SSL, you must specify a port other than the default non-SSL port 25. NonSslBadPort = When not using SSL, you must specify a port other than the default SSL port 465. AbsentUsername = UserAccount specifed {0} does not exist in Configuration Manager and will need to be created prior to adding as the connection account. + SmtpError = SmtpServerFqdn {0} should use . vs @ format, example test.contoso.com. + SendFromError = SendFrom {0} should use @ format, example sendfrom@contoso.com. '@ diff --git a/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 b/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 index fccd61a..2f500db 100644 --- a/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 +++ b/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 @@ -495,6 +495,10 @@ Configuration ConfigureSccm [HashTable[]] `$CMDistributionPointGroupMembers, + [Parameter()] + [HashTable[]] + `$CMEmailNotificationComponent, + [Parameter()] [HashTable[]] `$CMFallbackStatusPoint, @@ -723,6 +727,45 @@ Configuration ConfigureSccm } } + if (`$CMEmailNotificationComponent) + { + if (`$CMEmailNotificationComponent.Enabled -eq `$false) + { + CMEmailNotificationComponent EmailNotificationComponent + { + SiteCode = `$SiteCode + Enabled = `$CMEmailNotificationComponent.Enabled + } + } + elseif (`$CMEmailNotificationComponent.TypeOfAuthentication -eq 'Other') + { + CMEmailNotificationComponent EmailNotificationComponent + { + SiteCode = `$SiteCode + Enabled = `$CMEmailNotificationComponent.Enabled + TypeOfAuthentication = `$CMEmailNotificationComponent.TypeOfAuthentication + Port = `$CMEmailNotificationComponent.Port + SmtpServerFqdn = `$CMEmailNotificationComponent.SmtpServerFqdn + SendFrom = `$CMEmailNotificationComponent.SendFrom + UserName = `$CMEmailNotificationComponent.UserName + UseSsl = `$CMEmailNotificationComponent.UseSsl + } + } + else + { + CMEmailNotificationComponent EmailNotificationComponent + { + SiteCode = `$SiteCode + Enabled = `$CMEmailNotificationComponent.Enabled + TypeOfAuthentication = `$CMEmailNotificationComponent.TypeOfAuthentication + Port = `$CMEmailNotificationComponent.Port + SmtpServerFqdn = `$CMEmailNotificationComponent.SmtpServerFqdn + SendFrom = `$CMEmailNotificationComponent.SendFrom + UseSsl = `$CMEmailNotificationComponent.UseSsl + } + } + } + if (`$CMSystemDiscovery) { if (`$CMSystemDiscovery.Enabled -eq `$true) @@ -3697,10 +3740,10 @@ function Set-ConfigMgrCBDscReverse [ValidateSet('All','Accounts','AdministrativeUser','AssetIntelligencePoint','BoundaryGroups', 'ClientPush','ClientStatusSettings','CollectionEvaluationComponent','Collections', 'DistributionGroups','DistributionPoint','DistributionPointGroupMembers', - 'FallbackPoints','ForestDiscovery','HeartbeatDiscovery','MaintenanceWindow','ManagementPoint', - 'NetworkDiscovery','PullDistributionPoint','PxeDistributionPoint', - 'ReportingServicesPoint','SecurityScopes','ServiceConnection','SiteMaintenance', - 'SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', + 'EmailNotificationComponent','FallbackPoints','ForestDiscovery','HeartbeatDiscovery', + 'MaintenanceWindow','ManagementPoint','NetworkDiscovery','PullDistributionPoint', + 'PxeDistributionPoint','ReportingServicesPoint','SecurityScopes','ServiceConnection', + 'SiteMaintenance','SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', 'StatusReportingComponent','SystemDiscovery','UserDiscovery','ConfigFileOnly')] [String[]] $Include = 'All', @@ -3709,10 +3752,10 @@ function Set-ConfigMgrCBDscReverse [ValidateSet('Accounts','AdministrativeUser','AssetIntelligencePoint','BoundaryGroups', 'ClientPush','ClientStatusSettings','CollectionEvaluationComponent','Collections', 'DistributionGroups','DistributionPoint','DistributionPointGroupMembers', - 'FallbackPoints','ForestDiscovery','HeartbeatDiscovery','MaintenanceWindow','ManagementPoint', - 'NetworkDiscovery','PullDistributionPoint','PxeDistributionPoint', - 'ReportingServicesPoint','SecurityScopes','ServiceConnection','SiteMaintenance', - 'SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', + 'EmailNotificationComponent','FallbackPoints','ForestDiscovery','HeartbeatDiscovery', + 'MaintenanceWindow','ManagementPoint','NetworkDiscovery','PullDistributionPoint', + 'PxeDistributionPoint','ReportingServicesPoint','SecurityScopes','ServiceConnection', + 'SiteMaintenance','SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', 'StatusReportingComponent','SystemDiscovery','UserDiscovery')] [String[]] $Exclude, @@ -4112,6 +4155,25 @@ function Set-ConfigMgrCBDscReverse } } + if (($Include -eq 'All' -and $Exclude -notcontains 'EmailNotificationComponent') -or ($Include -contains 'EmailNotificationComponent')) + { + $resourceName = 'CMEmailNotificationComponent' + Write-Verbose -Message ($script:localizedData.SingleOutput -f $resourceName) -Verbose + + $wEmailNotify = "$resourceName = @{`r`n" + $params = @{ + ResourceName = $resourceName + SiteCode = $SiteCode + Indent = 1 + MultiEntry = $false + Resources = $resources + } + + $testThing = Set-OutFile @params + $wEmailNotify += "$testThing" + $fileOut += "$wEmailNotify`r`n" + } + if (($Include -eq 'All' -and $Exclude -notcontains 'FallbackPoints') -or ($Include -contains 'FallbackPoints')) { $resourceName = 'CMFallbackStatusPoint' diff --git a/tests/Unit/CMEmailNotificationComponent.tests.ps1 b/tests/Unit/CMEmailNotificationComponent.tests.ps1 index f1eac48..ea00278 100644 --- a/tests/Unit/CMEmailNotificationComponent.tests.ps1 +++ b/tests/Unit/CMEmailNotificationComponent.tests.ps1 @@ -395,6 +395,30 @@ try } $sslBadPort = 'When using SSL, you must specify a port other than the default non-SSL port 25.' + + $inputBadSendFrom = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender.contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 446 + UseSsl = $true + Enabled = $true + } + + $sendFromError = 'SendFrom emailsender.contoso.com should use @ format, example sendfrom@contoso.com.' + + $inputBadSmtpServerFqdn = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer@contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 446 + UseSsl = $true + Enabled = $true + } + + $smtpError = 'SmtpServerFqdn EmailServer@contoso.com should use . vs @ format, example test.contoso.com.' } It 'Should return throw Username specifed does not exist in Confiuration Manager' { @@ -466,6 +490,30 @@ try Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It } + + It 'Should return throw when specifying a bad misformatted SendFrom' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + Mock -CommandName Get-CMAccount -MockWith { $null } + + { Set-TargetResource @inputBadSendFrom } | Should -Throw -ExpectedMessage $sendFromError + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } + + It 'Should return throw when specifying a bad misformatted SmtpServerFqdn' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentNonSsl } + Mock -CommandName Get-CMAccount -MockWith { $null } + + { Set-TargetResource @inputBadSmtpServerFqdn } | Should -Throw -ExpectedMessage $smtpError + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMEmailNotificationComponent -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It + } } } @@ -612,6 +660,26 @@ try UseSsl = $true Enabled = $true } + + $inputBadSendFrom = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender.contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 446 + UseSsl = $true + Enabled = $true + } + + $inputBadSmtpServerFqdn = @{ + SiteCode = 'Lab' + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer@contoso.com' + TypeOfAuthentication = 'DefaultServiceAccount' + Port = 446 + UseSsl = $true + Enabled = $true + } } It 'Should return desired result false when Enabled and missing core components for enabled equals True' { @@ -655,6 +723,18 @@ try Test-TargetResource @inputNoneSslPortforSslTrue | Should -Be $false } + + It 'Should return desired result false when specifying a malformed SendFrom' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Test-TargetResource @inputBadSendFrom | Should -Be $false + } + + It 'Should return desired result false when specifying a malformed SmtpServerFqdn' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnPresentSsl } + + Test-TargetResource @inputBadSmtpServerFqdn | Should -Be $false + } } } } diff --git a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 index 000c43d..8b1515d 100644 --- a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 +++ b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 @@ -895,6 +895,74 @@ InModuleScope $script:subModuleName { } ) } + @{ + ImplementedAs = 'PowerShell' + Name = 'CMEmailNotificationComponent' + ModuleName = 'ConfigMgrCBDsc' + Version = '1.0.1' + Properties = @( + @{ + Name = 'SiteCode' + PropertyType = '[string]' + IsMandatory = $true + Values = '{}' + } + @{ + Name = 'Enabled' + PropertyType = '[boolean]' + IsMandatory = $true + Values = '{}' + } + @{ + Name = 'SmtpServerFqdn' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'SendFrom' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'Port' + PropertyType = '[UInt32]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'UserName' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'UseSsl' + PropertyType = '[boolean]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'TypeOfAuthentication' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'DependsOn' + PropertyType = '[string[]]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'PsDscRunAsCredential' + PropertyType = '[PSCredential]' + IsMandatory = $false + Values = '{}' + } + ) + } @{ ImplementedAs = 'PowerShell' Name = 'CMFallbackStatusPoint' @@ -2472,6 +2540,25 @@ InModuleScope $script:subModuleName { PSComputerName = 'localhost' } + $invokeEmailComponent = @{ + ConfigurationName = $null + DependsOn = $null + ModuleName = 'ConfigMgrCBDsc' + ModuleVersion = 1.0.1 + PsDscRunAsCredential = $null + ResourceId = $null + SourceInfo = $null + Enabled = $true + TypeOfAuthentication = 'Other' + UserName = 'contoso\emailUser' + SmtpServerFqdn = 'Smtp01.contoso.com' + SendFrom = 'sender@contoso.com' + Port = 446 + UseSsl = $true + SiteCode = 'Lab' + PSComputerName = 'localhost' + } + $getFallBackStatusReturn = @( @{ SiteCode = 'Lab' @@ -3412,6 +3499,7 @@ InModuleScope $script:subModuleName { Mock -CommandName Invoke-DscResource -MockWith { $invokeCMDistributionGroup } -ParameterFilter { $Name -eq 'CMDistributionGroup' } Mock -CommandName Invoke-DscResource -MockWith { $invokeCMDistributionPoint } -ParameterFilter { $Name -eq 'CMDistributionPoint' } Mock -CommandName Invoke-DscResource -MockWith { $invokeCMDistributionGroupMembers } -ParameterFilter { $Name -eq 'CMDistributionPointGroupMembers' } + Mock -CommandName Invoke-DscResource -MockWith { $invokeEmailComponent } -ParameterFilter { $Name -eq 'CMEmailNotificationComponent' } Mock -CommandName Invoke-DscResource -MockWith { $invokeFallbackPoints } -ParameterFilter { $Name -eq 'CMFallbackStatusPoint' } Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getForestDiscoveryEnabled } -ParameterFilter { $Name -eq 'ActiveDirectoryForestDiscovery' } Mock -CommandName Invoke-DscResource -MockWith { $invokeForestDiscoveryEnabled } -ParameterFilter { $Name -eq 'CMForestDiscovery' } @@ -3441,7 +3529,7 @@ InModuleScope $script:subModuleName { $result = Set-ConfigMgrCBDscReverse @testAll $result | Should -BeOfType System.String Assert-MockCalled Get-CMAccount -Exactly -Times 1 -Scope It - Assert-MockCalled Invoke-DscResource -Exactly -Times 25 -Scope It + Assert-MockCalled Invoke-DscResource -Exactly -Times 26 -Scope It Assert-MockCalled Get-CMAdministrativeUser -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMAssetIntelligenceSynchronizationPoint -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMCollection -Exactly -Times 2 -Scope It From 1933d84678e7a224644e6141345a364b109303f5 Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Wed, 30 Jun 2021 09:29:22 -0500 Subject: [PATCH 4/8] Update from Main and Readme.md Update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 74f5f37..8a7dc1d 100644 --- a/README.md +++ b/README.md @@ -1460,7 +1460,7 @@ After importing the module, Set-ConfigMgrCBDscReverse will be available. default setting: All. - Values include: { All|Accounts|AdministrativeUser|AssetIntelligencePoint|BoundaryGroups| ClientPush|ClientStatusSettings|CollectionEvaluationComponent|Collections| - DistributionGroups|DistributionPoint|DistributionPointGroupMembers| + DistributionGroups|DistributionPoint|DistributionPointGroupMembers|EmailNotificationComponent| FallbackPoints|ForestDiscovery|HeartbeatDiscovery|MaintenanceWindow|ManagementPoint| NetworkDiscovery|PullDistributionPoint|PxeDistributionPoint| ReportingServicesPoint|SecurityScopes|ServiceConnection|SiteMaintenance| @@ -1470,7 +1470,7 @@ After importing the module, Set-ConfigMgrCBDscReverse will be available. being evaluated. Only evaluated when Include = 'All' - Values include: { Accounts|AdministrativeUser|AssetIntelligencePoint|BoundaryGroups| ClientPush|ClientStatusSettings|CollectionEvaluationComponent|Collections| - DistributionGroups|DistributionPoint|DistributionPointGroupMembers| + DistributionGroups|DistributionPoint|DistributionPointGroupMembers|EmailNotificationComponent| FallbackPoints|ForestDiscovery|HeartbeatDiscovery|MaintenanceWindow|ManagementPoint| NetworkDiscovery|PullDistributionPoint|PxeDistributionPoint| ReportingServicesPoint|SecurityScopes|ServiceConnection|SiteMaintenance| From 3daced85d070ada7108d0dd9a2d980c864a6f8d8 Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Thu, 5 Aug 2021 10:03:45 -0500 Subject: [PATCH 5/8] adding linux module for composite --- RequiredModules.psd1 | 1 + 1 file changed, 1 insertion(+) diff --git a/RequiredModules.psd1 b/RequiredModules.psd1 index 2a7ec96..96d5ac2 100644 --- a/RequiredModules.psd1 +++ b/RequiredModules.psd1 @@ -20,6 +20,7 @@ 'DscResource.AnalyzerRules' = 'latest' xDscResourceDesigner = 'latest' 'DscResource.DocGenerator' = 'latest' + NX = 'latest' # Build dependent modules 'DscResource.Common' = 'latest' From 90dffa1334ac32bd89e17322c7f01915c01b66ce Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Thu, 5 Aug 2021 10:58:02 -0500 Subject: [PATCH 6/8] Updated Required modules --- RequiredModules.psd1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RequiredModules.psd1 b/RequiredModules.psd1 index 96d5ac2..de7a4fa 100644 --- a/RequiredModules.psd1 +++ b/RequiredModules.psd1 @@ -19,8 +19,7 @@ 'DscResource.Test' = 'latest' 'DscResource.AnalyzerRules' = 'latest' xDscResourceDesigner = 'latest' - 'DscResource.DocGenerator' = 'latest' - NX = 'latest' + 'DscResource.DocGenerator' = '0.8.3' # Build dependent modules 'DscResource.Common' = 'latest' From a4b34eb0c3bdacb630bc8f96a0b2cb086f68b6ce Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Thu, 5 Aug 2021 11:21:44 -0500 Subject: [PATCH 7/8] Removed extra entry in .Strings --- .../en-us/DSC_CMEmailNotificationComponent.strings.psd1 | 1 - 1 file changed, 1 deletion(-) diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 index b21db65..9f649cb 100644 --- a/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 @@ -1,6 +1,5 @@ ConvertFrom-StringData @' RetrieveSettingValue = Getting results for Configuration Manager accounts. - DesiredState = Setting is already in desired state. TestState = Test-TargetResource compliance check returned: {0}. Enabled = NOTMATCH: Value for property Enabled does not match. Current State is False and desired state is True. Disabled = NOTMATCH: Value for property Enabled does not match. Current State is True and desired state is False. From 6e8c3724d784f5fa9690699468c2af03b8ed2e0a Mon Sep 17 00:00:00 2001 From: Easyreturns <20781445+jeffotterpohl@users.noreply.github.com> Date: Fri, 6 Aug 2021 07:04:41 -0500 Subject: [PATCH 8/8] HQRM updates per PR feedback --- README.md | 2 +- .../DSC_CMEmailNotificationComponent.psm1 | 38 +++++++++---------- ...SC_CMEmailNotificationComponent.schema.mof | 2 +- ..._CMEmailNotificationComponent.strings.psd1 | 6 +-- source/Examples/PrimaryInstall.ps1 | 17 ++++++++- .../CMEmailNotificationComponent_Absent.ps1 | 2 +- .../CMEmailNotificationComponent.tests.ps1 | 2 +- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 8a7dc1d..a0b521a 100644 --- a/README.md +++ b/README.md @@ -1343,7 +1343,7 @@ you are using apply and auto correct. - **[String] SiteCode** _(Key)_: Specifies the Site Code for the Configuration Manager site. - **[String] Enabled** _(Key)_: Specifies if email notifications are - enable or disable. + enabled or disabled. - **[String] SmtpServerFqdn** _(Write)_: Specifies the FQDN of the site server that will send email. - **[String] SendFrom** _(Write)_: Specifies the address used to send email. diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 index f706eb9..c824785 100644 --- a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.psm1 @@ -14,7 +14,7 @@ $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' Specifies the SiteCode for the Configuration Manager site. .PARAMETER Enabled - Specifies if email notifications are enable or disable. + Specifies if email notifications are enabled or disabled. #> function Get-TargetResource { @@ -83,7 +83,7 @@ function Get-TargetResource Specifies the SiteCode for the Configuration Manager site. .PARAMETER Enabled - Specifies if email notifications are enable or disable. + Specifies if email notifications are enabled or disabled. .PARAMETER ServerFqdn Specifies the FQDN of the site server that will send e-mail. @@ -97,7 +97,7 @@ function Get-TargetResource .PARAMETER UserName Specifies the username for authenticating against an SMTP server. - .PARAMETER UseSSL + .PARAMETER UseSsl Specifies whether to use SSL for email alerts. If omitted, the assumed intent is that SSL is not to be used. .PARAMETER TypeOfAuthentication @@ -135,7 +135,7 @@ function Set-TargetResource [Parameter()] [Boolean] - $UseSsL, + $UseSsl, [Parameter()] [ValidateSet('Anonymous','DefaultServiceAccount','Other')] @@ -185,22 +185,22 @@ function Set-TargetResource if ($PSBoundParameters.ContainsKey('UseSsl')) { - if (($state.UseSSL -eq $false -and $useSSL -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) + if (($state.UseSsl -eq $false -and $useSsl -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) { Write-Warning -Message $script:localizedData.SSLTrueNoPort } - if (($state.UseSSL -eq $true -and $UseSsL -eq $false) -and -not $PSBoundParameters.ContainsKey('Port')) + if (($state.UseSsl -eq $true -and $UseSsl -eq $false) -and -not $PSBoundParameters.ContainsKey('Port')) { Write-Warning -Message $script:localizedData.SSLFalseNoPort } - if ($UseSsL -eq $true -and $Port -eq 25) + if ($UseSsl -eq $true -and $Port -eq 25) { throw $script:localizedData.SslBadPort } - if (($UseSsL -eq $false) -and ($Port -eq '465')) + if (($UseSsl -eq $false) -and ($Port -eq '465')) { throw $script:localizedData.NonSslBadPort } @@ -210,15 +210,15 @@ function Set-TargetResource { if ($param.Key -ne 'SiteCode') { - if ($param.Value -ne $state[$param.key]) + if ($param.Value -ne $state[$param.Key]) { - Write-Verbose -Message ($script:localizedData.SettingValue -f $param.key, $param.Value) + Write-Verbose -Message ($script:localizedData.SettingValue -f $param.Key, $param.Value) } if ($param.Key -ne 'Enabled') { $buildingParams += @{ - $param.key = $param.Value + $param.Key = $param.Value } } } @@ -263,7 +263,7 @@ function Set-TargetResource Specifies the SiteCode for the Configuration Manager site. .PARAMETER Enabled - Specifies if email notifications are enable or disable. + Specifies if email notifications are enabled or disabled. .PARAMETER ServerFqdn Specifies the FQDN of the site server that will send e-mail. @@ -278,7 +278,7 @@ function Set-TargetResource Specifies the username for authenticating against an SMTP server. Only used when TypeOfAuthentication equals Other. - .PARAMETER UseSSL + .PARAMETER UseSsl Specifies whether to use SSL for email alerts. If omitted, the assumed intent is that SSL is not to be used. .PARAMETER TypeOfAuthentication @@ -317,7 +317,7 @@ function Test-TargetResource [Parameter()] [Boolean] - $UseSsL, + $UseSsl, [Parameter()] [ValidateSet('Anonymous','DefaultServiceAccount','Other')] @@ -372,23 +372,23 @@ function Test-TargetResource if ($PSBoundParameters.ContainsKey('UseSsl')) { - if (($state.UseSSL -eq $false -and $useSSL -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) + if (($state.UseSsl -eq $false -and $useSsl -eq $true) -and -not $PSBoundParameters.ContainsKey('Port')) { Write-Warning -Message $script:localizedData.SSLTrueNoPort } - if (($state.UseSSL -eq $true -and $UseSsL -eq $false) -and -not $PSBoundParameters.ContainsKey('Port')) + if (($state.UseSsl -eq $true -and $UseSsl -eq $false) -and -not $PSBoundParameters.ContainsKey('Port')) { Write-Warning -Message $script:localizedData.SSLFalseNoPort } - if ($UseSsL -eq $true -and $Port -eq 25) + if ($UseSsl -eq $true -and $Port -eq 25) { Write-Warning -Message $script:localizedData.SslBadPort $result = $false } - if (($UseSsL -eq $false) -and ($Port -eq 465)) + if (($UseSsl -eq $false) -and ($Port -eq 465)) { Write-Warning -Message $script:localizedData.NonSslBadPort $result = $false @@ -406,7 +406,7 @@ function Test-TargetResource CurrentValues = $state DesiredValues = $PSBoundParameters ValuesToCheck = @('Enabled','SmtpServerFqdn','SendFrom','Port', - 'Username','UseSsL','TypeOfAuthentication') + 'Username','UseSsl','TypeOfAuthentication') } $testResult = Test-DscParameterState @testParams -Verbose -TurnOffTypeChecking diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof index 0c99f0e..81ebf06 100644 --- a/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/DSC_CMEmailNotificationComponent.schema.mof @@ -2,7 +2,7 @@ class DSC_CMEmailNotificationComponent : OMI_BaseResource { [Key, Description("Specifies the SiteCode for the Configuration Manager site.")] String SiteCode; - [Key, Description("Specifies if email notifications are enable or disable.")] Boolean Enabled; + [Key, Description("Specifies if email notifications are enabled or disabled.")] Boolean Enabled; [Write, Description("Specifies the FQDN of the site server that will send email.")] String SmtpServerFqdn; [Write, Description("Specifies the address used to send email.")] String SendFrom; [Write, Description("Specifies the port used to send email.")] UInt32 Port; diff --git a/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 index 9f649cb..7acbeb7 100644 --- a/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 +++ b/source/DSCResources/DSC_CMEmailNotificationComponent/en-us/DSC_CMEmailNotificationComponent.strings.psd1 @@ -7,11 +7,11 @@ ConvertFrom-StringData @' MissingParams = When specifying Enabled equals true you must specify SmtpServerFqdn, Sendfrom, and TypeOfAuthentication. UserAuthNotOther = When specifying UserName you must set TypeOfAuthentication to Other. AuthOtherNoUser = When setting TypeOfAuthentication to Other, you must specify UserName. - SslTrueNoPort = Changing UseSSL from false to true and no port was specified, the Port will automatically be changed to 465. - SslFalseNoPort = Chaning UseSSL from true to false and no port was specified, the Port will automatically be changed to 25 + SslTrueNoPort = Changing UseSsl from false to true and no port was specified, the Port will automatically be changed to 465. + SslFalseNoPort = Chaning UseSsl from true to false and no port was specified, the Port will automatically be changed to 25 SslBadPort = When using SSL, you must specify a port other than the default non-SSL port 25. NonSslBadPort = When not using SSL, you must specify a port other than the default SSL port 465. - AbsentUsername = UserAccount specifed {0} does not exist in Configuration Manager and will need to be created prior to adding as the connection account. + AbsentUsername = UserAccount specifed {0} does not exist in the specified Configuration Manager site and will need to be created prior to adding as the connection account. SmtpError = SmtpServerFqdn {0} should use . vs @ format, example test.contoso.com. SendFromError = SendFrom {0} should use @ format, example sendfrom@contoso.com. '@ diff --git a/source/Examples/PrimaryInstall.ps1 b/source/Examples/PrimaryInstall.ps1 index c3244ea..59f0f7e 100644 --- a/source/Examples/PrimaryInstall.ps1 +++ b/source/Examples/PrimaryInstall.ps1 @@ -274,6 +274,20 @@ Configuration PrimaryInstall [array]$cmAccountsDependsOn += "[CMAccounts]AddingAccount-$($account.Username)" } + CMEmailNotificationComponent EmailSettings + { + SiteCode = $SiteCode + SendFrom = 'emailsender@contoso.com' + SmtpServerFqdn = 'EmailServer.contoso.com' + TypeOfAuthentication = 'Other' + Port = 465 + UseSsl = $true + Enabled = $true + UserName = 'contoso\EmailUser' + PsDscRunAsCredential = $SccmInstallAccount + DependsOn = $cmAccountsDependsOn + } + CMForestDiscovery CreateForestDiscovery { SiteCode = $SiteCode @@ -551,7 +565,7 @@ Configuration PrimaryInstall '[CMHeartbeatDiscovery]CreateHeartbeatDiscovery','[CMUserDiscovery]CreateUserDiscovery','[CMClientStatusSettings]CreateClientStatusSettings',$cmSiteMaintenanceDependsOn, '[CMBoundaryGroups]DemoBoundaryGroup','[CMAdministrativeUser]SiteAdmins','[CMCollectionMembershipEvaluationComponent]CollectionSettings', '[CMStatusReportingComponent]StatusReportingSettings','[Registry]MaxHWMifSize','[CMDistributionPointGroupMembers]DPGroupMembers','[CMManagementPoint]MPInstall', - '[CMSoftwareUpdatePoint]SUPInstall' + '[CMSoftwareUpdatePoint]SUPInstall','[CMEmailNotificationComponent]EmailSettings' } } } @@ -579,6 +593,7 @@ $params = @{ Get-Credential -Username 'contoso\SCCM-Network' -Message 'SCCM Network Service account' Get-Credential -Username 'contoso\SCCM-ClientPush' -Message 'SCCM Client Push account' Get-Credential -Username 'contoso\SCCM-ADJoin' -Message 'SCCM AD Join account' + Get-Credential -Username 'contoso\EmailUser' -Message 'User account for authenticating against an SMTP server' ) } diff --git a/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 b/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 index 713f780..9c4913d 100644 --- a/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 +++ b/source/Examples/Resources/CMEmailNotificationComponent/CMEmailNotificationComponent_Absent.ps1 @@ -1,6 +1,6 @@ <# .SYNOPSIS - A DSC configuration script to disabled email notification component in Configuration Manager. + A DSC configuration script to disable email notification component in Configuration Manager. #> Configuration Example { diff --git a/tests/Unit/CMEmailNotificationComponent.tests.ps1 b/tests/Unit/CMEmailNotificationComponent.tests.ps1 index ea00278..17c0185 100644 --- a/tests/Unit/CMEmailNotificationComponent.tests.ps1 +++ b/tests/Unit/CMEmailNotificationComponent.tests.ps1 @@ -340,7 +340,7 @@ try Context 'When Set-TargetResource throws' { BeforeEach { Mock -CommandName Get-CMAccount - $absentUsername = 'UserAccount specifed contoso\EmailUser does not exist in Configuration Manager and will need to be created prior to adding as the connection account.' + $absentUsername = 'UserAccount specifed contoso\EmailUser does not exist in the specified Configuration Manager site and will need to be created prior to adding as the connection account.' $inputMissingCore = @{ SiteCode = 'Lab'