diff --git a/ActiveDirectoryCSDsc.psd1 b/ActiveDirectoryCSDsc.psd1 index 0bae19f..c0be4a1 100644 --- a/ActiveDirectoryCSDsc.psd1 +++ b/ActiveDirectoryCSDsc.psd1 @@ -41,7 +41,8 @@ 'AdcsEnrollmentPolicyWebService', 'AdcsOnlineResponder', 'AdcsWebEnrollment', - 'AdcsOcspExtension' + 'AdcsOcspExtension', + 'AdcsAiaExtension' ) # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. @@ -84,4 +85,3 @@ } # End of PSData hashtable } # End of PrivateData hashtable } - diff --git a/CHANGELOG.md b/CHANGELOG.md index 256e72e..9fd41bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Added new resource AdcsAiaExtension - see [Issue #78](https://github.com/PowerShell/ActiveDirectoryCSDsc/issues/78). - Remove reference to StorageDsc in README.md - fixes [Issue #76](https://github.com/PowerShell/ActiveDirectoryCSDsc/issues/76). ## 3.2.0.0 diff --git a/DSCResources/MSFT_AdcsAiaExtension/MSFT_AdcsAiaExtension.psm1 b/DSCResources/MSFT_AdcsAiaExtension/MSFT_AdcsAiaExtension.psm1 new file mode 100644 index 0000000..567ba70 --- /dev/null +++ b/DSCResources/MSFT_AdcsAiaExtension/MSFT_AdcsAiaExtension.psm1 @@ -0,0 +1,273 @@ +$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' + +# Import the ADCS Deployment Resource Common Module. +Import-Module -Name (Join-Path -Path $modulePath ` + -ChildPath (Join-Path -Path 'ActiveDirectoryCSDsc.CommonHelper' ` + -ChildPath 'ActiveDirectoryCSDsc.CommonHelper.psm1')) + +# Import the ADCS Deployment Resource Helper Module. +Import-Module -Name (Join-Path -Path $modulePath ` + -ChildPath (Join-Path -Path 'ActiveDirectoryCSDsc.ResourceHelper' ` + -ChildPath 'ActiveDirectoryCSDsc.ResourceHelper.psm1')) + +# Import Localization Strings. +$LocalizedData = Get-LocalizedData ` + -ResourceName 'MSFT_AdcsAiaExtension' ` + -ResourcePath (Split-Path -Parent $script:MyInvocation.MyCommand.Path) + +<# + .SYNOPSIS + Gets the current certificate Authority Information Access (AIA) Uniform Resource Identifiers (URI) + settings. + + .PARAMETER IsSingleInstance + Specifies the resource is a single instance, the value must be 'Yes'. + Not used in Get-TargetResource. + + .PARAMETER AiaUri + Specifies the URI location where issuer of certificate is located. + Not used in Get-TargetResource. + + .PARAMETER RestartService + Specifies if the service should be restarted. + Not used in Get-TargetResource. + + .PARAMETER Ensure + Ensures that the Authority Information Access (AIA) Uniform Resource Identifiers (URI) is Present or Absent. + Not used in Get-TargetResource. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Yes')] + [System.String] + $IsSingleInstance, + + [Parameter(Mandatory = $true)] + [System.String[]] + $AiaUri, + + [Parameter()] + [System.Boolean] + $RestartService, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present' + ) + + Write-Verbose -Message $localizedData.GetAiaUris + + [System.Array] $currentAiaUriList = (Get-CAAuthorityInformationAccess).Where( { + $_.AddToCertificateAia -eq $true + } ).Uri + + return @{ + AiaUri = $currentAiaUriList + Ensure = $Ensure + IsSingleInstance = $IsSingleInstance + RestartService = $RestartService + } +} + +<# + .SYNOPSIS + Configures the current Authority Information Access (AIA) settings for the certification authority. + + .PARAMETER IsSingleInstance + Specifies the resource is a single instance, the value must be 'Yes'. + + .PARAMETER AiaUri + Specifies the URI location where issuer of certificate is located. + + .PARAMETER RestartService + Specifies if the service should be restarted. + + .PARAMETER Ensure + Ensures that the Authority Information Access (AIA) Uniform Resource Identifiers (URI) is Present or Absent. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Yes')] + [System.String] + $IsSingleInstance, + + [Parameter(Mandatory = $true)] + [System.String[]] + $AiaUri, + + [Parameter()] + [System.Boolean] + $RestartService, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present' + ) + + $currentState = Get-TargetResource @PSBoundParameters + $change = $false + + if ($Ensure -eq 'Present') + { + foreach ($uri in $currentState.AiaUri) + { + if ($AiaUri -notcontains $uri) + { + Write-Verbose -Message ($localizedData.RemoveAiAUri -f $uri) + Remove-CAAuthorityInformationAccess -Uri $uri -AddToCertificateAIA -Force + $change = $true + } + } + + foreach ($uri in $AiaUri) + { + if ($currentState.AiaUri -contains $uri) + { + Write-Verbose -Message ($localizedData.RemoveAiAUri -f $uri) + Remove-CAAuthorityInformationAccess -Uri $uri -AddToCertificateAIA -Force + $change = $true + } + + Write-Verbose -Message ($localizedData.AddAiAUri -f $uri) + Add-CAAuthorityInformationAccess -Uri $uri -AddToCertificateAIA -Force + $change = $true + } + } + else + { + foreach ($uri in $AiaUri) + { + Write-Verbose -Message ($localizedData.RemoveAiaUri -f $uri) + Remove-CAAuthorityInformationAccess -Uri $uri -Force -ErrorAction Stop + $change = $true + } + } + + if (($RestartService) -and ($change)) + { + Write-Verbose -Message $localizedData.RestartService + Restart-ServiceIfExists -Name CertSvc + } +} + +<# + .SYNOPSIS + Tests the current certification authority AddToCertificateAia (boolean) and Uniform Resource Identifiers (URI) + settings. + + .PARAMETER IsSingleInstance + Specifies the resource is a single instance, the value must be 'Yes'. + + .PARAMETER AiaUri + Specifies the URI location where issuer of certificate is located. + + .PARAMETER RestartService + Specifies if the service should be restarted. + + .PARAMETER Ensure + Ensures that the Authority Information Access (AIA) Uniform Resource Identifiers (URI) is Present or Absent. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Yes')] + [System.String] + $IsSingleInstance, + + [Parameter(Mandatory = $true)] + [System.String[]] + $AiaUri, + + [Parameter()] + [System.Boolean] + $RestartService, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present' + ) + + $currentState = Get-TargetResource @PSBoundParameters + + $inDesiredState = $true + + if ($Ensure -eq 'Present') + { + if ($currentState.AiaUri.Count -ne $AiaUri.Count) + { + if ($null -ne $currentState.AiaUri) + { + $compareAiaUris = Compare-Object -ReferenceObject $AiaUri -DifferenceObject $currentState.AiaUri -PassThru + + # Desired state AIA URI(s) not found in reference set. + $desiredAiaUrisMissing = $compareAiaUris.Where( { + $_.SideIndicator -eq '<=' + } ) -join ', ' + + # AIA URI(s) found in $currentState that do not match $AiaUri desired state. + $notDesiredAiaUrisFound = $compareAiaUris.Where( { + $_.SideIndicator -eq '=>' + } ) -join ', ' + + if ($desiredAiaUrisMissing) + { + Write-Verbose -Message ($localizedData.DesiredAiasMissing -f $desiredAiaUrisMissing) + $inDesiredState = $false + } + + if ($notDesiredAiaUrisFound) + { + Write-Verbose -Message ($localizedData.AdditionalAiasFound -f $notDesiredAiaUrisFound) + $inDesiredState = $false + } + } + else + { + $aiaUriList = $AiaUri -join ', ' + + Write-Verbose -Message ($localizedData.AiasNull -f $aiaUriList) + $inDesiredState = $false + } + } + + foreach ($uri in $currentState.AiaUri) + { + if ($uri -notin $AiaUri) + { + Write-Verbose -Message ($localizedData.IncorrectAiaUriFound -f $uri) + $inDesiredState = $false + } + } + } + else + { + foreach ($uri in $AiaUri) + { + if ($uri -in $currentState.AiaUri) + { + Write-Verbose -Message ($localizedData.EnsureAbsentButUrisExist -f $uri) + $inDesiredState = $false + } + } + } + + return $inDesiredState +} + +Export-ModuleMember -Function Get-TargetResource, Test-TargetResource, Set-TargetResource diff --git a/DSCResources/MSFT_AdcsAiaExtension/MSFT_AdcsAiaExtension.schema.mof b/DSCResources/MSFT_AdcsAiaExtension/MSFT_AdcsAiaExtension.schema.mof new file mode 100644 index 0000000..ac3e17f --- /dev/null +++ b/DSCResources/MSFT_AdcsAiaExtension/MSFT_AdcsAiaExtension.schema.mof @@ -0,0 +1,8 @@ +[ClassVersion("1.0.0"), FriendlyName("AdcsAiaExtension")] +class MSFT_AdcsAiaExtension : OMI_BaseResource +{ + [Key, Description("Specifies the resource is a single instance, the value must be 'Yes'."), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; + [Required, Description("Specifies the URI location where issuer of certificate is located.")] String AiaUri[]; + [Write, Description("Specifies if the service should be restarted.")] Boolean RestartService; + [Write, Description("Ensures that the Authority Information Access (AIA) Uniform Resource Identifiers (URI) is Present or Absent."), ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure; +}; diff --git a/DSCResources/MSFT_AdcsAiaExtension/README.md b/DSCResources/MSFT_AdcsAiaExtension/README.md new file mode 100644 index 0000000..7a8c033 --- /dev/null +++ b/DSCResources/MSFT_AdcsAiaExtension/README.md @@ -0,0 +1,6 @@ +# Description + +This resource can be used to configure the AIA URI extensions on the +Certificate Authority after the feature has been installed on the server. +Using this DSC Resource to configure an ADCS Certificate AIA assumes that +the `ADCS-Cert-Authority` feature has already been installed. diff --git a/DSCResources/MSFT_AdcsAiaExtension/en-US/MSFT_AdcsAiaExtension.strings.psd1 b/DSCResources/MSFT_AdcsAiaExtension/en-US/MSFT_AdcsAiaExtension.strings.psd1 new file mode 100644 index 0000000..33fecdd --- /dev/null +++ b/DSCResources/MSFT_AdcsAiaExtension/en-US/MSFT_AdcsAiaExtension.strings.psd1 @@ -0,0 +1,11 @@ +ConvertFrom-StringData @' + AdditionalAiasFound = Not in desired state, additional AIA URIs found, "{0}". + AddAiaUri = Adding "{0}" to desired AIA URIs. + DesiredAiasMissing = Not in desired state, missing desired AIA URIs, "{0}". + EnsureAbsentButUrisExist = Not in desired state, AIA URIs should be Absent, but found "{0}". + GetAiaUris = Getting all AIA URIs. + AiasNull = Not in desired state, AIA URIs empty, missing "{0}". + RemoveAiaUri = Removing "{0}" AIA URIs. + RestartService = Preparing to restart the CertSvc for changes to take affect. + IncorrectAiaUriFound = Not in desired state, AIA URI incorrect, found "{0}". +'@ diff --git a/Examples/Resources/AdcsAiaExtension/1-AdcsAiaExtension_AddAia_Config.ps1 b/Examples/Resources/AdcsAiaExtension/1-AdcsAiaExtension_AddAia_Config.ps1 new file mode 100644 index 0000000..9889ed9 --- /dev/null +++ b/Examples/Resources/AdcsAiaExtension/1-AdcsAiaExtension_AddAia_Config.ps1 @@ -0,0 +1,43 @@ +<#PSScriptInfo +.VERSION 1.0.0 +.GUID 93c71497-c4ac-452e-baf1-aff17bd4ecac +.AUTHOR Microsoft Corporation +.COMPANYNAME Microsoft Corporation +.COPYRIGHT +.TAGS DSCConfiguration +.LICENSEURI https://github.com/PowerShell/ActiveDirectoryCSDsc/blob/master/LICENSE +.PROJECTURI https://github.com/PowerShell/ActiveDirectoryCSDsc +.ICONURI +.EXTERNALMODULEDEPENDENCIES +.REQUIREDSCRIPTS +.EXTERNALSCRIPTDEPENDENCIES +.RELEASENOTES First version. +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core +#> + +#Requires -module ActiveDirectoryCSDsc + +<# + .DESCRIPTION + A DSC configuration script to add desired AIA URI extensions for a Certificate Authority. + This will remove all existing AIA URIs from the Certificate Authority. +#> +configuration AdcsAiaExtension_AddAia_Config +{ + Import-DscResource -ModuleName ActiveDirectoryCSDsc + + node localhost + { + AdcsAiaExtension AddAiaUri + { + IsSingleInstance = 'Yes' + AiaUri = @( + 'http://setAIATest1/Certs/.cer' + 'http://setAIATest2/Certs/.cer' + 'http://setAIATest3/Certs/.cer' + ) + RestartService = $true + Ensure = 'Present' + } + } +} diff --git a/Examples/Resources/AdcsAiaExtension/2-AdcsAiaExtension_RemoveAia_Config.ps1 b/Examples/Resources/AdcsAiaExtension/2-AdcsAiaExtension_RemoveAia_Config.ps1 new file mode 100644 index 0000000..603af9c --- /dev/null +++ b/Examples/Resources/AdcsAiaExtension/2-AdcsAiaExtension_RemoveAia_Config.ps1 @@ -0,0 +1,43 @@ +<#PSScriptInfo +.VERSION 1.0.0 +.GUID 95bd5fea-6d07-4c27-bda5-bdaa9bf08437 +.AUTHOR Microsoft Corporation +.COMPANYNAME Microsoft Corporation +.COPYRIGHT +.TAGS DSCConfiguration +.LICENSEURI https://github.com/PowerShell/ActiveDirectoryCSDsc/blob/master/LICENSE +.PROJECTURI https://github.com/PowerShell/ActiveDirectoryCSDsc +.ICONURI +.EXTERNALMODULEDEPENDENCIES +.REQUIREDSCRIPTS +.EXTERNALSCRIPTDEPENDENCIES +.RELEASENOTES First version. +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core +#> + +#Requires -module ActiveDirectoryCSDsc + +<# + .DESCRIPTION + A DSC configuration script to remove desired AIA URI extensions for a Certificate Authority. + No previously configured AIA URIs will be removed. +#> +configuration AdcsAiaExtension_RemoveAia_Config +{ + Import-DscResource -ModuleName ActiveDirectoryCSDsc + + node localhost + { + AdcsAiaExtension RemoveAiaUri + { + IsSingleInstance = 'Yes' + AiaUri = @( + 'http://setAIATest1/Certs/.cer' + 'http://setAIATest2/Certs/.cer' + 'http://setAIATest3/Certs/.cer' + ) + RestartService = $true + Ensure = 'Absent' + } + } +} diff --git a/README.md b/README.md index c6b320e..172d209 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,9 @@ certificates that will automatically be trusted. - **AdcsOcspExtension**: This resource can be used to configure OCSP URI extensions on a Certificate Authority after the feature has been installed on the server. +- **AdcsAiaExtension**: This resource can be used to configure AIA URI + extensions on a Certificate Authority after the feature has been installed + on the server. This project has adopted [this code of conduct](CODE_OF_CONDUCT.md). diff --git a/Tests/Unit/MSFT_AdcsAiaExtension.Tests.ps1 b/Tests/Unit/MSFT_AdcsAiaExtension.Tests.ps1 new file mode 100644 index 0000000..aeda4e8 --- /dev/null +++ b/Tests/Unit/MSFT_AdcsAiaExtension.Tests.ps1 @@ -0,0 +1,294 @@ +Set-StrictMode -Version Latest + +$script:DSCModuleName = 'ActiveDirectoryCSDsc' +$script:DSCResourceName = 'MSFT_AdcsAiaExtension' + +$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 + +# Import Stub function +Import-Module (Join-Path -Path $script:moduleRoot -ChildPath 'Tests\TestHelpers\AdcsStub.psm1') + +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:DSCModuleName ` + -DSCResourceName $script:DSCResourceName ` + -TestType Unit + +try +{ + InModuleScope $DSCResourceName { + $aiaUriList = @( + 'http://setAiaTest/Certs/.cer' + 'http://setAiaTest2/Certs/.cer' + 'file:///CertEnroll/_.crt' + ) + + $presentParams = @{ + AiaUri = $aiaUriList + Ensure = 'Present' + IsSingleInstance = 'Yes' + RestartService = $true + } + + $setRestartServiceFalsePresentParams = @{ + AiaUri = $aiaUriList + Ensure = 'Present' + IsSingleInstance = 'Yes' + RestartService = $false + } + + $absentParams = @{ + AiaUri = $aiaUriList + Ensure = 'Absent' + IsSingleInstance = 'Yes' + RestartService = $true + } + + $setRestartServiceFalseAbsentParams = @{ + AiaUri = $aiaUriList + Ensure = 'Absent' + IsSingleInstance = 'Yes' + RestartService = $false + } + + Describe "$DSCResourceName\Get-TargetResource" -Tag 'Get' { + Context 'When the CA is installed and the Get-CAAuthorityInformationAccess cmdlet returns the AIA URI list' { + $retreivedGetTargetValue = @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest2/Certs/.cer' + } + + Mock -CommandName 'Get-CAAuthorityInformationAccess' -Mockwith { $retreivedGetTargetValue } + + It 'Should return a hashtable with the expected properties.' { + $result = Get-TargetResource @presentParams + + $result | Should -Be System.Collections.Hashtable + $result.AiaUri | Should -Be $retreivedGetTargetValue.Uri + $result.Ensure | Should -Be $presentParams.Ensure + $result.IsSingleInstance | Should -Be $presentParams.IsSingleInstance + $result.RestartService | Should -Be $presentParams.RestartService + } + } + } + + Describe "$DSCResourceName\Set-TargetResource" -Tag 'Set' { + Mock -CommandName Remove-CAAuthorityInformationAccess + Mock -CommandName Add-CAAuthorityInformationAccess + Mock -CommandName Restart-ServiceIfExists + + Context 'When ensure equals present, and AIA record is missing, and $RestartService equals $true' { + $missingAiaUri = @{ + AiaUri = @( + 'http://setAiaTest/Certs/.cer' + 'http://setAiaTest2/Certs/.cer' + 'http://setAiaTest4/Certs/.cer' + ) + Ensure = 'Present' + IsSingleInstance = 'Yes' + RestartService = $true + } + + Mock -CommandName Get-TargetResource -MockWith { $missingAiaUri } + + It 'Should call the expected mocks' { + Set-TargetResource @presentParams + + Assert-MockCalled -CommandName Remove-CAAuthorityInformationAccess -Exactly -Times 3 -Scope It -ParameterFilter { $AiaUri -eq $presentParams.AiaUriList } + Assert-MockCalled -CommandName Add-CAAuthorityInformationAccess -Exactly -Times 3 -Scope It -ParameterFilter { $AiaUri -eq $presentParams.AiaUriList } + Assert-MockCalled -CommandName Restart-ServiceIfExists -Exactly -Times 1 -Scope It -ParameterFilter { $Name -eq 'CertSvc' } + } + } + + Context 'When ensure equals present, and AIA record is missing, and $RestartService equals $false' { + $missingAiaUriRestartServiceFalse = @{ + AiaUri = @( + 'http://setAiaTest/Certs/.cer' + 'http://setAiaTest2/Certs/.cer' + ) + Ensure = 'Present' + IsSingleInstance = 'Yes' + RestartService = $false + } + + Mock -CommandName Get-TargetResource -MockWith { $missingAiaUriRestartServiceFalse } + + It 'Should call the expected mocks' { + Set-TargetResource @setRestartServiceFalsePresentParams + + Assert-MockCalled -CommandName Remove-CAAuthorityInformationAccess -Exactly -Times 2 -Scope It -ParameterFilter { $AiaUri -eq $setRestartServiceFalsePresentParams.AiaUriList } + Assert-MockCalled -CommandName Add-CAAuthorityInformationAccess -Exactly -Times 3 -Scope It -ParameterFilter { $AiaUri -eq $setRestartServiceFalsePresentParams.AiaUriList } + Assert-MockCalled -CommandName Restart-ServiceIfExists -Exactly -Times 0 -Scope It -ParameterFilter { $Name -eq 'CertSvc' } + } + } + + Context 'When ensure equals absent, and AIA records are present, and $RestartService equals $true' { + Mock -CommandName Get-TargetResource -MockWith { $presentParams } + + It 'Should call the expected mocks' { + Set-TargetResource @absentParams + + Assert-MockCalled -CommandName Remove-CAAuthorityInformationAccess -Exactly -Times 3 -Scope It -ParameterFilter { $AiaUri -eq $absentParams.AiaUriList } + Assert-MockCalled -CommandName Add-CAAuthorityInformationAccess -Exactly -Times 0 -Scope It -ParameterFilter { $AiaUri -eq $absentParams.AiaUriList } + Assert-MockCalled -CommandName Restart-ServiceIfExists -Exactly -Times 1 -Scope It -ParameterFilter { $Name -eq 'CertSvc' } + } + } + + Context 'When ensure equals absent, and AIA records are present, and $RestartService equals $false' { + Mock -CommandName Get-TargetResource -MockWith { $setRestartServiceFalsePresentParams } + + It 'Should call the expected mocks' { + Set-TargetResource @setRestartServiceFalseAbsentParams + + Assert-MockCalled -CommandName Remove-CAAuthorityInformationAccess -Exactly -Times 3 -Scope It -ParameterFilter { $AiaUri -eq $setRestartServiceFalseAbsentParams.AiaUriList } + Assert-MockCalled -CommandName Add-CAAuthorityInformationAccess -Exactly -Times 0 -Scope It -ParameterFilter { $AiaUri -eq $setRestartServiceFalseAbsentParams.AiaUriList } + Assert-MockCalled -CommandName Restart-ServiceIfExists -Exactly -Times 0 -Scope It -ParameterFilter { $Name -eq 'CertSvc' } + } + } + } + + Describe "$DSCResourceName\Test-TargetResource" -Tag 'Test' { + Context 'When ensure equals present and in desired state' { + $desiredStateRecordReturned = @( + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest2/Certs/.cer' + } + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest/Certs/.cer' + } + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'file:///CertEnroll/_.crt' + } + ) + + Mock -CommandName 'Get-CAAuthorityInformationAccess' -MockWith { $desiredStateRecordReturned } + + It 'Should return $true' { + Test-TargetResource @presentParams | Should -Be $true + } + } + + Context 'When ensure equals absent and in desired state' { + $absentStateRecordReturned = @() + + Mock -CommandName 'Get-CAAuthorityInformationAccess' -MockWith { $absentStateRecordReturned } + + It 'Should return $true' { + Test-TargetResource @absentParams | Should -Be $true + } + } + + Context 'When ensure equals present, but not in desired state, and no values stored in AIA records when passing in a value for AIA' { + Mock -CommandName 'Get-CAAuthorityInformationAccess' + + It 'Should return $false' { + Test-TargetResource @presentParams | Should -Be $false + } + } + + Context 'When ensure equals present, but not in desired state, and different values are stored in AIA records when passing in a value for AIA' { + $singleRecordReturned = @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest2/Certs/.cer' + } + + Mock -CommandName 'Get-CAAuthorityInformationAccess' -MockWith { $singleRecordReturned } + + It 'Should return $false' { + Test-TargetResource @presentParams | Should -Be $false + } + } + + Context 'When ensure equals absent, but not in desired state, and AIA record is returned' { + $aiaRecordReturned = @( + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest2/Certs/.cer' + } + ) + + Mock -CommandName 'Get-CAAuthorityInformationAccess' -MockWith { $aiaRecordReturned } + + It 'Should return $false' { + Test-TargetResource @absentParams | Should -Be $false + } + } + + Context 'When ensure equals present, but not in desired state, and AIA record # 3 contains a typographical error' { + $wrongAiaRecordReturned = @( + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest2/Certs/.cer' + } + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest/Certs/.cer' + } + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://wrongAiaTest/Certs/.cer' + } + ) + + Mock -CommandName 'Get-CAAuthorityInformationAccess' -MockWith { $wrongAiaRecordReturned } + + It 'Should return $false' { + Test-TargetResource @presentParams | Should -Be $false + } + } + + Context 'When ensure equals present, but not in desired state, and counts do not match, and additional AIA URI record returned' { + $additionalAiaRecordReturned = @( + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest2/Certs/.cer' + } + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest/Certs/.cer' + } + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://setAiaTest3/Certs/.cer' + } + @{ + AddToCertificateOcsp = 'false' + AddToCertificateAia = 'true' + Uri = 'http://rogueAiaTest/Certs/.cer' + } + ) + + Mock -CommandName 'Get-CAAuthorityInformationAccess' -MockWith { $additionalAiaRecordReturned } + + It 'Should return $false' { + Test-TargetResource @presentParams | Should -Be $false + } + } + } + } +} + +finally { + Restore-TestEnvironment -TestEnvironment $TestEnvironment + Remove-Module -Name AdcsStub -Force +}