Tests/Unit/MSFT_SecurityOption.tests.ps1
#region HEADER # Unit Test Template Version: 1.2.1 $script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) { & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests')) } Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force $TestEnvironment = Initialize-TestEnvironment ` -DSCModuleName 'SecurityPolicyDsc' ` -DSCResourceName 'MSFT_SecurityOption' ` -TestType Unit #endregion HEADER function Invoke-TestCleanup { Restore-TestEnvironment -TestEnvironment $TestEnvironment } # Begin Testing try { InModuleScope 'MSFT_SecurityOption' { $dscResourceInfo = Get-DscResource -Name SecurityOption $testParameters = @{ Name = 'Test' User_Account_Control_Behavior_of_the_elevation_prompt_for_standard_users = 'Automatically deny elevation request' Accounts_Administrator_account_status = 'Enabled' } $kerberosValueMap = @{ DES_CBC_CRC = '4,1' DES_CBC_MD5 = '4,2' RC4_HMAC_MD5 = '4,4' AES128_HMAC_SHA1 = '4,8' AES256_HMAC_SHA1 = '4,16' FUTURE = '4,2147483616' } Describe 'SecurityOptionHelperTests' { Context 'Get-PolicyOptionData' { $dataFilePath = Join-Path -Path $dscResourceInfo.ParentPath -ChildPath SecurityOptionData.psd1 $securityOptionData = Get-PolicyOptionData -FilePath $dataFilePath.Normalize() $securityOptionPropertyList = $dscResourceInfo.Properties | Where-Object -FilterScript { $PSItem.Name -match '_' } It 'Should have the same count as property count' { $securityOptionDataPropertyCount = $securityOptionData.Count $securityOptionDataPropertyCount | Should Be $securityOptionPropertyList.Name.Count } foreach ( $name in $securityOptionData.Keys ) { It "Should contain property name: $name" { $securityOptionPropertyList.Name -contains $name | Should Be $true } } $optionData = Get-PolicyOptionData -FilePath $dataFilePath.Normalize() foreach ($option in $optionData.GetEnumerator()) { Context "$($option.Name)" { $options = $option.Value.Option foreach ($entry in $options.GetEnumerator()) { It "$($entry.Name) Should have string as Option type" { $entry.value.GetType().Name -is [string] | Should Be $true } } } } } Context 'Add-PolicyOption' { It 'Should have [Registry Values]' { [string[]]$testString = "Registry\path" [string]$addOptionResult = Add-PolicyOption -RegistryPolicies $testPath $addOptionResult | Should Match '[Registry Values]' } It 'Should have [System Access]' { [string[]]$testString = "EnableAdminAccount=1" [string]$addOptionResult = Add-PolicyOption -SystemAccessPolicies $testPath $addOptionResult | Should Match '[System Access]' } } Context 'Format-LogonMessage' { $singleLineMessage = 'Line 1 - Message for line 1.,Line 2 - Message for line 2"," words"," seperated"," with"," commas.,Line 3 - Message for line 3.' $multiLineMessage = @' Line 1 - Message for line 1. Line 2 - Message for line 2, words, seperated, with, commas. Line 3 - Message for line 3. '@ It 'Should return a string' { $result = Format-LogonMessage -Message $multiLineMessage $result -is [string] | Should be $true } It 'Should match SingleLineMessage' { $result = Format-LogonMessage -Message $multiLineMessage $result -eq $singleLineMessage | Should be $true } } Context 'Test-RestrictedRemoteSam' { $desiredSettingInput = ConvertTo-CimRestrictedRemoteSam -InputObject "(A;;RC;;;S-1-5-32-544)" It 'Should be true' { $currentSettingInput = ConvertTo-CimRestrictedRemoteSam -InputObject "(A;;RC;;;S-1-5-32-544)" $result = Test-RestrictedRemoteSam -DesiredSetting $desiredSettingInput -CurrentSetting $currentSettingInput $result | Should Be $true } It 'Should be false' { $currentSettingInput = ConvertTo-CimRestrictedRemoteSam -InputObject "(A;;RC;;;S-1-5-20)" $result = Test-RestrictedRemoteSam -DesiredSetting $desiredSettingInput -CurrentSetting $currentSettingInput $result | Should Be $false } } Context 'ConvertTo-CimRestrictedRemoteSam' { It 'Should return BuiltIn\Administrators' { $result = ConvertTo-CimRestrictedRemoteSam -InputObject "(D;;RC;;;BA)" $result.Permission | Should Be 'Deny' $result.Identity | Should Be 'BuiltIn\Administrators' } It 'Should return NT AUTHORITY\NETWORK SERVICE' { $result = ConvertTo-CimRestrictedRemoteSam -InputObject "(A;;RC;;;S-1-5-20)" $result.Permission | Should Be 'Allow' $result.Identity | Should Be 'NT AUTHORITY\NETWORK SERVICE' } } Context 'Format-RestrictedRemoteSam' { $formatDescriptorDenyParameters = @{ Identity = 'BUILTIN\Administrators' Permission = 'Deny' } $formatDescriptorAllowParameters = @{ Identity = 'NT AUTHORITY\NETWORK SERVICE' Permission = 'Allow' } It 'Should Deny BUILTIN\Administrators' { $result = Format-RestrictedRemoteSam -SecurityDescriptor $formatDescriptorDenyParameters $result | Should Be '"O:BAG:BAD:(D;;RC;;;BA)"' } It 'Should Allow NT AUTHORITY\NETWORK SERVICE' { $result = Format-RestrictedRemoteSam -SecurityDescriptor $formatDescriptorAllowParameters $result | Should Be '"O:BAG:BAD:(A;;RC;;;S-1-5-20)"' } } Context 'ConvertTo-KerberosEncryptionValue' { $validateSet = (Get-Command -Name ConvertTo-KerberosEncryptionValue).Parameters.EncryptionType.Attributes.ValidValues $testCases = $validateSet | ForEach-Object -Process { @{EncryptionType = $PSItem} } It 'ValidateSet should match valueMap' { $validateSet.Count | Should Be $kerberosValueMap.Count } It 'Should match valueMap <EncryptionType>' -TestCases $testCases { param ($EncryptionType) $result = ConvertTo-KerberosEncryptionValue -EncryptionType $EncryptionType $result | Should Be $kerberosValueMap.$EncryptionType } } Context 'ConvertTo-KerberosEncryptionOption' { $testCases = $kerberosValueMap.Values | ForEach-Object -Process { @{OptionValue = $PSItem} } It 'Should match Kerberos Option <OptionValue>' -TestCases $testCases { param ($OptionValue) $result = ConvertTo-KerberosEncryptionOption -EncryptionValue $OptionValue $shouldResult = $kerberosValueMap.GetEnumerator() | Where-Object -FilterScript { $PSItem.value -eq $OptionValue } $result | Should Be $shouldResult.Name } } } Describe 'Get-TargetResource' { Context 'General operation tests' { It 'Should not throw' { { Get-TargetResource -Name Test } | Should Not throw } It 'Should return one hashTable' { $getTargetResult = Get-TargetResource -Name Test $getTargetResult.GetType().BaseType.Name | Should Not Be 'Array' $getTargetResult.GetType().Name | Should Be 'Hashtable' } } } Describe 'Test-TargetResource' { $falseMockResult = @{ User_Account_Control_Behavior_of_the_elevation_prompt_for_standard_users = 'Prompt for credentials' } Context 'General operation tests' { It 'Should return a bool' { $testResult = Test-TargetResource @testParameters $testResult -is [bool] | Should Be $true } } Context 'Not in a desired state' { It 'Should return false when NOT in desired state' { Mock -CommandName Get-TargetResource -MockWith { $falseMockResult } $testResult = Test-TargetResource @testParameters $testResult | Should Be $false } } Context 'In a desired State' { $trueMockResult = $testParameters.Clone() $trueMockResult.Remove('Name') It 'Should return true when in desired state' { Mock -CommandName Get-TargetResource -MockWith { $trueMockResult } $testResult = Test-TargetResource @testParameters $testResult | Should Be $true } } Context 'Null handler' { $avoidNullTestParameters = @{ Name = 'Test' Network_security_Configure_encryption_types_allowed_for_Kerberos = 'AES128_HMAC_SHA1' } Mock -CommandName Get-TargetResource -MockWith { @{ Name = 'Test' Network_security_Configure_encryption_types_allowed_for_Kerberos = $null } } It 'Should not throw when the existing value is null' { { Test-TargetResource @avoidNullTestParameters } | Should Not Throw } } Context 'Restricted Remote Sam' { $restrictedSamvalue = ConvertTo-CimRestrictedRemoteSam -InputObject "(A;;RC;;;S-1-5-20)" $parameters = @{ Name = 'Test' Network_access_Restrict_clients_allowed_to_make_remote_calls_to_SAM = $restrictedSamvalue } Mock -CommandName Get-TargetResource -MockWith { @{ Name = 'Test' Network_access_Restrict_clients_allowed_to_make_remote_calls_to_SAM = $restrictedSamvalue } } $result = Test-TargetResource @parameters $result | Should Be $true } } Describe 'Set-TargetResource' { Mock -CommandName Invoke-Secedit -MockWith {} Context 'Successfully applied security policy' { Mock -CommandName Test-TargetResource -MockWith { $true } It 'Should not throw when successfully updated security option' { { Set-TargetResource @testParameters } | Should Not throw } It 'Should call Test-TargetResource 2 times' { Assert-MockCalled -CommandName Test-TargetResource -Times 2 } } Context 'Failed to apply security policy' { Mock -CommandName Test-TargetResource -MockWith { $false } It 'Should throw when failed to apply security policy' { { Set-TargetResource @testParameters } | Should throw } It 'Should call Test-TargetResource 2 times' { Assert-MockCalled -CommandName Test-TargetResource -Times 2 } } Context 'Call correct helper functions' { Mock -CommandName Test-TargetResource Mock -CommandName Format-LogonMessage Mock -CommandName ConvertTo-KerberosEncryptionValue Mock -CommandName Format-RestrictedRemoteSam $settingsThatRequireHelpers = @( @{ Name = 'Test' Interactive_logon_Message_text_for_users_attempting_to_log_on = 'You must accept the EULA before preceeding.' HelperFunction = 'Format-LogonMessage' } @{ Name = 'Test' Network_security_Configure_encryption_types_allowed_for_Kerberos = 'AES256_HMAC_SHA1' HelperFunction = 'ConvertTo-KerberosEncryptionValue' } @{ Name = 'Test' Network_access_Restrict_clients_allowed_to_make_remote_calls_to_SAM = (ConvertTo-CimRestrictedRemoteSam "O:BAG:BAD:(D;;RC;;;BA)") HelperFunction = 'Format-RestrictedRemoteSam' } ) foreach ($setting in $settingsThatRequireHelpers) { $parameters = $setting.Clone() $parameters.Remove('HelperFunction') Set-TargetResource @parameters It 'Should call correct helper function' { Assert-MockCalled -CommandName $setting.HelperFunction -Times 1 } } } It "Should call Invoke-Secedit 2 times" { Assert-MockCalled -CommandName Invoke-Secedit -Times 2 } } } } finally { Invoke-TestCleanup } |