diff --git a/DSCResources/Helper.psm1 b/DSCResources/Helper.psm1 index 5ea02f31f..220768529 100644 --- a/DSCResources/Helper.psm1 +++ b/DSCResources/Helper.psm1 @@ -165,7 +165,10 @@ function Find-Certificate if ($PSBoundParameters.ContainsKey('Subject')) { - $certFilters += @('($_.Subject -eq $Subject)') + $certFilters += @('(@(Compare-Object ` + -ReferenceObject (($_.Subject -split ", ").trim()|sort-object) ` + -DifferenceObject (($subject -split ",").trim()|sort-object)| ` + Where-Object -Property SideIndicator -eq "=>").Count -eq 0)') } # if if ($PSBoundParameters.ContainsKey('Issuer')) @@ -180,17 +183,26 @@ function Find-Certificate if ($PSBoundParameters.ContainsKey('DNSName')) { - $certFilters += @('(@(Compare-Object -ReferenceObject $_.DNSNameList.Unicode -DifferenceObject $DNSName | Where-Object -Property SideIndicator -eq "=>").Count -eq 0)') + $certFilters += @('(@(Compare-Object ` + -ReferenceObject $_.DNSNameList.Unicode ` + -DifferenceObject $DNSName | ` + Where-Object -Property SideIndicator -eq "=>").Count -eq 0)') } # if if ($PSBoundParameters.ContainsKey('KeyUsage')) { - $certFilters += @('(@(Compare-Object -ReferenceObject ($_.Extensions.KeyUsages -split ", ") -DifferenceObject $KeyUsage | Where-Object -Property SideIndicator -eq "=>").Count -eq 0)') + $certFilters += @('(@(Compare-Object ` + -ReferenceObject ($_.Extensions.KeyUsages -split ", ") ` + -DifferenceObject $KeyUsage | ` + Where-Object -Property SideIndicator -eq "=>").Count -eq 0)') } # if if ($PSBoundParameters.ContainsKey('EnhancedKeyUsage')) { - $certFilters += @('(@(Compare-Object -ReferenceObject ($_.EnhancedKeyUsageList.FriendlyName) -DifferenceObject $EnhancedKeyUsage | Where-Object -Property SideIndicator -eq "=>").Count -eq 0)') + $certFilters += @('(@(Compare-Object ` + -ReferenceObject ($_.EnhancedKeyUsageList.FriendlyName) ` + -DifferenceObject $EnhancedKeyUsage | ` + Where-Object -Property SideIndicator -eq "=>").Count -eq 0)') } # if # Join all the filters together diff --git a/DSCResources/MSFT_xIisLogging/MSFT_xIisLogging.schema.mof b/DSCResources/MSFT_xIisLogging/MSFT_xIisLogging.schema.mof index acc905db0..a6803f21f 100644 --- a/DSCResources/MSFT_xIisLogging/MSFT_xIisLogging.schema.mof +++ b/DSCResources/MSFT_xIisLogging/MSFT_xIisLogging.schema.mof @@ -1,11 +1,3 @@ -[ClassVersion("1.0.0")] -class MSFT_xLogCustomField -{ - [Required, Description("Name for the custom field")] String LogFieldName; - [Required, Description("Name for the source type")] String SourceName; - [Required, Description("Specify the source type"), ValueMap{"RequestHeader","ResponseHeader","ServerVariable"},Values{"RequestHeader","ResponseHeader","ServerVariable"}] String SourceType; -}; - [ClassVersion("1.0.0"), FriendlyName("xIisLogging")] class MSFT_xIisLogging : OMI_BaseResource { @@ -18,3 +10,11 @@ class MSFT_xIisLogging : OMI_BaseResource [Write, Description ("Specifies whether IIS will use Event Tracing or file logging"), ValueMap{"File","ETW","File,ETW"}, Values{"File","ETW","File,ETW"}] String LogTargetW3C; [Write, EmbeddedInstance("MSFT_xLogCustomField"), Description("Custom logging field information in the form of an array of embedded instances of MSFT_xLogCustomField CIM class")] String LogCustomFields[]; }; + +[ClassVersion("1.0.0")] +class MSFT_xLogCustomField +{ + [Required, Description("Name for the custom field")] String LogFieldName; + [Required, Description("Name for the source type")] String SourceName; + [Required, Description("Specify the source type"), ValueMap{"RequestHeader","ResponseHeader","ServerVariable"},Values{"RequestHeader","ResponseHeader","ServerVariable"}] String SourceType; +}; diff --git a/DSCResources/MSFT_xWebApplication/MSFT_xWebApplication.schema.mof b/DSCResources/MSFT_xWebApplication/MSFT_xWebApplication.schema.mof index cbd1dcd76..e933e4039 100644 --- a/DSCResources/MSFT_xWebApplication/MSFT_xWebApplication.schema.mof +++ b/DSCResources/MSFT_xWebApplication/MSFT_xWebApplication.schema.mof @@ -1,12 +1,3 @@ -[ClassVersion("1.0.0")] -class MSFT_xWebApplicationAuthenticationInformation -{ - [Write] Boolean Anonymous; - [Write] Boolean Basic; - [Write] Boolean Digest; - [Write] Boolean Windows; -}; - [ClassVersion("1.0.0.0"), FriendlyName("xWebApplication")] class MSFT_xWebApplication : OMI_BaseResource { @@ -23,3 +14,12 @@ class MSFT_xWebApplication : OMI_BaseResource [Write, Description ("Adds a AutostartProvider ApplicationType")] String ApplicationType; [Write, Description ("Adds EnabledProtocols on an Application"), ValueMap{"http","https","net.tcp","net.msmq","net.pipe"},Values{"http","https","net.tcp","net.msmq","net.pipe"}] String EnabledProtocols[]; }; + +[ClassVersion("1.0.0")] +class MSFT_xWebApplicationAuthenticationInformation +{ + [Write] Boolean Anonymous; + [Write] Boolean Basic; + [Write] Boolean Digest; + [Write] Boolean Windows; +}; diff --git a/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof b/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof index 43175d3a1..3d01c27ff 100644 --- a/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof +++ b/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof @@ -1,3 +1,30 @@ +[ClassVersion("2.0.0"), FriendlyName("xWebsite")] +class MSFT_xWebsite : OMI_BaseResource +{ + [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; + [Key] String Name; + [Write] UInt32 SiteId; + [Write] String PhysicalPath; + [Write,ValueMap{"Started","Stopped"},Values{"Started", "Stopped"}] String State; + [Write] String ApplicationPool; + [Write, EmbeddedInstance("MSFT_xWebBindingInformation"), Description("Website's binding information in the form of an array of embedded instances of the MSFT_xWebBindingInformation CIM class.")] String BindingInfo[]; + [Write] String DefaultPage[]; + [Write] String EnabledProtocols; + [write, EmbeddedInstance("MSFT_xWebAuthenticationInformation"), Description("Hashtable containing authentication information (Anonymous, Basic, Digest, Windows)")] String AuthenticationInfo; + [Write, Description ("Allows the Website to automatically start without a request")] Boolean PreloadEnabled; + [Write, Description ("Enables Autostart on a Website.")] Boolean ServiceAutoStartEnabled; + [Write, Description ("Adds a AutostartProvider")] String ServiceAutoStartProvider; + [Write, Description ("Adds a AutostartProvider ApplicationType")] String ApplicationType; + [Write, Description ("The directory to be used for logfiles")] String LogPath; + [Write, Description ("The W3C logging fields"), ValueMap{"Date","Time","ClientIP","UserName","SiteName","ComputerName","ServerIP","Method","UriStem","UriQuery","HttpStatus","Win32Status","BytesSent","BytesRecv","TimeTaken","ServerPort","UserAgent","Cookie","Referer","ProtocolVersion","Host","HttpSubStatus"},Values{"Date","Time","ClientIP","UserName","SiteName","ComputerName","ServerIP","Method","UriStem","UriQuery","HttpStatus","Win32Status","BytesSent","BytesRecv","TimeTaken","ServerPort","UserAgent","Cookie","Referer","ProtocolVersion","Host","HttpSubStatus"}] String LogFlags[]; + [Write, Description ("How often the log file should rollover"), ValueMap{"Hourly","Daily","Weekly","Monthly","MaxSize"},Values{"Hourly","Daily","Weekly","Monthly","MaxSize"}] String LogPeriod; + [Write, Description ("How large the file should be before it is truncated")] String LogTruncateSize; + [Write, Description ("Use the localtime for file naming and rollover")] Boolean LoglocalTimeRollover; + [Write, Description ("Format of the Logfiles. Only W3C supports LogFlags"), ValueMap{"IIS","W3C","NCSA"}, Values{"IIS","W3C","NCSA"}] String LogFormat; + [Write, Description ("Specifies whether IIS will use Event Tracing or file logging"), ValueMap{"File","ETW","File,ETW"}, Values{"File","ETW","File,ETW"}] String LogTargetW3C; + [Write, EmbeddedInstance("MSFT_xLogCustomFieldInformation"), Description("Custom logging field information in the form of an array of embedded instances of MSFT_xLogCustomFieldInformation CIM class")] String LogCustomFields[]; +}; + [ClassVersion("1.0.0")] class MSFT_xWebBindingInformation { @@ -28,30 +55,3 @@ class MSFT_xLogCustomFieldInformation [Write] String SourceName; [Write, ValueMap{"RequestHeader","ResponseHeader","ServerVariable"},Values{"RequestHeader","ResponseHeader","ServerVariable"}] String SourceType; }; - -[ClassVersion("2.0.0"), FriendlyName("xWebsite")] -class MSFT_xWebsite : OMI_BaseResource -{ - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; - [Key] String Name; - [Write] UInt32 SiteId; - [Write] String PhysicalPath; - [Write,ValueMap{"Started","Stopped"},Values{"Started", "Stopped"}] String State; - [Write] String ApplicationPool; - [Write, EmbeddedInstance("MSFT_xWebBindingInformation"), Description("Website's binding information in the form of an array of embedded instances of the MSFT_xWebBindingInformation CIM class.")] String BindingInfo[]; - [Write] String DefaultPage[]; - [Write] String EnabledProtocols; - [write, EmbeddedInstance("MSFT_xWebAuthenticationInformation"), Description("Hashtable containing authentication information (Anonymous, Basic, Digest, Windows)")] String AuthenticationInfo; - [Write, Description ("Allows the Website to automatically start without a request")] Boolean PreloadEnabled; - [Write, Description ("Enables Autostart on a Website.")] Boolean ServiceAutoStartEnabled; - [Write, Description ("Adds a AutostartProvider")] String ServiceAutoStartProvider; - [Write, Description ("Adds a AutostartProvider ApplicationType")] String ApplicationType; - [Write, Description ("The directory to be used for logfiles")] String LogPath; - [Write, Description ("The W3C logging fields"), ValueMap{"Date","Time","ClientIP","UserName","SiteName","ComputerName","ServerIP","Method","UriStem","UriQuery","HttpStatus","Win32Status","BytesSent","BytesRecv","TimeTaken","ServerPort","UserAgent","Cookie","Referer","ProtocolVersion","Host","HttpSubStatus"},Values{"Date","Time","ClientIP","UserName","SiteName","ComputerName","ServerIP","Method","UriStem","UriQuery","HttpStatus","Win32Status","BytesSent","BytesRecv","TimeTaken","ServerPort","UserAgent","Cookie","Referer","ProtocolVersion","Host","HttpSubStatus"}] String LogFlags[]; - [Write, Description ("How often the log file should rollover"), ValueMap{"Hourly","Daily","Weekly","Monthly","MaxSize"},Values{"Hourly","Daily","Weekly","Monthly","MaxSize"}] String LogPeriod; - [Write, Description ("How large the file should be before it is truncated")] String LogTruncateSize; - [Write, Description ("Use the localtime for file naming and rollover")] Boolean LoglocalTimeRollover; - [Write, Description ("Format of the Logfiles. Only W3C supports LogFlags"), ValueMap{"IIS","W3C","NCSA"}, Values{"IIS","W3C","NCSA"}] String LogFormat; - [Write, Description ("Specifies whether IIS will use Event Tracing or file logging"), ValueMap{"File","ETW","File,ETW"}, Values{"File","ETW","File,ETW"}] String LogTargetW3C; - [Write, EmbeddedInstance("MSFT_xLogCustomFieldInformation"), Description("Custom logging field information in the form of an array of embedded instances of MSFT_xLogCustomFieldInformation CIM class")] String LogCustomFields[]; -}; diff --git a/README.md b/README.md index c88231430..f626102c4 100644 --- a/README.md +++ b/README.md @@ -320,6 +320,13 @@ This resource manages the IIS configuration section locking (overrideMode) to co ### Unreleased +### 2.6.0.0 +* Changed order of classes in schema.mof files to workaround [#423](https://github.com/PowerShell/xWebAdministration/issues/423) +* Fix subject comparison multiple entries for helper function `Find-Certificate` that could not find the test + helper function `Install-NewSelfSignedCertificateExScript`. +* Updated unit test for helper function `Find-Certificate` to check for multiple + subject names in different orders. + ### 2.5.0.0 * Added SiteId to xWebSite to address [396] diff --git a/Tests/Unit/Helper.Tests.ps1 b/Tests/Unit/Helper.Tests.ps1 index b0be37538..47f78fbc8 100644 --- a/Tests/Unit/Helper.Tests.ps1 +++ b/Tests/Unit/Helper.Tests.ps1 @@ -36,6 +36,9 @@ try $certEKUReverse = @('Client authentication','Server Authentication') $certEKUNoMatch = $certEKU + @('Encrypting File System') $certSubject = 'CN=contoso, DC=com' + $certSubjectLong = 'CN=contoso, E=myemail@contoso.com, O=Fabrikam., OU=IT, L=Location, S=State, C=Country' + $certSubjectNoSpace = 'CN=contoso,E=myemail@contoso.com,O=Fabrikam.,OU=IT,L=Location,S=State,C=Country' + $certSubjectLongReverse = 'E=myemail@contoso.com,O=Fabrikam.,L=Location,CN=contoso,OU=IT,S=State,C=Country' $certFriendlyName = 'Contoso Test Cert' $validCert = New-SelfSignedCertificateEx ` -Subject $certSubject ` @@ -51,6 +54,21 @@ try $validCert = Get-Item -Path "cert:\CurrentUser\My\$validThumbprint" Remove-Item -Path $validCert.PSPath -Force + # Generate the long subject certificate for testing but remove it from the store straight away + $validCertSubjectLong = New-SelfSignedCertificateEx ` + -Subject $certSubjectLong ` + -KeyUsage $certKeyUsage ` + -KeySpec 'Exchange' ` + -EKU $certEKU ` + -SubjectAlternativeName $certDNSNames ` + -FriendlyName $certFriendlyName ` + -StoreLocation 'CurrentUser' ` + -Exportable + # Pull the generated certificate from the store so we have the friendlyname + $longThumbprint = $validCertSubjectLong.Thumbprint + $validCertSubjectLong = Get-Item -Path "cert:\CurrentUser\My\$longThumbprint" + Remove-Item -Path $validCertSubjectLong.PSPath -Force + # Generate the Expired certificate for testing but remove it from the store straight away $expiredCert = New-SelfSignedCertificateEx ` -Subject $certSubject ` @@ -94,6 +112,11 @@ try return @( $expiredCert ) } + 'cert:\LocalMachine\LongSubject' + { + return @( $validCertSubjectLong ) + } + default { throw 'mock called with unexpected value {0}' -f $Path @@ -201,6 +224,36 @@ try } } + Context 'Subject only is passed and certificate with a different subject order exists' { + It 'should not throw exception' { + { $script:result = Find-Certificate -Subject $certSubjectLongReverse -Store 'LongSubject' } | Should Not Throw + } + + It 'should return expected certificate' { + $script:result.Thumbprint | Should Be $longThumbprint + } + + It 'should call expected mocks' { + Assert-MockCalled -CommandName Test-Path -Exactly -Times 1 + Assert-MockCalled -CommandName Get-ChildItem -Exactly -Times 1 + } + } + + Context 'Subject only is passed and certificate subject without spaces exists' { + It 'should not throw exception' { + { $script:result = Find-Certificate -Subject $certSubjectNoSpace -Store 'LongSubject' } | Should Not Throw + } + + It 'should return expected certificate' { + $script:result.Thumbprint | Should Be $longThumbprint + } + + It 'should call expected mocks' { + Assert-MockCalled -CommandName Test-Path -Exactly -Times 1 + Assert-MockCalled -CommandName Get-ChildItem -Exactly -Times 1 + } + } + Context 'Issuer only is passed and matching certificate exists' { It 'should not throw exception' { { $script:result = Find-Certificate -Issuer $certSubject } | Should Not Throw diff --git a/xWebAdministration.psd1 b/xWebAdministration.psd1 index ca9504260..70b15d047 100644 --- a/xWebAdministration.psd1 +++ b/xWebAdministration.psd1 @@ -1,6 +1,6 @@ @{ # Version number of this module. -moduleVersion = '2.5.0.0' +moduleVersion = '2.6.0.0' # ID used to uniquely identify this module GUID = 'b3239f27-d7d3-4ae6-a5d2-d9a1c97d6ae4' @@ -12,7 +12,7 @@ Author = 'Microsoft Corporation' CompanyName = 'Microsoft Corporation' # Copyright statement for this module -Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.' +Copyright = '(c) 2019 Microsoft Corporation. All rights reserved.' # Description of the functionality provided by this module Description = 'Module with DSC Resources for Web Administration' @@ -41,10 +41,11 @@ PrivateData = @{ # IconUri = '' # ReleaseNotes of this module - ReleaseNotes = '* Added SiteId to xWebSite to address [396] -* xWebSite: Full path is used to get list of default documents -* xIISLogging: Added support for LogTargetW3C -* xWebsite: Added support for LogTargetW3C + ReleaseNotes = '* Changed order of classes in schema.mof files to workaround [423](https://github.com/PowerShell/xWebAdministration/issues/423) +* Fix subject comparison multiple entries for helper function `Find-Certificate` that could not find the test + helper function `Install-NewSelfSignedCertificateExScript`. +* Updated unit test for helper function `Find-Certificate` to check for multiple + subject names in different orders. ' @@ -75,3 +76,4 @@ CmdletsToExport = '*' +