diff --git a/CHANGELOG.md b/CHANGELOG.md index 043e53739..f221dcd3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - SharePointDsc - Changed ModuleBuilder module to latest version +- SPFarm + - Added support for specifying port number in the CentralAdministrationUrl parameter. + If CentralAdministrationPort is also specified both port numbers must match. ### Fixed diff --git a/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 2829da699..f036fa400 100644 --- a/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -215,7 +215,7 @@ function Get-TargetResource $ca = Get-SPServiceInstance -Server $env:ComputerName if ($null -ne $ca) { - $ca = $ca | Where-Object -Filterscript { + $ca = $ca | Where-Object -FilterScript { $_.GetType().Name -eq "SPWebServiceInstance" -and $_.Name -eq "WSS_Administration" -and $_.Status -eq "Online" @@ -440,9 +440,14 @@ function Set-TargetResource { throw "CentralAdministrationUrl is not a valid URI. It should include the scheme (http/https) and address." } - if ($CentralAdministrationUrl -match ':\d+') + + if ($PSBoundParameters.ContainsKey("CentralAdministrationPort")) { - throw "CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead." + if ($uri.Port -ne $CentralAdministrationPort) + { + throw ("CentralAdministrationPort does not match port number specified in CentralAdministrationUrl. " + + "Either make the values match or don't specify CentralAdministrationPort.") + } } } } @@ -562,7 +567,7 @@ function Set-TargetResource $isCentralAdminUrlHttps = (([System.Uri]$params.CentralAdministrationUrl).Scheme -eq 'https') - $desiredUri = [System.Uri]("{0}:{1}" -f $params.CentralAdministrationUrl.TrimEnd('/'), $params.CentralAdministrationPort) + $desiredUri = [System.Uri]($params.CentralAdministrationUrl.TrimEnd('/')) $currentUri = [System.Uri]$centralAdminSite.Url if ($desiredUri.AbsoluteUri -ne $currentUri.AbsoluteUri) { @@ -976,7 +981,7 @@ function Set-TargetResource $reprovisionCentralAdmin = $false $isCentralAdminUrlHttps = (([System.Uri]$params.CentralAdministrationUrl).Scheme -eq 'https') - $desiredUri = [System.Uri]("{0}:{1}" -f $params.CentralAdministrationUrl.TrimEnd('/'), $params.CentralAdministrationPort) + $desiredUri = [System.Uri]($params.CentralAdministrationUrl.TrimEnd('/')) $currentUri = [System.Uri]$centralAdminSite.Url if ($isCentralAdminUrlHttps) @@ -1177,12 +1182,14 @@ function Test-TargetResource throw ("CentralAdministrationUrl is not a valid URI. It should " + "include the scheme (http/https) and address.") } - # TODO: should we allow port here as long as either the port matches CentralAdministrationPort - # or CentralAdministrationPort is not specified? - if ($CentralAdministrationUrl -match ':\d+') + + if ($PSBoundParameters.ContainsKey("CentralAdministrationPort")) { - throw ("CentralAdministrationUrl should not specify port. Use " + - "CentralAdministrationPort instead.") + if ($uri.Port -ne $CentralAdministrationPort) + { + throw ("CentralAdministrationPort does not match port number specified in CentralAdministrationUrl. " + + "Either make the values match or don't specify CentralAdministrationPort.") + } } } } diff --git a/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md b/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md index 1ceadb2ea..f483a9722 100644 --- a/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md +++ b/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md @@ -25,6 +25,13 @@ The port of the Central Admin website can be set by using the CentralAdministrationPort property. If this is not defined, the site will be provisioned on port 9999 unless the CentralAdministrationUrl property is specified and begins with https, in which case it will default to port 443. +The port number in CentralAdministrationPort and CentralAdministrationUrl must +match if both parameters are specified. It is not recommended to include port +number 80 and 443 in the CentralAdministrationUrl parameter. This will +automatically follow the URL shceme http (80) and https (443) specified. +CentralAdministrationPort is an optional parameter and can be omitted if the +port is specified in CentralAdministrationUrl, or if default ports for +http/https is used (no port is required to be specified). However, this setting will not impact existing deployments that already have Central Admin provisioned on another port. Also, when a farm is created, the current behavior is to not enroll the server as a cache server (which is the diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 index a25017428..901b32bcb 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 @@ -123,8 +123,8 @@ namespace Microsoft.SharePoint.Administration { } $expectedException = "Cannot validate argument on parameter 'CentralAdministrationPort'. " + - "The 80000 argument is greater than the maximum allowed range of 65535. " + - "Supply an argument that is less than or equal to 65535 and then try the command again." + "The 80000 argument is greater than the maximum allowed range of 65535. " + + "Supply an argument that is less than or equal to 65535 and then try the command again." It 'Should throw parameter validation exception in the get method' { { Get-TargetResource @testParams } | Should Throw $expectedException @@ -162,13 +162,13 @@ namespace Microsoft.SharePoint.Administration { } } - Context -Name "Invalid CA URL has been passed in with port included" -Fixture { + Context -Name "CA URL has been passed in, and the port does not match the one specified in CA Port" -Fixture { $testParams = @{ IsSingleInstance = "Yes" Ensure = "Present" FarmConfigDatabaseName = "SP_Config" - CentralAdministrationPort = 443 - CentralAdministrationUrl = "https://admin.contoso.com:443" + CentralAdministrationPort = 80 + CentralAdministrationUrl = "https://admin.contoso.com" DatabaseServer = "sql.contoso.com" FarmAccount = $mockFarmAccount Passphrase = $mockPassphrase @@ -177,11 +177,13 @@ namespace Microsoft.SharePoint.Administration { } It "Should throw exception in the test method" { - { Test-TargetResource @testParams } | Should Throw "CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead." + { Test-TargetResource @testParams } | Should Throw "CentralAdministrationPort does not match port number specified in CentralAdministrationUrl. " + + "Either make the values match or don't specify CentralAdministrationPort." } It "Should throw exception in the set method" { - { Set-TargetResource @testParams } | Should Throw "CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead." + { Set-TargetResource @testParams } | Should Throw "CentralAdministrationPort does not match port number specified in CentralAdministrationUrl. " + + "Either make the values match or don't specify CentralAdministrationPort." } } @@ -627,7 +629,107 @@ namespace Microsoft.SharePoint.Administration { } } - Context -Name "Server is connected to farm, but CentralAdminPort is different" -Fixture { + Context -Name "Server is connected to farm, but CentralAdminPort is different (specified by CAUrl)" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Ensure = "Present" + FarmConfigDatabaseName = "SP_Config" + DatabaseServer = "sql.contoso.com" + FarmAccount = $mockFarmAccount + Passphrase = $mockPassphrase + AdminContentDatabaseName = "SP_AdminContent" + RunCentralAdmin = $true + CentralAdministrationUrl = "http://localhost:8080" + } + + Mock -CommandName Get-SPDscRegistryKey -MockWith { + return "Connection string example" + } + + Mock -CommandName Get-SPFarm -MockWith { + return @{ + Name = $testParams.FarmConfigDatabaseName + DatabaseServer = @{ + Name = $testParams.DatabaseServer + } + AdminContentDatabaseName = $testParams.AdminContentDatabaseName + Services = @{ + TypeName = "Central Administration" + ApplicationPools = @{ + Name = "SharePoint Central Administration v4" + } + } + } + } + + Mock -CommandName Get-SPDscConfigDBStatus -MockWith { + return @{ + Locked = $false + ValidPermissions = $true + DatabaseExists = $true + } + } + + Mock -CommandName Get-SPDatabase -MockWith { + return @(@{ + Name = $testParams.FarmConfigDatabaseName + Type = "Configuration Database" + NormalizedDataSource = $testParams.DatabaseServer + }) + } + + Mock -CommandName Get-SPWebApplication -MockWith { + return @{ + IsAdministrationWebApplication = $true + ContentDatabases = @(@{ + Name = $testParams.AdminContentDatabaseName + }) + IISSettings = @(@{ + DisableKerberos = $true + }) + Url = "http://localhost:9999" + } + } + + Mock -CommandName Get-CimInstance -MockWith { + return @{ + Domain = "domain.com" + } + } + + Mock -CommandName Get-SPServiceInstance -MockWith { + return @( + @{ + Name = "WSS_Administration" + Status = "Online" + } | Add-Member -MemberType ScriptMethod ` + -Name GetType ` + -Value { + return @{ + Name = "SPWebServiceInstance" + } + } -PassThru -Force + ) + } + + Mock -CommandName Set-SPCentralAdministration -MockWith { } + + It "Should return 9999 as CA Port from the get method" { + (Get-TargetResource @testParams).CentralAdministrationPort | Should Be 9999 + } + + It "Should remove, and re-extend CA web application in the set method" { + Set-TargetResource @testParams + Assert-MockCalled -CommandName "Remove-SPWebApplication" + Assert-MockCalled -CommandName "New-SPWebApplicationExtension" + } + + It "Should return false from the test method" { + Test-TargetResource @testParams | Should be $false + } + } + + Context -Name "Server is connected to farm, but CentralAdminPort is different (specified by CAPort)" -Fixture { $testParams = @{ IsSingleInstance = "Yes" Ensure = "Present"