From 90cfcf4f5f363a3ba907cbab63516af86089c3b7 Mon Sep 17 00:00:00 2001 From: Jens Otto Hatlevold Date: Thu, 24 Sep 2020 09:06:08 +0200 Subject: [PATCH 1/4] Added possibility to specify port number in the Central Administration URL --- CHANGELOG.md | 3 +++ .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 23 ++++++++++++------- .../DSCResources/MSFT_SPFarm/Readme.md | 7 ++++++ 3 files changed, 25 insertions(+), 8 deletions(-) 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..39a9ca748 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.") + } } } } @@ -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..68abad095 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 prot 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 From e24ed1f7d05ca86eae34a0cc23ca56b8c3350526 Mon Sep 17 00:00:00 2001 From: Jens Otto Hatlevold Date: Thu, 24 Sep 2020 13:26:07 +0200 Subject: [PATCH 2/4] Fixed construction of desiredUri to not include port number duplicate --- SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 39a9ca748..f036fa400 100644 --- a/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -567,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) { @@ -981,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) From aa788d6cf73bede2cbe60341c348f38114e50eca Mon Sep 17 00:00:00 2001 From: Jens Otto Hatlevold Date: Thu, 24 Sep 2020 13:26:30 +0200 Subject: [PATCH 3/4] Updated unit tests --- .../SharePointDsc.SPFarm.Tests.ps1 | 118 ++++++++++++++++-- 1 file changed, 110 insertions(+), 8 deletions(-) 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" From 7aca560163708816811a6e298f6064a0f9db03e9 Mon Sep 17 00:00:00 2001 From: Jens Otto Hatlevold Date: Thu, 24 Sep 2020 21:56:56 +0200 Subject: [PATCH 4/4] Fixed typo in readme --- SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md b/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md index 68abad095..f483a9722 100644 --- a/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md +++ b/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md @@ -25,7 +25,7 @@ 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 prot number in CentralAdministrationPort and CentralAdministrationUrl must +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.