Tests/Unit/MSFT_xADUser.Tests.ps1
$script:dscModuleName = 'xActiveDirectory' $script:dscResourceName = 'MSFT_xADUser' #region HEADER # Unit Test Template Version: 1.2.4 $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 $script:dscModuleName ` -DSCResourceName $script:dscResourceName ` -ResourceType 'Mof' ` -TestType Unit #endregion HEADER function Invoke-TestSetup { } function Invoke-TestCleanup { Restore-TestEnvironment -TestEnvironment $TestEnvironment } # Begin Testing try { Invoke-TestSetup InModuleScope $script:dscResourceName { $testPresentParams = @{ DomainName = 'contoso.com' UserName = 'TestUser' Ensure = 'Present' } $testAbsentParams = $testPresentParams.Clone() $testAbsentParams['Ensure'] = 'Absent' $fakeADUser = @{ DistinguishedName = "CN=$($testPresentParams.UserName),CN=Users,DC=contoso,DC=com" Enabled = $true GivenName = '' Name = $testPresentParams.UserName SamAccountName = $testPresentParams.UserName Surname = '' UserPrincipalName = '' ServicePrincipalName = @('spn/a', 'spn/b') } $testDomainController = 'TESTDC' $testCredential = [System.Management.Automation.PSCredential]::Empty $testStringProperties = @( 'UserPrincipalName', 'DisplayName', 'Path', 'GivenName', 'Initials', 'Surname', 'Description', 'StreetAddress', 'POBox', 'City', 'State', 'PostalCode', 'Country', 'Department', 'Division', 'Company', 'Office', 'JobTitle', 'EmailAddress', 'EmployeeID', 'EmployeeNumber', 'HomeDirectory', 'HomeDrive', 'HomePage', 'ProfilePath', 'LogonScript', 'Notes', 'OfficePhone', 'MobilePhone', 'Fax', 'Pager', 'IPPhone', 'HomePhone', 'CommonName', 'Manager', 'LogonWorkstations', 'Organization', 'OtherName' ) $testBooleanProperties = @( 'PasswordNeverExpires', 'CannotChangePassword', 'ChangePasswordAtLogon', 'TrustedForDelegation', 'Enabled','AccountNotDelegated', 'AllowReversiblePasswordEncryption', 'CompoundIdentitySupported', 'PasswordNotRequired', 'SmartcardLogonRequired' ) $testArrayProperties = @('ServicePrincipalNames', 'ProxyAddresses') #region Function Get-TargetResource Describe 'xADUser\Get-TargetResource' { It "Returns a 'System.Collections.Hashtable' object type" { Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $fakeADUser } $adUser = Get-TargetResource @testPresentParams $adUser -is [System.Collections.Hashtable] | Should -Be $true } It "Returns 'Ensure' is 'Present' when user account exists" { Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $fakeADUser } $adUser = Get-TargetResource @testPresentParams $adUser.Ensure | Should -Be 'Present' } It "Returns 'Ensure' is 'Absent' when user account does not exist" { Mock -CommandName Get-ADUser -MockWith { throw New-Object Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException } $adUser = Get-TargetResource @testPresentParams $adUser.Ensure | Should -Be 'Absent' } It "Should throw the correct exception when Get-ADUser returns an unknown error" { Mock -CommandName Get-ADUser -MockWith { throw } $expectedError = $script:localizedData.RetrievingADUserError -f $testPresentParams.UserName, $testPresentParams.DomainName { Get-TargetResource @testPresentParams } | Should -Throw $expectedError } It "Calls 'Get-ADUser' with 'Server' parameter when 'DomainController' specified" { Mock -CommandName Get-ADUser -ParameterFilter { $Server -eq $testDomainController } -MockWith { return [PSCustomObject] $fakeADUser } Get-TargetResource @testPresentParams -DomainController $testDomainController Assert-MockCalled -CommandName Get-ADUser -ParameterFilter { $Server -eq $testDomainController } -Scope It } It "Calls 'Get-ADUser' with 'Credential' parameter when 'DomainAdministratorCredential' specified" { Mock -CommandName Get-ADUser -ParameterFilter { $Credential -eq $testCredential } -MockWith { return [PSCustomObject] $fakeADUser } Get-TargetResource @testPresentParams -DomainAdministratorCredential $testCredential Assert-MockCalled -CommandName Get-ADUser -ParameterFilter { $Credential -eq $testCredential } -Scope It } It "Should return the correct value for an Array property" { Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $fakeADUser } $adUser = Get-TargetResource @testPresentParams -ServicePrincipalNames '' -Verbose $adUser.ServicePrincipalNames | Should -Be $fakeADUser.ServicePrincipalName } It "Should return the correct value of 'ChangePassswordAtLogon' if it is true" { $mockADUser = $fakeADUser.Clone() $mockADUser['pwdLastSet'] = 0 $mockPresentParams = $testPresentParams.Clone() $mockPresentParams['ChangePasswordAtLogon'] = $true Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $mockADUser } $adUser = Get-TargetResource @mockPresentParams $adUser.ChangePasswordAtLogon | Should -Be $true } It "Should return the correct value of 'ChangePassswordAtLogon' if it is false" { $mockADUser = $fakeADUser.Clone() $mockADUser['pwdLastSet'] = 12345678 $mockPresentParams = $testPresentParams.Clone() $mockPresentParams['ChangePasswordAtLogon'] = $true Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $mockADUser } $adUser = Get-TargetResource @mockPresentParams $adUser.ChangePasswordAtLogon | Should -Be $false } } #endregion #region Function Test-TargetResource Describe 'xADUser\Test-TargetResource' { It "Passes when user account does not exist and 'Ensure' is 'Absent'" { Mock -CommandName Get-TargetResource -MockWith { return $testAbsentParams } Test-TargetResource @testAbsentParams | Should -Be $true } It "Passes when user account exists and 'Ensure' is 'Present'" { Mock -CommandName Get-TargetResource -MockWith { return $testPresentParams } Test-TargetResource @testPresentParams | Should -Be $true } It "Passes when user account password matches, 'Password' is specified and 'PasswordNeverResets' is False" { Mock -CommandName Get-TargetResource -MockWith { return $testPresentParams } Mock -CommandName Test-Password { return $true } Test-TargetResource @testPresentParams -Password $testCredential | Should -Be $true } It "Passes when user account password does not match, 'Password' is specified and 'PasswordNeverResets' is True" { Mock -CommandName Get-TargetResource -MockWith { return $testPresentParams } Mock -CommandName Test-Password { return $false } Test-TargetResource @testPresentParams -Password $testCredential -PasswordNeverResets $true | Should -Be $true } It "Fails when user account does not exist and 'Ensure' is 'Present'" { Mock -CommandName Get-TargetResource -MockWith { return $testAbsentParams } Test-TargetResource @testPresentParams | Should -Be $false } It "Fails when user account exists, and 'Ensure' is 'Absent'" { Mock -CommandName Get-TargetResource -MockWith { return $testPresentParams } Test-TargetResource @testAbsentParams | Should -Be $false } It "Fails when user account password is incorrect, 'Password' is specified and 'PasswordNeverResets' is False" { Mock -CommandName Get-TargetResource -MockWith { return $testPresentParams } Mock -CommandName Test-Password { return $false } Test-TargetResource @testPresentParams -Password $testCredential | Should -Be $false } It "Calls 'Test-Password' with 'Default' PasswordAuthentication by default" { Mock -CommandName Get-TargetResource -MockWith { return $testPresentParams } Mock -CommandName Test-Password -ParameterFilter { $PasswordAuthentication -eq 'Default' } { return $true } Test-TargetResource @testPresentParams -Password $testCredential Assert-MockCalled -CommandName Test-Password -ParameterFilter { $PasswordAuthentication -eq 'Default' } -Scope It } It "Calls 'Test-Password' with 'Negotiate' PasswordAuthentication when specified" { Mock -CommandName Get-TargetResource -MockWith { return $testPresentParams } Mock -CommandName Test-Password -ParameterFilter { $PasswordAuthentication -eq 'Negotiate' } { return $false } Test-TargetResource @testPresentParams -Password $testCredential -PasswordAuthentication 'Negotiate' Assert-MockCalled -CommandName Test-Password -ParameterFilter { $PasswordAuthentication -eq 'Negotiate' } -Scope It } foreach ($testParameter in $testStringProperties) { It "Passes when user account '$testParameter' matches AD account property" { $testParameterValue = 'Test Parameter String Value' $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() $invalidADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = $testParameterValue return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } It "Fails when user account '$testParameter' does not match incorrect AD account property value" { $testParameterValue = 'Test Parameter String Value' $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() $invalidADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $invalidADUser[$testParameter] = $testParameterValue.Substring(0, ([System.Int32] $testParameterValue.Length / 2)) return $invalidADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } It "Fails when user account '$testParameter' does not match empty AD account property value" { $testParameterValue = 'Test Parameter String Value' $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() $invalidADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $invalidADUser[$testParameter] = '' return $invalidADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } It "Fails when user account '$testParameter' does not match null AD account property value" { $testParameterValue = 'Test Parameter String Value' $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() $invalidADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $invalidADUser[$testParameter] = $null return $invalidADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } It "Passes when empty user account '$testParameter' matches empty AD account property" { $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = '' return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } It "Passes when empty user account '$testParameter' matches null AD account property" { $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = $null return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } } #end foreach test string property foreach ($testParameter in $testBooleanProperties) { It "Should Pass when user account '$testParameter' is true and matches AD account property" { $testParameterValue = $true $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = $testParameterValue return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } It "Should fail when user account '$testParameter' is true and does not match AD account property value" { $testParameterValue = $true $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $invalidADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $invalidADUser[$testParameter] = -not $testParameterValue return $invalidADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } It "Should pass when user account '$testParameter' is false matches AD account property" { $testParameterValue = $false $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = $testParameterValue return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } It "Should fail when user account '$testParameter' is false and does not match AD account property value" { $testParameterValue = $false $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $invalidADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $invalidADUser[$testParameter] = -not $testParameterValue return $invalidADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } } #end foreach test boolean property foreach ($testParameter in $testArrayProperties) { It "Passes when user account '$testParameter' matches empty AD account property" { $testParameterValue = @() $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = $testParameterValue return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } It "Passes when user account '$testParameter' matches single AD account property" { $testParameterValue = @('Entry1') $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = $testParameterValue return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } It "Passes when user account '$testParameter' matches multiple AD account property" { $testParameterValue = @('Entry1', 'Entry2') $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = $testParameterValue return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $true } It "Fails when user account '$testParameter' does not match AD account property count" { $testParameterValue = @('Entry1', 'Entry2') $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = @('Entry1') return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } It "Fails when user account '$testParameter' does not match AD account property name" { $testParameterValue = @('Entry1') $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = @('Entry2') return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } It "Fails when user account '$testParameter' does not match empty AD account property" { $testParameterValue = @('Entry1') $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = @() return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } It "Fails when empty user account '$testParameter' does not match AD account property" { $testParameterValue = @() $testValidPresentParams = $testPresentParams.Clone() $testValidPresentParams[$testParameter] = $testParameterValue $validADUser = $testPresentParams.Clone() Mock -CommandName Get-TargetResource -MockWith { $validADUser[$testParameter] = @('ExtraEntry1') return $validADUser } Test-TargetResource @testValidPresentParams | Should -Be $false } }#end foreach test array property } #endregion #region Function Set-TargetResource Describe 'xADUser\Set-TargetResource' { It "Calls 'New-ADUser' when 'Ensure' is 'Present' and the account does not exist" { $newUserName = 'NewUser' $newAbsentParams = $testAbsentParams.Clone() $newAbsentParams['UserName'] = $newUserName $newPresentParams = $testPresentParams.Clone() $newPresentParams['UserName'] = $newUserName Mock -CommandName New-ADUser -ParameterFilter { $Name -eq $newUserName } Mock -CommandName Set-ADUser Mock -CommandName Get-TargetResource -ParameterFilter { $Username -eq $newUserName } { return $newAbsentParams } Set-TargetResource @newPresentParams Assert-MockCalled -CommandName New-ADUser -ParameterFilter { $Name -eq $newUserName } -Scope It } It "Calls 'Move-ADObject' when 'Ensure' is 'Present', the account exists but Path is incorrect" { $testTargetPath = 'CN=Users,DC=contoso,DC=com' Mock -CommandName Set-ADUser Mock -CommandName Get-ADUser -MockWith { $duffADUser = $fakeADUser.Clone() $duffADUser['DistinguishedName'] = "CN=$($testPresentParams.UserName),OU=WrongPath,DC=contoso,DC=com" return $duffADUser } Mock -CommandName Move-ADObject -ParameterFilter { $TargetPath -eq $testTargetPath } Set-TargetResource @testPresentParams -Path $testTargetPath -Enabled $true Assert-MockCalled -CommandName Move-ADObject -ParameterFilter { $TargetPath -eq $testTargetPath } -Scope It } It "Calls 'Rename-ADObject' when 'Ensure' is 'Present', the account exists but 'CommonName' is incorrect" { $testCommonName = 'Test Common Name' Mock -CommandName Set-ADUser Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Rename-ADObject -ParameterFilter { $NewName -eq $testCommonName } Set-TargetResource @testPresentParams -CommonName $testCommonName -Enabled $true Assert-MockCalled -CommandName Rename-ADObject -ParameterFilter { $NewName -eq $testCommonName } -Scope It } It "Calls 'Set-ADAccountPassword' when 'Password' parameter is specified and 'PasswordNeverResets' is False" { Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Set-ADUser Mock -CommandName Set-ADAccountPassword -ParameterFilter { $NewPassword -eq $testCredential.Password } Mock -CommandName Test-Password -MockWith { $false } Set-TargetResource @testPresentParams -Password $testCredential Assert-MockCalled -CommandName Set-ADAccountPassword -ParameterFilter { $NewPassword -eq $testCredential.Password } -Scope It } It "Does not call 'Set-ADAccountPassword' when 'Password' parameter is specified and 'PasswordNeverResets' is True" { Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Set-ADUser Mock -CommandName Set-ADAccountPassword Set-TargetResource @testPresentParams -Password $testCredential -PasswordNeverResets $true Assert-MockCalled -CommandName Set-ADAccountPassword -Scope It -Times 0 } It "Does not call 'Set-ADAccountPassword' when 'Password' parameter is specified and is in the desired state" { Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Set-ADUser Mock -CommandName Set-ADAccountPassword Mock -CommandName Test-Password -MockWith { $true } Set-TargetResource @testPresentParams -Password $testCredential Assert-MockCalled -CommandName Set-ADAccountPassword -Scope It -Times 0 } It "Calls 'Test-Password' with the correct parameters when 'DomainAdministratorCredential' is specified" { Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Set-ADUser Mock -CommandName Set-ADAccountPassword -ParameterFilter { $NewPassword -eq $testCredential.Password } Mock -CommandName Test-Password -ParameterFilter { $DomainAdministratorCredential -eq $testCredential } -MockWith { $true } Set-TargetResource @testPresentParams -Password $testCredential -DomainAdministratorCredential $testCredential Assert-MockCalled -CommandName Test-Password -ParameterFilter { $DomainAdministratorCredential -eq $testCredential } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Replace' when existing mismatched AD property is null" { $testADPropertyName = 'Description' Mock -CommandName Get-ADUser -MockWith { $duffADUser = $fakeADUser.Clone() $duffADUser[$testADPropertyName] = $null return $duffADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } Set-TargetResource @testPresentParams -Description 'My custom description' Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Replace' when existing mismatched AD property is empty" { $testADPropertyName = 'Description' Mock -CommandName Get-ADUser -MockWith { $duffADUser = $fakeADUser.Clone() $duffADUser[$testADPropertyName] = '' return $duffADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } Set-TargetResource @testPresentParams -Description 'My custom description' Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Clear' when new mismatched AD property is empty" { $testADPropertyName = 'Description' Mock -CommandName Get-ADUser -MockWith { $duffADUser = $fakeADUser.Clone() $duffADUser[$testADPropertyName] = 'Incorrect parameter value' return $duffADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Clear -eq $testADPropertyName } Set-TargetResource @testPresentParams -Description '' Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Clear -eq $testADPropertyName } -Scope It -Exactly 1 } It "Calls 'Set-ADUser' with 'Replace' when existing mismatched AD property is null" { $testADPropertyName = 'Title' Mock -CommandName Get-ADUser -MockWith { $duffADUser = $fakeADUser.Clone() $duffADUser[$testADPropertyName] = $null return $duffADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } Set-TargetResource @testPresentParams -JobTitle 'Gaffer' Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Replace' when new mismatched AD property is not empty" { $testADPropertyName = 'Title' Mock -CommandName Get-ADUser -MockWith { $duffADUser = $fakeADUser.Clone() $duffADUser[$testADPropertyName] = 'Incorrect job title' return $duffADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } Set-TargetResource @testPresentParams -JobTitle 'Gaffer' Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey($testADPropertyName) } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Replace' when existing mismatched AD array property is empty" { $mockSPNs = @('spn/a', 'spn/b') $mockADUser = $fakeADUser.Clone() $mockADUser['ServicePrincipalName'] = '' Mock -CommandName Get-ADUser -MockWith { return $mockADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey('ServicePrincipalName') } Set-TargetResource @testPresentParams -ServicePrincipalNames $mockSPNs Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey('ServicePrincipalName') } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Replace' when existing mismatched AD array property is not empty" { $testSPNs = @('spn/c', 'spn/d') Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey('ServicePrincipalName') } Set-TargetResource @testPresentParams -ServicePrincipalNames $testSPNs Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey('ServicePrincipalName') } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Clear' when new mismatched AD array property is empty" { $testSPNs = '' Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Clear -eq 'ServicePrincipalName' } Set-TargetResource @testPresentParams -ServicePrincipalNames $testSPNs Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Clear -eq 'ServicePrincipalName' } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with 'Replace' when new mismatched AD array property is not empty" { $testSPNs = @('spn/c', 'spn/d') Mock -CommandName Get-ADUser -MockWith { return $fakeADUser } Mock -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey('ServicePrincipalName') } Set-TargetResource @testPresentParams -ServicePrincipalNames $testSPNs Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $Replace.ContainsKey('ServicePrincipalName') } -Scope It -Exactly 1 } It "Calls 'Remove-ADUser' when 'Ensure' is 'Absent' and user account exists" { Mock -CommandName Get-ADUser -MockWith { return [PSCustomObject] $fakeADUser } Mock -CommandName Remove-ADUser -ParameterFilter { $Identity.ToString() -eq $testAbsentParams.UserName } Set-TargetResource @testAbsentParams Assert-MockCalled -CommandName Remove-ADUser -ParameterFilter { $Identity.ToString() -eq $testAbsentParams.UserName } -Scope It } It "Should call 'Set-ADUser' with the correct parameter when new AD boolean property is true and old property is false" { $mockBoolParam = 'CannotChangePassword' $mockADUser = $fakeADUser.Clone() $mockADUser[$mockBoolParam] = $false Mock -CommandName Get-ADUser -MockWith { return $mockADUser } Mock -CommandName Set-ADUser -ParameterFilter { $mockBoolParam } $mockSetTargetResourceParams = @{ $mockBoolParam = $true } Set-TargetResource @testPresentParams @mockSetTargetResourceParams Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $mockBoolParam } -Scope It -Exactly 1 } It "Should call 'Set-ADUser' with the correct parameter when new AD boolean property is false and old property is true" { $mockBoolParam = 'CannotChangePassword' $mockADUser = $fakeADUser.Clone() $mockADUser[$mockBoolParam] = $true Mock -CommandName Get-ADUser -MockWith { return $mockADUser } Mock -CommandName Set-ADUser -ParameterFilter { $mockBoolParam } $mockSetTargetResourceParams = @{ $mockBoolParam = $false } Set-TargetResource @testPresentParams @mockSetTargetResourceParams Assert-MockCalled -CommandName Set-ADUser -ParameterFilter { $mockBoolParam } -Scope It -Exactly 1 } Context 'When RestoreFromRecycleBin is used' { BeforeAll { Mock -CommandName Get-TargetResource -MockWith { if ($script:mockCounter -gt 0) { return @{ Ensure = 'Present' } } $script:mockCounter++ return @{ Ensure = 'Absent' } } Mock -CommandName New-ADUser # Had to overwrite parameter filter from an earlier test Mock -CommandName Set-ADUser -ParameterFilter { return $true } } It 'Should calls Restore-AdCommonObject' { $restoreParam = $testPresentParams.Clone() $restoreParam.RestoreFromRecycleBin = $true $script:mockCounter = 0 Mock -CommandName Restore-ADCommonObject -MockWith { return [PSCustomObject]@{ ObjectClass = 'user' } } Set-TargetResource @restoreParam Assert-MockCalled -CommandName Restore-ADCommonObject -Scope It Assert-MockCalled -CommandName New-ADUser -Times 0 -Exactly -Scope It Assert-MockCalled -CommandName Set-ADUser -Scope It } It 'Should call New-ADUser if no object was found in the recycle bin' { $restoreParam = $testPresentParams.Clone() $restoreParam.RestoreFromRecycleBin = $true $script:mockCounter = 0 Mock -CommandName Restore-ADCommonObject Set-TargetResource @restoreParam Assert-MockCalled -CommandName Restore-ADCommonObject -Scope It Assert-MockCalled -CommandName New-ADUser -Scope It Assert-MockCalled -CommandName Set-ADUser -Scope It } It 'Should throw the correct error when then object cannot be restored from recycle bin' { $restoreParam = $testPresentParams.Clone() $restoreParam.RestoreFromRecycleBin = $true $script:mockCounter = 0 Mock -CommandName Restore-ADCommonObject -MockWith { throw (New-Object -TypeName System.InvalidOperationException) } { Set-TargetResource @restoreParam } | Should -Throw Assert-MockCalled -CommandName Restore-ADCommonObject -Scope It Assert-MockCalled -CommandName New-ADUser -Scope It -Exactly -Times 0 Assert-MockCalled -CommandName Set-ADUser -Scope It -Exactly -Times 0 } } } #endregion #region Function Assert-TargetResource Describe 'xADUser\Assert-Parameters' { It "Does not throw when 'PasswordNeverExpires' and 'CannotChangePassword' are specified" { { Assert-Parameters -PasswordNeverExpires $true -CannotChangePassword $true } | Should -Not -Throw } It "Throws when account is disabled and 'Password' is specified" { { Assert-Parameters -Password $testCredential -Enabled $false } | Should -Throw } It "Does not throw when 'TrustedForDelegation' is specified" { { Assert-Parameters -TrustedForDelegation $true } | Should -Not -Throw } It "Should throw the correct error when 'PasswordNeverExpires' and 'ChangePasswordAtLogon' are specified" { { Assert-Parameters -PasswordNeverExpires $true -ChangePasswordAtLogon $true } | ` Should -Throw $script:localizedData.ChangePasswordParameterConflictError } } #endregion } } finally { Invoke-TestCleanup } |