From 6942331a80fa20fdb1c34fe104deca6c26f739d2 Mon Sep 17 00:00:00 2001 From: Simon Heather <32168619+X-Guardian@users.noreply.github.com> Date: Sat, 16 Nov 2019 11:04:17 +0000 Subject: [PATCH] ADObjectPermissionEntry: Update Assert-ADPSDrive with PSProvider Checks (#528) - Changes to ADObjectPermissionEntry - Updated Assert-ADPSDrive with PSProvider Checks (issue #527). --- CHANGELOG.md | 2 + .../ActiveDirectoryDsc.Common.psm1 | 36 +++- .../ActiveDirectoryDsc.Common.strings.psd1 | 2 + Tests/Unit/ActiveDirectory.Common.Tests.ps1 | 163 ++++++++++++++---- 4 files changed, 165 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73282c980..3132d8aa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ - Resource Integration tests added. - Changes to ADKDSKey - Added Integration testing ([issue #351](https://github.com/PowerShell/ActiveDirectoryDsc/issues/351)) +- Changes to ADObjectPermissionEntry + - Updated Assert-ADPSDrive with PSProvider Checks ([issue #527](https://github.com/PowerShell/ActiveDirectoryDsc/issues/527)). ## 4.2.0.0 diff --git a/Modules/ActiveDirectoryDsc.Common/ActiveDirectoryDsc.Common.psm1 b/Modules/ActiveDirectoryDsc.Common/ActiveDirectoryDsc.Common.psm1 index 1e95d6824..c47c10fe0 100644 --- a/Modules/ActiveDirectoryDsc.Common/ActiveDirectoryDsc.Common.psm1 +++ b/Modules/ActiveDirectoryDsc.Common/ActiveDirectoryDsc.Common.psm1 @@ -1880,6 +1880,38 @@ function Test-DscPropertyState return $returnValue } +<# + .SYNOPSIS + Asserts if the AD PS Provider has been installed. + + .NOTES + Attempts to force import the ActiveDirectory module if the AD PS Provider has not been installed + and throws an exception if the AD PS Provider cannot be installed. +#> + +function Assert-ADPSProvider +{ + [CmdletBinding()] + param() + + $activeDirectoryPSProvider = Get-PSProvider -PSProvider 'ActiveDirectory' -ErrorAction SilentlyContinue + + if ($null -eq $activeDirectoryPSProvider) + { + Write-Verbose -Message $script:localizedData.AdPsProviderNotFound -Verbose + Import-Module -Name 'ActiveDirectory' -Force + try + { + $activeDirectoryPSProvider = Get-PSProvider -PSProvider 'ActiveDirectory' + } + catch + { + $errorMessage = $script:localizedData.AdPsProviderInstallFailureError + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + } +} + <# .SYNOPSIS Asserts if the AD PS Drive has been created, and creates one if not. @@ -1900,7 +1932,9 @@ function Assert-ADPSDrive $Root = '//RootDSE/' ) - Assert-Module -ModuleName 'ActiveDirectory' -ImportModule + Assert-Module -ModuleName 'ActiveDirectory' + + Assert-ADPSProvider $activeDirectoryPSDrive = Get-PSDrive -Name AD -ErrorAction SilentlyContinue diff --git a/Modules/ActiveDirectoryDsc.Common/en-US/ActiveDirectoryDsc.Common.strings.psd1 b/Modules/ActiveDirectoryDsc.Common/en-US/ActiveDirectoryDsc.Common.strings.psd1 index 14d6d50e8..68dccca1d 100644 --- a/Modules/ActiveDirectoryDsc.Common/en-US/ActiveDirectoryDsc.Common.strings.psd1 +++ b/Modules/ActiveDirectoryDsc.Common/en-US/ActiveDirectoryDsc.Common.strings.psd1 @@ -51,4 +51,6 @@ ConvertFrom-StringData @' SearchingForDomainControllerInSite = Searching for a domain controller in the site '{0}' in the domain '{1}'. (ADCOMMON0053) IgnoreCredentialError = Suppressing the credential error '{0}' with the message '{1}'. (ADCOMMON0054) NoObjectFoundInRecycleBin = Did not find a restorable object in the recycle bin. (ADCOMMON0055) + AdPsProviderNotFound = The Active Directory PS Provider was not found, Forcing import of the ActiveDirectory module. (ADCOMMON0056) + AdPsProviderInstallFailureError = Error installing the Active Directory PS Provider. (ADCOMMON0057) '@ diff --git a/Tests/Unit/ActiveDirectory.Common.Tests.ps1 b/Tests/Unit/ActiveDirectory.Common.Tests.ps1 index 0348b9045..bcc5c21c0 100644 --- a/Tests/Unit/ActiveDirectory.Common.Tests.ps1 +++ b/Tests/Unit/ActiveDirectory.Common.Tests.ps1 @@ -2171,69 +2171,158 @@ InModuleScope 'ActiveDirectoryDsc.Common' { } } - Describe 'ActiveDirectoryDsc.Common\Assert-ADPSDrive' { - Mock -CommandName Assert-Module + Describe 'ActiveDirectoryDsc.Common\Assert-ADPSProvider' { + BeforeAll { - Context 'When the AD PS Drive does not exist and the New-PSDrive function is successful' { - Mock -CommandName Get-PSDrive -MockWith { $null } - Mock -CommandName New-PSDrive + } - It 'Should not throw' { - { Assert-ADPSDrive } | Should -Not -Throw - } + Context 'When the AD PS Provider is installed' { + BeforeAll { + $mockPSProviderResult = @{ + Name = 'ActiveDirectory' + } - It 'Should have called Assert-Module' { - Assert-MockCalled -CommandName Assert-Module -Exactly -Times 1 -Scope Context + Mock -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -eq 'SilentlyContinue' } ` + -MockWith { $mockPSProviderResult } + Mock -CommandName Import-Module } - It 'Should have called Get-PSDrive only once' { - Assert-MockCalled -CommandName Get-PSDrive -Exactly -Times 1 -Scope Context + It 'Should not throw' { + { Assert-ADPSProvider -Verbose } | Should -Not -Throw } - It 'Should have called New-PSDrive only once' { - Assert-MockCalled -CommandName New-PSDrive -Exactly -Times 1 -Scope Context + It 'Should call the expected mocks' { + Assert-MockCalled -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -eq 'SilentlyContinue' } ` + -Exactly -Times 1 + Assert-MockCalled -CommandName Import-Module -Exactly -Times 0 } } - Context 'When the AD PS Drive does not exist and the New-PSDrive function is not successful' { - Mock -CommandName Get-PSDrive -MockWith { $null } - Mock -CommandName New-PSDrive -MockWith { throw } + Context 'When the AD PS Provider is not installed' { - It 'Should throw the correct error' { - { Assert-ADPSDrive } | Should -Throw $script:localizedString.CreatingNewADPSDriveError + Context 'When the AD PS Provider is successfully installed by Import-Module' { + BeforeAll { + $mockPSProviderResult = @{ + Name = 'ActiveDirectory' + } + + Mock -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -eq 'SilentlyContinue' } + Mock -CommandName Import-Module + Mock -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -ne 'SilentlyContinue' } ` + -MockWith { $mockPSProviderResult } + } + + It 'Should not throw' { + { Assert-ADPSProvider } | Should -Not -Throw + } + + It 'Should call the expected mocks' { + Assert-MockCalled -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -eq 'SilentlyContinue' } ` + -Exactly -Times 1 + Assert-MockCalled -CommandName Import-Module -Exactly -Times 1 + Assert-MockCalled -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -ne 'SilentlyContinue' } ` + -Exactly -Times 1 + } } - It 'Should call Assert-Module' { - Assert-MockCalled -CommandName Assert-Module -Exactly -Times 1 -Scope Context + Context 'When the AD PS Provider is not successfully installed by Import-Module' { + BeforeAll { + Mock -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -eq 'SilentlyContinue' } + Mock -CommandName Import-Module + Mock -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -ne 'SilentlyContinue' } ` + -MockWith { Throw 'Error'} + } + + It 'Should throw the correct exception' { + { Assert-ADPSProvider } | Should -Throw $script:localizedData.AdPsProviderInstallFailureError + } + + It 'Should call the expected mocks' { + Assert-MockCalled -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -eq 'SilentlyContinue' } ` + -Exactly -Times 1 + Assert-MockCalled -CommandName Import-Module -Exactly -Times 1 + Assert-MockCalled -CommandName Get-PSProvider ` + -ParameterFilter { $PSBoundParameters['ErrorAction'] -ne 'SilentlyContinue' } ` + -Exactly -Times 1 + } } + } + } - It 'Should call Get-PSDrive once' { - Assert-MockCalled -CommandName Get-PSDrive -Exactly -Times 1 -Scope Context + Describe 'ActiveDirectoryDsc.Common\Assert-ADPSDrive' { + BeforeAll { + $defaultPSDriveRoot = '//RootDSE/' + Mock -CommandName Assert-Module + Mock -CommandName Assert-ADPSProvider + } + + Context 'When the AD PS Drive does not exist' { + BeforeAll { + Mock -CommandName Get-PSDrive } - It 'Should call New-PSDrive once' { - Assert-MockCalled -CommandName New-PSDrive -Exactly -Times 1 -Scope Context + Context 'When the New-PSDrive function is successful' { + BeforeAll { + Mock -CommandName New-PSDrive + } + + It 'Should not throw' { + { Assert-ADPSDrive } | Should -Not -Throw + } + + It 'Should call the expected mocks' { + Assert-MockCalled -CommandName Assert-Module -Exactly -Times 1 + Assert-MockCalled -CommandName Get-PSDrive -Exactly -Times 1 + Assert-MockCalled -CommandName New-PSDrive ` + -ParameterFilter { $Root -eq $defaultPSDriveRoot } ` + -Exactly -Times 1 + } } - } - Context 'When the AD PS Drive already exists' { - Mock -CommandName Get-PSDrive -MockWith { New-MockObject -Type System.Management.Automation.PSDriveInfo } - Mock -CommandName New-PSDrive + Context 'When the New-PSDrive function is not successful' { + BeforeAll { + Mock -CommandName New-PSDrive -MockWith { throw } + } - It 'Should not throw' { - { Assert-ADPSDrive } | Should -Not -Throw + It 'Should throw the correct error' { + { Assert-ADPSDrive } | Should -Throw $script:localizedString.CreatingNewADPSDriveError + } + + It 'Should call the expected mocks' { + Assert-MockCalled -CommandName Assert-Module -Exactly -Times 1 + Assert-MockCalled -CommandName Get-PSDrive -Exactly -Times 1 + Assert-MockCalled -CommandName New-PSDrive ` + -ParameterFilter { $Root -eq $defaultPSDriveRoot } ` + -Exactly -Times 1 + } } + } - It 'Should call Assert-Module only once' { - Assert-MockCalled -CommandName Assert-Module -Exactly -Times 1 -Scope Context + Context 'When the AD PS Drive already exists' { + BeforeAll { + Mock -CommandName Get-PSDrive -MockWith { New-MockObject -Type System.Management.Automation.PSDriveInfo } + Mock -CommandName New-PSDrive } - It 'Should call Get-PSDrive only once' { - Assert-MockCalled -CommandName Get-PSDrive -Exactly -Times 1 -Scope Context + It 'Should not throw' { + { Assert-ADPSDrive } | Should -Not -Throw } - It 'Should not call New-PSDrive' { - Assert-MockCalled -CommandName New-PSDrive -Exactly -Times 0 -Scope Context + It 'Should call the expected mocks' { + Assert-MockCalled -CommandName Assert-Module -Exactly -Times 1 + Assert-MockCalled -CommandName Get-PSDrive ` + -ParameterFilter { $Name -eq 'AD' } ` + -Exactly -Times 1 + Assert-MockCalled -CommandName New-PSDrive -Exactly -Times 0 } } }