From d6b2cbd0ae19f39c60053bcb0391dba61cd0366b Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 14:12:03 -0500 Subject: [PATCH 01/53] Reprovision CA if binding isn't created correctly --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 467 +++++++++++------- 1 file changed, 296 insertions(+), 171 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index bc963caf0..1814e7a68 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -10,7 +10,7 @@ function Get-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present","Absent")] + [ValidateSet("Present", "Absent")] [System.String] $Ensure = "Present", @@ -38,30 +38,39 @@ function Get-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [switch] + $CentralAdministrationIsSsl, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $CentralAdministrationSslHostHeader, + [Parameter()] [System.UInt32] $CentralAdministrationPort, [Parameter()] [System.String] - [ValidateSet("NTLM","Kerberos")] + [ValidateSet("NTLM", "Kerberos")] $CentralAdministrationAuth, [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] - [ValidateSet("Off","On","OnDemand")] + [ValidateSet("Off", "On", "OnDemand")] [System.String] $DeveloperDashboard, @@ -78,34 +87,36 @@ function Get-TargetResource if ($CentralAdministrationPort -notin 1..65535) { throw ("An invalid value for CentralAdministrationPort is specified: " + ` - "$CentralAdministrationPort") + "$CentralAdministrationPort") } } if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 { + 15 + { Write-Verbose -Message "Detected installation of SharePoint 2013" } - 16 { + 16 + { if ($DeveloperDashboard -eq "OnDemand") { throw ("The DeveloperDashboard value 'OnDemand' is not allowed in SharePoint " + ` - "2016 and 2019") + "2016 and 2019") } if ($DeveloperDashboard -eq "On") { Write-Verbose -Message ("Please make sure you also provision the Usage and Health " + ` - "service application to make sure the Developer Dashboard " + ` - "works properly") + "service application to make sure the Developer Dashboard " + ` + "works properly") } if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) @@ -117,42 +128,43 @@ function Get-TargetResource Write-Verbose -Message "Detected installation of SharePoint 2019" } } - default { + default + { throw ("Detected an unsupported major version of SharePoint. SharePointDsc only " + ` - "supports SharePoint 2013, 2016 or 2019.") + "supports SharePoint 2013, 2016 or 2019.") } } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -ne 16) + -and $installedVersion.FileMajorPart -ne 16) { throw [Exception] "Server role is only supported in SharePoint 2016 and 2019." } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -eq 16 ` - -and $installedVersion.FileBuildPart -lt 4456 ` - -and ($ServerRole -eq "ApplicationWithSearch" ` - -or $ServerRole -eq "WebFrontEndWithDistributedCache")) + -and $installedVersion.FileMajorPart -eq 16 ` + -and $installedVersion.FileBuildPart -lt 4456 ` + -and ($ServerRole -eq "ApplicationWithSearch" ` + -or $ServerRole -eq "WebFrontEndWithDistributedCache")) { throw [Exception] ("ServerRole values of 'ApplicationWithSearch' or " + ` - "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` - "Feature Pack 1 to be installed. See " + ` - "https://support.microsoft.com/en-us/kb/3127940") + "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` + "Feature Pack 1 to be installed. See " + ` + "https://support.microsoft.com/en-us/kb/3127940") } # Determine if a connection to a farm already exists $majorVersion = $installedVersion.FileMajorPart - $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" - $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue + $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" + $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue if ($null -ne $dsnValue) { # This node has already been connected to a farm $result = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] try @@ -174,9 +186,23 @@ function Get-TargetResource $_.Name -eq $spFarm.Name -and $_.Type -eq "Configuration Database" } $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { + | Where-Object -FilterScript { $_.IsAdministrationWebApplication -eq $true } + $centralAdminIsSsl = ($null -ne $centralAdminSite -and ` + (New-Object -TypeName System.Uri $centralAdminSite.Url).Scheme -eq "https") + + # if central admin is SSL, there should be an entry in the SecureBindings + # object of the SPWebApplication's IisSettings for the default zone + $centralAdminSslHostHeader = $null + if ($centralAdminIsSsl) + { + $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings + if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + { + $centralAdminSslHostHeader = $secureBindings[0].HostHeader + } + } if ($params.FarmAccount.UserName -eq $spFarm.DefaultServiceAccount.Name) { @@ -187,20 +213,15 @@ function Get-TargetResource $farmAccount = $spFarm.DefaultServiceAccount.Name } - $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } - $centralAdminProvisioned = $false $ca = Get-SPServiceInstance -Server $env:ComputerName if ($null -ne $ca) { $ca = $ca | Where-Object -Filterscript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" -and ` - $_.Status -eq "Online" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" -and ` + $_.Status -eq "Online" + } } if ($null -ne $ca) @@ -217,21 +238,23 @@ function Get-TargetResource $centralAdminAuth = "NTLM" } - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings - $developerDashboardStatus = $developerDashboardSettings.DisplayLevel + $developerDashboardStatus = $developerDashboardSettings.DisplayLevel $returnValue = @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $spFarm.Name - DatabaseServer = $configDb.NormalizedDataSource - FarmAccount = $farmAccount # Need to return this as a credential to match the type expected - Passphrase = $null - AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name - RunCentralAdmin = $centralAdminProvisioned - CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port - CentralAdministrationAuth = $centralAdminAuth - DeveloperDashboard = $developerDashboardStatus + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $spFarm.Name + DatabaseServer = $configDb.NormalizedDataSource + FarmAccount = $farmAccount # Need to return this as a credential to match the type expected + Passphrase = $null + AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name + RunCentralAdmin = $centralAdminProvisioned + CentralAdministrationIsSsl = $centralAdminIsSsl + CentralAdministrationSslHostHeader = $centralAdminSslHostHeader + CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port + CentralAdministrationAuth = $centralAdminAuth + DeveloperDashboard = $developerDashboardStatus } $installedVersion = Get-SPDSCInstalledProductVersion if ($installedVersion.FileMajorPart -eq 16) @@ -261,21 +284,23 @@ function Get-TargetResource # The node is currently connected to a farm but was unable to retrieve the values # of current farm settings, most likely due to connectivity issues with the SQL box Write-Verbose -Message ("This server appears to be connected to a farm already, " + ` - "but the configuration database is currently unable to be " + ` - "accessed. Values returned from the get method will be " + ` - "incomplete, however the 'Ensure' property should be " + ` - "considered correct") + "but the configuration database is currently unable to be " + ` + "accessed. Values returned from the get method will be " + ` + "incomplete, however the 'Ensure' property should be " + ` + "considered correct") return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Present" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationIsSsl = $null + CentralAdministrationSslHostHeader = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Present" } } else @@ -288,16 +313,18 @@ function Get-TargetResource { # This node has never been connected to a farm, return the null return object return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Absent" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationIsSsl = $null + CentralAdministrationSslHostHeader = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Absent" } } } @@ -315,7 +342,7 @@ function Set-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present","Absent")] + [ValidateSet("Present", "Absent")] [System.String] $Ensure = "Present", @@ -343,30 +370,39 @@ function Set-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [switch] + $CentralAdministrationIsSsl, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $CentralAdministrationSslHostHeader, + [Parameter()] [System.UInt32] $CentralAdministrationPort, [Parameter()] [System.String] - [ValidateSet("NTLM","Kerberos")] + [ValidateSet("NTLM", "Kerberos")] $CentralAdministrationAuth, [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] - [ValidateSet("Off","On","OnDemand")] + [ValidateSet("Off", "On", "OnDemand")] [System.String] $DeveloperDashboard, @@ -381,7 +417,7 @@ function Set-TargetResource if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $CurrentValues = Get-TargetResource @PSBoundParameters @@ -389,7 +425,22 @@ function Set-TargetResource # Set default values to ensure they are passed to Invoke-SPDSCCommand if (-not $PSBoundParameters.ContainsKey("CentralAdministrationPort")) { - $PSBoundParameters.Add("CentralAdministrationPort", 9999) + # If SSL and host header specified, let's default to port 443 and assume SNI will be used + if ($CentralAdministrationIsSsl -and ` + (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))) + { + $PSBoundParameters.Add("CentralAdministrationPort", 443) + } + else + { + $PSBoundParameters.Add("CentralAdministrationPort", 9999) + } + } + + # if we're not passing Ssl Host Header in, let's set it to $null for comparison to Current Values + if (-not $PSBoundParameters.ContainsKey("CentralAdministrationSslHostHeader")) + { + $CentralAdministrationSslHostHeader = $null } if (-not $PSBoundParameters.ContainsKey("CentralAdministrationAuth")) @@ -404,8 +455,8 @@ function Set-TargetResource if ($CurrentValues.RunCentralAdmin -ne $RunCentralAdmin) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] # Provision central administration @@ -416,16 +467,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" - $serviceInstance = Get-SPServiceInstance -Server $fqdn ` + $fqdn = "$($env:COMPUTERNAME).$domain" + $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -441,16 +492,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" + $fqdn = "$($env:COMPUTERNAME).$domain" $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -461,11 +512,45 @@ function Set-TargetResource } } } - if ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) + # For the following SSL scenarios, we should remove the CA web application and recreate it + # CentralAdministrationIsSsl = $true + # AND Current CentralAdministrationIsSsl is $false + # OR Current SSL HostHeader -ne desired SSL HostHeader (and desired host header is not null or empty) + # OR Current SecureBindings does not exist or doesn't match desired port + # The last condition might not be applicable if we rely on host header to be specified for SSL bindings + if ($CentralAdministrationIsSsl -and ` + ((-not $CurrentValues.CentralAdministrationIsSsl) -or ` + ($CurrentValues.CentralAdministrationSslHostHeader -ne $CentralAdministrationSslHostHeader -and ` + (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))))) + { + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + $centralAdmin = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { + $_.IsAdministrationWebApplication + } + Remove-SPWebApplication -Identity $centralAdmin.Url -Zone Default -DeleteIisSite + + Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" + $webAppParams = @{ + Identity = "https://$($params.CentralAdministrationSslHostHeader)" + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = $params.CentralAdministrationSslHostHeader + Port = $params.CentralAdministrationPort + SecureSocketsLayer = $true + } + New-SPWebApplication @webAppParams + } + } + elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Central Admin port" @@ -476,12 +561,12 @@ function Set-TargetResource if ($CurrentValues.DeveloperDashboard -ne $DeveloperDashboard) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -495,9 +580,9 @@ function Set-TargetResource Write-Verbose -Message "Server not part of farm, creating or joining farm" $actionResult = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments @($PSBoundParameters, $PSScriptRoot) ` - -ScriptBlock { - $params = $args[0] + -Arguments @($PSBoundParameters, $PSScriptRoot) ` + -ScriptBlock { + $params = $args[0] $scriptRoot = $args[1] $modulePath = "..\..\Modules\SharePointDsc.Farm\SPFarm.psm1" @@ -511,16 +596,16 @@ function Set-TargetResource } $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName while ($dbStatus.Locked -eq $true) { Write-Verbose -Message ("[$([DateTime]::Now.ToShortTimeString())] The configuration " + ` - "database is currently being provisioned by a remote " + ` - "server, this server will wait for this to complete") + "database is currently being provisioned by a remote " + ` + "server, this server will wait for this to complete") Start-Sleep -Seconds 30 $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } if ($dbStatus.ValidPermissions -eq $false) @@ -538,21 +623,23 @@ function Set-TargetResource $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 { + 15 + { Write-Verbose -Message "Detected Version: SharePoint 2013" } - 16 { + 16 + { if ($params.ContainsKey("ServerRole") -eq $true) { if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } $executeArgs.Add("LocalServerRole", $params.ServerRole) } @@ -561,30 +648,31 @@ function Set-TargetResource if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } $executeArgs.Add("ServerRoleOptional", $true) } } - Default { + Default + { throw [Exception] ("An unknown version of SharePoint (Major version $_) " + ` - "was detected. Only versions 15 (SharePoint 2013) and" + ` - "16 (SharePoint 2016 or SharePoint 2019) are supported.") + "was detected. Only versions 15 (SharePoint 2013) and" + ` + "16 (SharePoint 2016 or SharePoint 2019) are supported.") } } if ($dbStatus.DatabaseExists -eq $true) { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' already exists, so " + ` - "this server will join the farm.") + "'$($params.FarmConfigDatabaseName)' already exists, so " + ` + "this server will join the farm.") $createFarm = $false } elseif ($dbStatus.DatabaseExists -eq $false -and $params.RunCentralAdmin -eq $false) @@ -592,17 +680,17 @@ function Set-TargetResource # Only allow the farm to be created by a server that will run central admin # to avoid a ghost CA site appearing on this server and causing issues Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` - "this server will not be running the central admin " + ` - "website, so it will wait to join the farm rather than " + ` - "create one.") + "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` + "this server will not be running the central admin " + ` + "website, so it will wait to join the farm rather than " + ` + "create one.") $createFarm = $false } else { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` - "this server will create the farm.") + "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` + "this server will create the farm.") $createFarm = $true } @@ -619,10 +707,10 @@ function Set-TargetResource } Write-Verbose -Message ("The server will attempt to join the farm now once every " + ` - "60 seconds for the next 15 minutes.") - $loopCount = 0 + "60 seconds for the next 15 minutes.") + $loopCount = 0 $connectedToFarm = $false - $lastException = $null + $lastException = $null while ($connectedToFarm -eq $false -and $loopCount -lt 15) { try @@ -634,11 +722,11 @@ function Set-TargetResource { $lastException = $_.Exception Write-Verbose -Message ("$([DateTime]::Now.ToShortTimeString()) - An error " + ` - "occured joining config database " + ` - "'$($params.FarmConfigDatabaseName)' on " + ` - "'$($params.DatabaseServer)'. This resource will " + ` - "wait and retry automatically for up to 15 minutes. " + ` - "(waited $loopCount of 15 minutes)") + "occured joining config database " + ` + "'$($params.FarmConfigDatabaseName)' on " + ` + "'$($params.DatabaseServer)'. This resource will " + ` + "wait and retry automatically for up to 15 minutes. " + ` + "(waited $loopCount of 15 minutes)") $loopCount++ Start-Sleep -Seconds 60 } @@ -656,14 +744,14 @@ function Set-TargetResource Write-Verbose -Message "The database does not exist, so create a new farm" Write-Verbose -Message ("Creating Lock database to prevent two servers creating " + ` - "the same farm") + "the same farm") Add-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName try { $executeArgs += @{ - FarmCredentials = $params.FarmAccount + FarmCredentials = $params.FarmAccount AdministrationContentDatabaseName = $params.AdminContentDatabaseName } @@ -676,7 +764,7 @@ function Set-TargetResource { Write-Verbose -Message "Removing Lock database" Remove-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } } @@ -698,10 +786,9 @@ function Set-TargetResource { Write-Verbose -Message "RunCentralAdmin is True, provisioning Central Admin" $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } - + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } $centralAdminProvisioned = $false if ((New-Object -TypeName System.Uri $centralAdminSite.Url).Port -eq $params.CentralAdministrationPort) @@ -712,7 +799,34 @@ function Set-TargetResource if ($centralAdminProvisioned -eq $false) { New-SPCentralAdministration -Port $params.CentralAdministrationPort ` - -WindowsAuthProvider $params.CentralAdministrationAuth + -WindowsAuthProvider $params.CentralAdministrationAuth + + # if central admin is to be SSL and has a host name specified, let's remove and re-provision + if ($params.CentralAdministrationIsSsl -and ` + -not [string]::IsNullOrEmpty($params.CentralAdministrationSslHostHeader)) + { + Write-Verbose -Message "Removing Central Admin to properly provision as SSL" + + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } + + Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite + + Write-Verbose -Message "Reprovisioning Central Admin with SSL" + + $webAppParams = @{ + Identity = "https://$($params.CentralAdministrationSslHostHeader)" + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = $params.CentralAdministrationSslHostHeader + Port = $params.CentralAdministrationPort + SecureSocketsLayer = $true + } + + New-SPWebApplicationExtension @webAppParams + } } else { @@ -728,7 +842,7 @@ function Set-TargetResource { $serviceInstance = $serviceInstance | Where-Object -FilterScript { $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" + $_.Name -eq "WSS_Administration" } } @@ -746,7 +860,7 @@ function Set-TargetResource if ($params.DeveloperDashboard -ne "Off") { Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -761,10 +875,10 @@ function Set-TargetResource Start-Service -Name sptimerv4 Write-Verbose -Message ("Pausing for 5 minutes to allow the timer service to " + ` - "fully provision the server") + "fully provision the server") Start-Sleep -Seconds 300 Write-Verbose -Message ("Join farm complete. Restarting computer to allow " + ` - "configuration to continue") + "configuration to continue") $global:DSCMachineStatus = 1 } @@ -783,7 +897,7 @@ function Test-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present","Absent")] + [ValidateSet("Present", "Absent")] [System.String] $Ensure = "Present", @@ -811,30 +925,39 @@ function Test-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [switch] + $CentralAdministrationIsSsl, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $CentralAdministrationSslHostHeader, + [Parameter()] [System.UInt32] $CentralAdministrationPort, [Parameter()] [System.String] - [ValidateSet("NTLM","Kerberos")] + [ValidateSet("NTLM", "Kerberos")] $CentralAdministrationAuth, [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] - [ValidateSet("Off","On","OnDemand")] + [ValidateSet("Off", "On", "OnDemand")] [System.String] $DeveloperDashboard, @@ -851,11 +974,13 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters return Test-SPDscParameterState -CurrentValues $CurrentValues ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck @("Ensure", - "RunCentralAdmin", - "CentralAdministrationPort", - "DeveloperDashboard") + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("Ensure", + "RunCentralAdmin", + "CentralAdministrationIsSsl", + "CentralAdministrationSslHostHeader", + "CentralAdministrationPort", + "DeveloperDashboard") } Export-ModuleMember -Function *-TargetResource From ccf992603256634697503608e233c5e4fe038554 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 21:21:45 -0500 Subject: [PATCH 02/53] restore most formatting, change argument for CA SSL, more changes coming --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 251 +++++++++--------- 1 file changed, 119 insertions(+), 132 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 1814e7a68..950a39f83 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -38,14 +38,10 @@ function Get-TargetResource [System.Boolean] $RunCentralAdmin, - [Parameter()] - [switch] - $CentralAdministrationIsSsl, - [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $CentralAdministrationSslHostHeader, + $CentralAdministrationUrl, [Parameter()] [System.UInt32] @@ -59,14 +55,14 @@ function Get-TargetResource [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] @@ -87,14 +83,14 @@ function Get-TargetResource if ($CentralAdministrationPort -notin 1..65535) { throw ("An invalid value for CentralAdministrationPort is specified: " + ` - "$CentralAdministrationPort") + "$CentralAdministrationPort") } } if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $installedVersion = Get-SPDSCInstalledProductVersion @@ -109,7 +105,7 @@ function Get-TargetResource if ($DeveloperDashboard -eq "OnDemand") { throw ("The DeveloperDashboard value 'OnDemand' is not allowed in SharePoint " + ` - "2016 and 2019") + "2016 and 2019") } if ($DeveloperDashboard -eq "On") @@ -131,40 +127,40 @@ function Get-TargetResource default { throw ("Detected an unsupported major version of SharePoint. SharePointDsc only " + ` - "supports SharePoint 2013, 2016 or 2019.") + "supports SharePoint 2013, 2016 or 2019.") } } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -ne 16) + -and $installedVersion.FileMajorPart -ne 16) { throw [Exception] "Server role is only supported in SharePoint 2016 and 2019." } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -eq 16 ` - -and $installedVersion.FileBuildPart -lt 4456 ` - -and ($ServerRole -eq "ApplicationWithSearch" ` - -or $ServerRole -eq "WebFrontEndWithDistributedCache")) + -and $installedVersion.FileMajorPart -eq 16 ` + -and $installedVersion.FileBuildPart -lt 4456 ` + -and ($ServerRole -eq "ApplicationWithSearch" ` + -or $ServerRole -eq "WebFrontEndWithDistributedCache")) { throw [Exception] ("ServerRole values of 'ApplicationWithSearch' or " + ` - "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` - "Feature Pack 1 to be installed. See " + ` - "https://support.microsoft.com/en-us/kb/3127940") + "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` + "Feature Pack 1 to be installed. See " + ` + "https://support.microsoft.com/en-us/kb/3127940") } # Determine if a connection to a farm already exists $majorVersion = $installedVersion.FileMajorPart - $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" - $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue + $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" + $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue if ($null -ne $dsnValue) { # This node has already been connected to a farm $result = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] try @@ -186,7 +182,7 @@ function Get-TargetResource $_.Name -eq $spFarm.Name -and $_.Type -eq "Configuration Database" } $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { + | Where-Object -FilterScript { $_.IsAdministrationWebApplication -eq $true } $centralAdminIsSsl = ($null -ne $centralAdminSite -and ` @@ -218,10 +214,10 @@ function Get-TargetResource if ($null -ne $ca) { $ca = $ca | Where-Object -Filterscript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" -and ` - $_.Status -eq "Online" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" -and ` + $_.Status -eq "Online" + } } if ($null -ne $ca) @@ -238,9 +234,9 @@ function Get-TargetResource $centralAdminAuth = "NTLM" } - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings - $developerDashboardStatus = $developerDashboardSettings.DisplayLevel + $developerDashboardStatus = $developerDashboardSettings.DisplayLevel $returnValue = @{ IsSingleInstance = "Yes" @@ -284,10 +280,10 @@ function Get-TargetResource # The node is currently connected to a farm but was unable to retrieve the values # of current farm settings, most likely due to connectivity issues with the SQL box Write-Verbose -Message ("This server appears to be connected to a farm already, " + ` - "but the configuration database is currently unable to be " + ` - "accessed. Values returned from the get method will be " + ` - "incomplete, however the 'Ensure' property should be " + ` - "considered correct") + "but the configuration database is currently unable to be " + ` + "accessed. Values returned from the get method will be " + ` + "incomplete, however the 'Ensure' property should be " + ` + "considered correct") return @{ IsSingleInstance = "Yes" FarmConfigDatabaseName = $null @@ -370,14 +366,10 @@ function Set-TargetResource [System.Boolean] $RunCentralAdmin, - [Parameter()] - [switch] - $CentralAdministrationIsSsl, - [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $CentralAdministrationSslHostHeader, + $CentralAdministrationUrl, [Parameter()] [System.UInt32] @@ -391,14 +383,14 @@ function Set-TargetResource [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] @@ -417,7 +409,7 @@ function Set-TargetResource if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $CurrentValues = Get-TargetResource @PSBoundParameters @@ -455,8 +447,8 @@ function Set-TargetResource if ($CurrentValues.RunCentralAdmin -ne $RunCentralAdmin) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] # Provision central administration @@ -467,16 +459,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" + $fqdn = "$($env:COMPUTERNAME).$domain" $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -492,16 +484,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" + $fqdn = "$($env:COMPUTERNAME).$domain" $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -549,8 +541,8 @@ function Set-TargetResource elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Central Admin port" @@ -561,12 +553,12 @@ function Set-TargetResource if ($CurrentValues.DeveloperDashboard -ne $DeveloperDashboard) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -580,9 +572,9 @@ function Set-TargetResource Write-Verbose -Message "Server not part of farm, creating or joining farm" $actionResult = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments @($PSBoundParameters, $PSScriptRoot) ` - -ScriptBlock { - $params = $args[0] + -Arguments @($PSBoundParameters, $PSScriptRoot) ` + -ScriptBlock { + $params = $args[0] $scriptRoot = $args[1] $modulePath = "..\..\Modules\SharePointDsc.Farm\SPFarm.psm1" @@ -596,16 +588,16 @@ function Set-TargetResource } $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName while ($dbStatus.Locked -eq $true) { Write-Verbose -Message ("[$([DateTime]::Now.ToShortTimeString())] The configuration " + ` - "database is currently being provisioned by a remote " + ` - "server, this server will wait for this to complete") + "database is currently being provisioned by a remote " + ` + "server, this server will wait for this to complete") Start-Sleep -Seconds 30 $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } if ($dbStatus.ValidPermissions -eq $false) @@ -634,12 +626,12 @@ function Set-TargetResource if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } $executeArgs.Add("LocalServerRole", $params.ServerRole) } @@ -648,14 +640,14 @@ function Set-TargetResource if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } $executeArgs.Add("ServerRoleOptional", $true) } @@ -663,16 +655,16 @@ function Set-TargetResource Default { throw [Exception] ("An unknown version of SharePoint (Major version $_) " + ` - "was detected. Only versions 15 (SharePoint 2013) and" + ` - "16 (SharePoint 2016 or SharePoint 2019) are supported.") + "was detected. Only versions 15 (SharePoint 2013) and" + ` + "16 (SharePoint 2016 or SharePoint 2019) are supported.") } } if ($dbStatus.DatabaseExists -eq $true) { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' already exists, so " + ` - "this server will join the farm.") + "'$($params.FarmConfigDatabaseName)' already exists, so " + ` + "this server will join the farm.") $createFarm = $false } elseif ($dbStatus.DatabaseExists -eq $false -and $params.RunCentralAdmin -eq $false) @@ -680,17 +672,17 @@ function Set-TargetResource # Only allow the farm to be created by a server that will run central admin # to avoid a ghost CA site appearing on this server and causing issues Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` - "this server will not be running the central admin " + ` - "website, so it will wait to join the farm rather than " + ` - "create one.") + "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` + "this server will not be running the central admin " + ` + "website, so it will wait to join the farm rather than " + ` + "create one.") $createFarm = $false } else { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` - "this server will create the farm.") + "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` + "this server will create the farm.") $createFarm = $true } @@ -707,10 +699,10 @@ function Set-TargetResource } Write-Verbose -Message ("The server will attempt to join the farm now once every " + ` - "60 seconds for the next 15 minutes.") - $loopCount = 0 + "60 seconds for the next 15 minutes.") + $loopCount = 0 $connectedToFarm = $false - $lastException = $null + $lastException = $null while ($connectedToFarm -eq $false -and $loopCount -lt 15) { try @@ -722,11 +714,11 @@ function Set-TargetResource { $lastException = $_.Exception Write-Verbose -Message ("$([DateTime]::Now.ToShortTimeString()) - An error " + ` - "occured joining config database " + ` - "'$($params.FarmConfigDatabaseName)' on " + ` - "'$($params.DatabaseServer)'. This resource will " + ` - "wait and retry automatically for up to 15 minutes. " + ` - "(waited $loopCount of 15 minutes)") + "occured joining config database " + ` + "'$($params.FarmConfigDatabaseName)' on " + ` + "'$($params.DatabaseServer)'. This resource will " + ` + "wait and retry automatically for up to 15 minutes. " + ` + "(waited $loopCount of 15 minutes)") $loopCount++ Start-Sleep -Seconds 60 } @@ -744,14 +736,14 @@ function Set-TargetResource Write-Verbose -Message "The database does not exist, so create a new farm" Write-Verbose -Message ("Creating Lock database to prevent two servers creating " + ` - "the same farm") + "the same farm") Add-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName try { $executeArgs += @{ - FarmCredentials = $params.FarmAccount + FarmCredentials = $params.FarmAccount AdministrationContentDatabaseName = $params.AdminContentDatabaseName } @@ -764,7 +756,7 @@ function Set-TargetResource { Write-Verbose -Message "Removing Lock database" Remove-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } } @@ -786,9 +778,9 @@ function Set-TargetResource { Write-Verbose -Message "RunCentralAdmin is True, provisioning Central Admin" $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } $centralAdminProvisioned = $false if ((New-Object -TypeName System.Uri $centralAdminSite.Url).Port -eq $params.CentralAdministrationPort) @@ -799,7 +791,7 @@ function Set-TargetResource if ($centralAdminProvisioned -eq $false) { New-SPCentralAdministration -Port $params.CentralAdministrationPort ` - -WindowsAuthProvider $params.CentralAdministrationAuth + -WindowsAuthProvider $params.CentralAdministrationAuth # if central admin is to be SSL and has a host name specified, let's remove and re-provision if ($params.CentralAdministrationIsSsl -and ` @@ -842,7 +834,7 @@ function Set-TargetResource { $serviceInstance = $serviceInstance | Where-Object -FilterScript { $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" + $_.Name -eq "WSS_Administration" } } @@ -860,7 +852,7 @@ function Set-TargetResource if ($params.DeveloperDashboard -ne "Off") { Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -875,10 +867,10 @@ function Set-TargetResource Start-Service -Name sptimerv4 Write-Verbose -Message ("Pausing for 5 minutes to allow the timer service to " + ` - "fully provision the server") + "fully provision the server") Start-Sleep -Seconds 300 Write-Verbose -Message ("Join farm complete. Restarting computer to allow " + ` - "configuration to continue") + "configuration to continue") $global:DSCMachineStatus = 1 } @@ -925,14 +917,10 @@ function Test-TargetResource [System.Boolean] $RunCentralAdmin, - [Parameter()] - [switch] - $CentralAdministrationIsSsl, - [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $CentralAdministrationSslHostHeader, + $CentralAdministrationUrl, [Parameter()] [System.UInt32] @@ -946,14 +934,14 @@ function Test-TargetResource [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] @@ -974,13 +962,12 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters return Test-SPDscParameterState -CurrentValues $CurrentValues ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck @("Ensure", - "RunCentralAdmin", - "CentralAdministrationIsSsl", - "CentralAdministrationSslHostHeader", - "CentralAdministrationPort", - "DeveloperDashboard") + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("Ensure", + "RunCentralAdmin", + "CentralAdministrationUrl", + "CentralAdministrationPort", + "DeveloperDashboard") } Export-ModuleMember -Function *-TargetResource From 022159b291ed994361394c79bdc8d9aec31c8bfa Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 21:23:38 -0500 Subject: [PATCH 03/53] restore additional formatting --- .../SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 950a39f83..180db06be 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -111,8 +111,8 @@ function Get-TargetResource if ($DeveloperDashboard -eq "On") { Write-Verbose -Message ("Please make sure you also provision the Usage and Health " + ` - "service application to make sure the Developer Dashboard " + ` - "works properly") + "service application to make sure the Developer Dashboard " + ` + "works properly") } if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) From 8b4c375691cb94d773ebc88f03660b012751bd20 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 21:28:43 -0500 Subject: [PATCH 04/53] final formatting restoration --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 180db06be..d7679027f 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -10,7 +10,7 @@ function Get-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present", "Absent")] + [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", @@ -49,7 +49,7 @@ function Get-TargetResource [Parameter()] [System.String] - [ValidateSet("NTLM", "Kerberos")] + [ValidateSet("NTLM","Kerberos")] $CentralAdministrationAuth, [Parameter()] @@ -66,7 +66,7 @@ function Get-TargetResource $ServerRole, [Parameter()] - [ValidateSet("Off", "On", "OnDemand")] + [ValidateSet("Off","On","OnDemand")] [System.String] $DeveloperDashboard, @@ -96,12 +96,10 @@ function Get-TargetResource $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 - { + 15 { Write-Verbose -Message "Detected installation of SharePoint 2013" } - 16 - { + 16 { if ($DeveloperDashboard -eq "OnDemand") { throw ("The DeveloperDashboard value 'OnDemand' is not allowed in SharePoint " + ` @@ -124,8 +122,7 @@ function Get-TargetResource Write-Verbose -Message "Detected installation of SharePoint 2019" } } - default - { + default { throw ("Detected an unsupported major version of SharePoint. SharePointDsc only " + ` "supports SharePoint 2013, 2016 or 2019.") } @@ -338,7 +335,7 @@ function Set-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present", "Absent")] + [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", @@ -377,7 +374,7 @@ function Set-TargetResource [Parameter()] [System.String] - [ValidateSet("NTLM", "Kerberos")] + [ValidateSet("NTLM","Kerberos")] $CentralAdministrationAuth, [Parameter()] @@ -394,7 +391,7 @@ function Set-TargetResource $ServerRole, [Parameter()] - [ValidateSet("Off", "On", "OnDemand")] + [ValidateSet("Off","On","OnDemand")] [System.String] $DeveloperDashboard, @@ -615,12 +612,10 @@ function Set-TargetResource $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 - { + 15 { Write-Verbose -Message "Detected Version: SharePoint 2013" } - 16 - { + 16 { if ($params.ContainsKey("ServerRole") -eq $true) { if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) @@ -652,8 +647,7 @@ function Set-TargetResource $executeArgs.Add("ServerRoleOptional", $true) } } - Default - { + Default { throw [Exception] ("An unknown version of SharePoint (Major version $_) " + ` "was detected. Only versions 15 (SharePoint 2013) and" + ` "16 (SharePoint 2016 or SharePoint 2019) are supported.") @@ -889,7 +883,7 @@ function Test-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present", "Absent")] + [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", @@ -928,7 +922,7 @@ function Test-TargetResource [Parameter()] [System.String] - [ValidateSet("NTLM", "Kerberos")] + [ValidateSet("NTLM","Kerberos")] $CentralAdministrationAuth, [Parameter()] @@ -945,7 +939,7 @@ function Test-TargetResource $ServerRole, [Parameter()] - [ValidateSet("Off", "On", "OnDemand")] + [ValidateSet("Off","On","OnDemand")] [System.String] $DeveloperDashboard, From 2545d32bceae542b75986eaeecb1bb9dfe263a2e Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Wed, 13 Feb 2019 11:12:31 -0500 Subject: [PATCH 05/53] udpate CA SSL code to use CentralAdministrationUrl param --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 196 ++++++++++-------- 1 file changed, 107 insertions(+), 89 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index d7679027f..59beac2b5 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -87,6 +87,14 @@ function Get-TargetResource } } + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl")) + { + if ($CentralAdministrationUrl -match ':\d+') + { + throw ("CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead.") + } + } + if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` @@ -182,20 +190,6 @@ function Get-TargetResource | Where-Object -FilterScript { $_.IsAdministrationWebApplication -eq $true } - $centralAdminIsSsl = ($null -ne $centralAdminSite -and ` - (New-Object -TypeName System.Uri $centralAdminSite.Url).Scheme -eq "https") - - # if central admin is SSL, there should be an entry in the SecureBindings - # object of the SPWebApplication's IisSettings for the default zone - $centralAdminSslHostHeader = $null - if ($centralAdminIsSsl) - { - $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings - if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) - { - $centralAdminSslHostHeader = $secureBindings[0].HostHeader - } - } if ($params.FarmAccount.UserName -eq $spFarm.DefaultServiceAccount.Name) { @@ -236,18 +230,17 @@ function Get-TargetResource $developerDashboardStatus = $developerDashboardSettings.DisplayLevel $returnValue = @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $spFarm.Name - DatabaseServer = $configDb.NormalizedDataSource - FarmAccount = $farmAccount # Need to return this as a credential to match the type expected - Passphrase = $null - AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name - RunCentralAdmin = $centralAdminProvisioned - CentralAdministrationIsSsl = $centralAdminIsSsl - CentralAdministrationSslHostHeader = $centralAdminSslHostHeader - CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port - CentralAdministrationAuth = $centralAdminAuth - DeveloperDashboard = $developerDashboardStatus + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $spFarm.Name + DatabaseServer = $configDb.NormalizedDataSource + FarmAccount = $farmAccount # Need to return this as a credential to match the type expected + Passphrase = $null + AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name + RunCentralAdmin = $centralAdminProvisioned + CentralAdministrationUrl = $centralAdminSite.Url + CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port + CentralAdministrationAuth = $centralAdminAuth + DeveloperDashboard = $developerDashboardStatus } $installedVersion = Get-SPDSCInstalledProductVersion if ($installedVersion.FileMajorPart -eq 16) @@ -282,18 +275,17 @@ function Get-TargetResource "incomplete, however the 'Ensure' property should be " + ` "considered correct") return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationIsSsl = $null - CentralAdministrationSslHostHeader = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Present" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationUrl = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Present" } } else @@ -306,18 +298,17 @@ function Get-TargetResource { # This node has never been connected to a farm, return the null return object return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationIsSsl = $null - CentralAdministrationSslHostHeader = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Absent" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationUrl = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Absent" } } } @@ -414,11 +405,11 @@ function Set-TargetResource # Set default values to ensure they are passed to Invoke-SPDSCCommand if (-not $PSBoundParameters.ContainsKey("CentralAdministrationPort")) { - # If SSL and host header specified, let's default to port 443 and assume SNI will be used - if ($CentralAdministrationIsSsl -and ` - (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))) + # If CentralAdministrationUrl is specified and is SSL, let's infer the port from the Url + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl") -and ` + (New-Object -TypeName System.Uri $CentralAdministrationUrl).Scheme -eq 'https') { - $PSBoundParameters.Add("CentralAdministrationPort", 443) + $PSBoundParameters.Add("CentralAdministrationPort", (New-Object -TypeName System.Uri $CentralAdministrationUrl).Port) } else { @@ -427,10 +418,10 @@ function Set-TargetResource } # if we're not passing Ssl Host Header in, let's set it to $null for comparison to Current Values - if (-not $PSBoundParameters.ContainsKey("CentralAdministrationSslHostHeader")) - { - $CentralAdministrationSslHostHeader = $null - } + # if (-not $PSBoundParameters.ContainsKey("CentralAdministrationSslHostHeader")) + # { + # $CentralAdministrationSslHostHeader = $null + # } if (-not $PSBoundParameters.ContainsKey("CentralAdministrationAuth")) { @@ -502,37 +493,63 @@ function Set-TargetResource } } # For the following SSL scenarios, we should remove the CA web application and recreate it - # CentralAdministrationIsSsl = $true - # AND Current CentralAdministrationIsSsl is $false - # OR Current SSL HostHeader -ne desired SSL HostHeader (and desired host header is not null or empty) - # OR Current SecureBindings does not exist or doesn't match desired port - # The last condition might not be applicable if we rely on host header to be specified for SSL bindings - if ($CentralAdministrationIsSsl -and ` - ((-not $CurrentValues.CentralAdministrationIsSsl) -or ` - ($CurrentValues.CentralAdministrationSslHostHeader -ne $CentralAdministrationSslHostHeader -and ` - (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))))) + # CentralAdministrationUrl is HTTPS + # AND Current CentralAdministrationUrl is not equal to new CentralAdministrationUrl + # OR Current SecureBindings does not exist or doesn't match desired url and port + if ((New-Object -TypeName System.Uri $CentralAdministrationUrl).Scheme -eq 'https') { Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { $params = $args[0] - Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" - $centralAdmin = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { + $reprovisionCentralAdmin = $false + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { $_.IsAdministrationWebApplication } - Remove-SPWebApplication -Identity $centralAdmin.Url -Zone Default -DeleteIisSite - - Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" - $webAppParams = @{ - Identity = "https://$($params.CentralAdministrationSslHostHeader)" - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = $params.CentralAdministrationSslHostHeader - Port = $params.CentralAdministrationPort - SecureSocketsLayer = $true + if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) + { + $reprovisionCentralAdmin = $true + } + else + { + # check securebindings + # there should be an entry in the SecureBindings object of the + # SPWebApplication's IisSettings for the default zone + $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings + if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + { + # check to see if secureBindings host header and port match what we want them to be + if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` + $params.CentralAdministrationPort -ne $secureBindings[0].Port) + { + $reprovisionCentralAdmin = $true + } + } + else + { + # secureBindings did not exist or did not contain a valid hostheader + $reprovisionCentralAdmin = $true + } + } + + if ($reprovisionCentralAdmin) + { + Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite + + Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" + $webAppParams = @{ + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + WindowsAuthProvider = $params.CentralAdministrationAuth + SecureSocketsLayer = $true + } + New-SPWebApplication @webAppParams } - New-SPWebApplication @webAppParams } } elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) @@ -787,9 +804,9 @@ function Set-TargetResource New-SPCentralAdministration -Port $params.CentralAdministrationPort ` -WindowsAuthProvider $params.CentralAdministrationAuth - # if central admin is to be SSL and has a host name specified, let's remove and re-provision - if ($params.CentralAdministrationIsSsl -and ` - -not [string]::IsNullOrEmpty($params.CentralAdministrationSslHostHeader)) + # if central admin is to be SSL, let's remove and re-provision + if (-not [string]::IsNullOrEmpty($params.CentralAdministrationUrl) -and ` + ([System.Uri]$params.CentralAdministrationUrl).Scheme -eq 'https') { Write-Verbose -Message "Removing Central Admin to properly provision as SSL" @@ -803,12 +820,13 @@ function Set-TargetResource Write-Verbose -Message "Reprovisioning Central Admin with SSL" $webAppParams = @{ - Identity = "https://$($params.CentralAdministrationSslHostHeader)" - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = $params.CentralAdministrationSslHostHeader - Port = $params.CentralAdministrationPort - SecureSocketsLayer = $true + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + WindowsAuthProvider = $params.CentralAdministrationAuth + SecureSocketsLayer = $true } New-SPWebApplicationExtension @webAppParams From ed9182b7cb3c1b042db81219dbb3f749b79b51fe Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Wed, 13 Feb 2019 12:13:50 -0500 Subject: [PATCH 06/53] Add CentralAdministrationUrl param to schema --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof index 8e013ce58..3e45d7166 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof @@ -9,6 +9,7 @@ class MSFT_SPFarm : OMI_BaseResource [Required, Description("The passphrase to use to allow servers to join this farm"), EmbeddedInstance("MSFT_Credential")] String Passphrase; [Required, Description("The name of the admin content database")] String AdminContentDatabaseName; [Required, Description("Should the central admin site run on this specific server?")] Boolean RunCentralAdmin; + [Write, Description("Vanity URL for Central Administration to be used with SSL")] String CentralAdministrationUrl; [Write, Description("What port will Central Admin be provisioned to - default is 9999")] Uint32 CentralAdministrationPort; [Write, Description("The authentication provider of the CentralAdministration web application"), ValueMap{"NTLM","Kerberos"}, Values{"NTLM","Kerberos"}] String CentralAdministrationAuth; [Write, Description("SharePoint 2016 & 2019 only - the MinRole role to enroll this server as"), ValueMap{"Application","ApplicationWithSearch","Custom","DistributedCache","Search","SingleServer","SingleServerFarm","WebFrontEnd","WebFrontEndWithDistributedCache"}, Values{"Application","ApplicationWithSearch","Custom","DistributedCache","Search","SingleServer","SingleServerFarm","WebFrontEnd","WebFrontEndWithDistributedCache"}] String ServerRole; From faa5037964e7fc4be2d4b16db5b487ae7fe2aa93 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Wed, 13 Feb 2019 21:31:24 -0500 Subject: [PATCH 07/53] fixes --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 133 +++++++++--------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 59beac2b5..27503dd62 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -492,75 +492,80 @@ function Set-TargetResource } } } - # For the following SSL scenarios, we should remove the CA web application and recreate it - # CentralAdministrationUrl is HTTPS - # AND Current CentralAdministrationUrl is not equal to new CentralAdministrationUrl - # OR Current SecureBindings does not exist or doesn't match desired url and port - if ((New-Object -TypeName System.Uri $CentralAdministrationUrl).Scheme -eq 'https') - { - Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { - $params = $args[0] - $reprovisionCentralAdmin = $false - $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { - $_.IsAdministrationWebApplication - } - if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) - { - $reprovisionCentralAdmin = $true - } - else - { - # check securebindings - # there should be an entry in the SecureBindings object of the - # SPWebApplication's IisSettings for the default zone - $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings - if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + if ($RunCentralAdmin) + { + # For the following SSL scenarios, we should remove the CA web application and recreate it + # CentralAdministrationUrl is HTTPS + # AND Current CentralAdministrationUrl is not equal to new CentralAdministrationUrl + # OR Current SecureBindings does not exist or doesn't match desired url and port + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl") -and ` + ([System.Uri]$CentralAdministrationUrl).Scheme -eq 'https') + { + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + $reprovisionCentralAdmin = $false + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { + $_.IsAdministrationWebApplication + } + if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) { - # check to see if secureBindings host header and port match what we want them to be - if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` - $params.CentralAdministrationPort -ne $secureBindings[0].Port) + $reprovisionCentralAdmin = $true + } + else + { + # check securebindings + # there should be an entry in the SecureBindings object of the + # SPWebApplication's IisSettings for the default zone + $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings + if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + { + # check to see if secureBindings host header and port match what we want them to be + if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` + $params.CentralAdministrationPort -ne $secureBindings[0].Port) + { + $reprovisionCentralAdmin = $true + } + } + else { + # secureBindings did not exist or did not contain a valid hostheader $reprovisionCentralAdmin = $true } } - else + + if ($reprovisionCentralAdmin) { - # secureBindings did not exist or did not contain a valid hostheader - $reprovisionCentralAdmin = $true - } - } + Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite - if ($reprovisionCentralAdmin) - { - Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" - Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite - - Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" - $webAppParams = @{ - Identity = $params.CentralAdministrationUrl - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host - Port = $params.CentralAdministrationPort - WindowsAuthProvider = $params.CentralAdministrationAuth - SecureSocketsLayer = $true + Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" + $webAppParams = @{ + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + AuthenticationMethod = $params.CentralAdministrationAuth + SecureSocketsLayer = $true + } + New-SPWebApplicationExtension @webAppParams } - New-SPWebApplication @webAppParams } } - } - elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) - { - Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { - $params = $args[0] + elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) + { + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] - Write-Verbose -Message "Updating Central Admin port" - Set-SPCentralAdministration -Port $params.CentralAdministrationPort + Write-Verbose -Message "Updating Central Admin port" + Set-SPCentralAdministration -Port $params.CentralAdministrationPort + } } } @@ -820,13 +825,13 @@ function Set-TargetResource Write-Verbose -Message "Reprovisioning Central Admin with SSL" $webAppParams = @{ - Identity = $params.CentralAdministrationUrl - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host - Port = $params.CentralAdministrationPort - WindowsAuthProvider = $params.CentralAdministrationAuth - SecureSocketsLayer = $true + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + AuthenticationMethod = $params.CentralAdministrationAuth + SecureSocketsLayer = $true } New-SPWebApplicationExtension @webAppParams From 268b430da61fa5c8f007a052ffb01ff29d05a650 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 21 Feb 2019 15:13:29 -0500 Subject: [PATCH 08/53] Add verbose output for CA SSL. Fix Identity param during lookup. --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 27503dd62..64e61478f 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -511,8 +511,9 @@ function Set-TargetResource $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { $_.IsAdministrationWebApplication } - if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) + if ($centralAdminSite.Url.TrimEnd('/') -ne $params.CentralAdministrationUrl.TrimEnd('/')) { + Write-Verbose -Message "Re-provisioning CA because $($centralAdminSite.Url.TrimEnd('/')) does not equal $($params.CentralAdministrationUrl.TrimEnd('/'))" $reprovisionCentralAdmin = $true } else @@ -527,24 +528,26 @@ function Set-TargetResource if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` $params.CentralAdministrationPort -ne $secureBindings[0].Port) { + Write-Verbose -Message "Re-provisioning CA because $(([System.Uri]$params.CentralAdministrationUrl).Host) does not equal $($secureBindings[0].HostHeader)" $reprovisionCentralAdmin = $true } } else { # secureBindings did not exist or did not contain a valid hostheader + Write-Verbose -Message "Re-provisioning CA because secureBindings does not exist or does not contain a valid host header" $reprovisionCentralAdmin = $true } } if ($reprovisionCentralAdmin) { - Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + # Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" $webAppParams = @{ - Identity = $params.CentralAdministrationUrl + Identity = $centralAdminSite.Url Name = "SharePoint Central Administration v4" Zone = "Default" HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host @@ -825,7 +828,7 @@ function Set-TargetResource Write-Verbose -Message "Reprovisioning Central Admin with SSL" $webAppParams = @{ - Identity = $params.CentralAdministrationUrl + Identity = $centralAdminSite.Url Name = "SharePoint Central Administration v4" Zone = "Default" HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host From 3f26191abc9cda740f96deb1d7488df8ec611aee Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 28 Feb 2019 15:08:57 -0500 Subject: [PATCH 09/53] Trim URL for comparison --- Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 64e61478f..25ce79275 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -237,7 +237,7 @@ function Get-TargetResource Passphrase = $null AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name RunCentralAdmin = $centralAdminProvisioned - CentralAdministrationUrl = $centralAdminSite.Url + CentralAdministrationUrl = $centralAdminSite.Url.TrimEnd('/') CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port CentralAdministrationAuth = $centralAdminAuth DeveloperDashboard = $developerDashboardStatus From 7303925ef28ec44433b1acb39d177d2c95b8f8f8 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 14:12:03 -0500 Subject: [PATCH 10/53] Reprovision CA if binding isn't created correctly --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 467 +++++++++++------- 1 file changed, 296 insertions(+), 171 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 7c36cc357..372e64bd0 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -10,7 +10,7 @@ function Get-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present","Absent")] + [ValidateSet("Present", "Absent")] [System.String] $Ensure = "Present", @@ -38,30 +38,39 @@ function Get-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [switch] + $CentralAdministrationIsSsl, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $CentralAdministrationSslHostHeader, + [Parameter()] [System.UInt32] $CentralAdministrationPort, [Parameter()] [System.String] - [ValidateSet("NTLM","Kerberos")] + [ValidateSet("NTLM", "Kerberos")] $CentralAdministrationAuth, [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] - [ValidateSet("Off","On","OnDemand")] + [ValidateSet("Off", "On", "OnDemand")] [System.String] $DeveloperDashboard, @@ -78,34 +87,36 @@ function Get-TargetResource if ($CentralAdministrationPort -notin 1..65535) { throw ("An invalid value for CentralAdministrationPort is specified: " + ` - "$CentralAdministrationPort") + "$CentralAdministrationPort") } } if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 { + 15 + { Write-Verbose -Message "Detected installation of SharePoint 2013" } - 16 { + 16 + { if ($DeveloperDashboard -eq "OnDemand") { throw ("The DeveloperDashboard value 'OnDemand' is not allowed in SharePoint " + ` - "2016 and 2019") + "2016 and 2019") } if ($DeveloperDashboard -eq "On") { Write-Verbose -Message ("Please make sure you also provision the Usage and Health " + ` - "service application to make sure the Developer Dashboard " + ` - "works properly") + "service application to make sure the Developer Dashboard " + ` + "works properly") } if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) @@ -117,42 +128,43 @@ function Get-TargetResource Write-Verbose -Message "Detected installation of SharePoint 2019" } } - default { + default + { throw ("Detected an unsupported major version of SharePoint. SharePointDsc only " + ` - "supports SharePoint 2013, 2016 or 2019.") + "supports SharePoint 2013, 2016 or 2019.") } } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -ne 16) + -and $installedVersion.FileMajorPart -ne 16) { throw [Exception] "Server role is only supported in SharePoint 2016 and 2019." } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -eq 16 ` - -and $installedVersion.FileBuildPart -lt 4456 ` - -and ($ServerRole -eq "ApplicationWithSearch" ` - -or $ServerRole -eq "WebFrontEndWithDistributedCache")) + -and $installedVersion.FileMajorPart -eq 16 ` + -and $installedVersion.FileBuildPart -lt 4456 ` + -and ($ServerRole -eq "ApplicationWithSearch" ` + -or $ServerRole -eq "WebFrontEndWithDistributedCache")) { throw [Exception] ("ServerRole values of 'ApplicationWithSearch' or " + ` - "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` - "Feature Pack 1 to be installed. See " + ` - "https://support.microsoft.com/en-us/kb/3127940") + "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` + "Feature Pack 1 to be installed. See " + ` + "https://support.microsoft.com/en-us/kb/3127940") } # Determine if a connection to a farm already exists $majorVersion = $installedVersion.FileMajorPart - $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" - $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue + $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" + $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue if ($null -ne $dsnValue) { # This node has already been connected to a farm $result = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] try @@ -174,9 +186,23 @@ function Get-TargetResource $_.Name -eq $spFarm.Name -and $_.Type -eq "Configuration Database" } $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { + | Where-Object -FilterScript { $_.IsAdministrationWebApplication -eq $true } + $centralAdminIsSsl = ($null -ne $centralAdminSite -and ` + (New-Object -TypeName System.Uri $centralAdminSite.Url).Scheme -eq "https") + + # if central admin is SSL, there should be an entry in the SecureBindings + # object of the SPWebApplication's IisSettings for the default zone + $centralAdminSslHostHeader = $null + if ($centralAdminIsSsl) + { + $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings + if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + { + $centralAdminSslHostHeader = $secureBindings[0].HostHeader + } + } if ($params.FarmAccount.UserName -eq $spFarm.DefaultServiceAccount.Name) { @@ -187,20 +213,15 @@ function Get-TargetResource $farmAccount = $spFarm.DefaultServiceAccount.Name } - $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } - $centralAdminProvisioned = $false $ca = Get-SPServiceInstance -Server $env:ComputerName if ($null -ne $ca) { $ca = $ca | Where-Object -Filterscript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" -and ` - $_.Status -eq "Online" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" -and ` + $_.Status -eq "Online" + } } if ($null -ne $ca) @@ -217,21 +238,23 @@ function Get-TargetResource $centralAdminAuth = "NTLM" } - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings - $developerDashboardStatus = $developerDashboardSettings.DisplayLevel + $developerDashboardStatus = $developerDashboardSettings.DisplayLevel $returnValue = @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $spFarm.Name - DatabaseServer = $configDb.NormalizedDataSource - FarmAccount = $farmAccount # Need to return this as a credential to match the type expected - Passphrase = $null - AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name - RunCentralAdmin = $centralAdminProvisioned - CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port - CentralAdministrationAuth = $centralAdminAuth - DeveloperDashboard = $developerDashboardStatus + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $spFarm.Name + DatabaseServer = $configDb.NormalizedDataSource + FarmAccount = $farmAccount # Need to return this as a credential to match the type expected + Passphrase = $null + AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name + RunCentralAdmin = $centralAdminProvisioned + CentralAdministrationIsSsl = $centralAdminIsSsl + CentralAdministrationSslHostHeader = $centralAdminSslHostHeader + CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port + CentralAdministrationAuth = $centralAdminAuth + DeveloperDashboard = $developerDashboardStatus } $installedVersion = Get-SPDSCInstalledProductVersion if ($installedVersion.FileMajorPart -eq 16) @@ -261,21 +284,23 @@ function Get-TargetResource # The node is currently connected to a farm but was unable to retrieve the values # of current farm settings, most likely due to connectivity issues with the SQL box Write-Verbose -Message ("This server appears to be connected to a farm already, " + ` - "but the configuration database is currently unable to be " + ` - "accessed. Values returned from the get method will be " + ` - "incomplete, however the 'Ensure' property should be " + ` - "considered correct") + "but the configuration database is currently unable to be " + ` + "accessed. Values returned from the get method will be " + ` + "incomplete, however the 'Ensure' property should be " + ` + "considered correct") return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Present" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationIsSsl = $null + CentralAdministrationSslHostHeader = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Present" } } else @@ -288,16 +313,18 @@ function Get-TargetResource { # This node has never been connected to a farm, return the null return object return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Absent" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationIsSsl = $null + CentralAdministrationSslHostHeader = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Absent" } } } @@ -315,7 +342,7 @@ function Set-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present","Absent")] + [ValidateSet("Present", "Absent")] [System.String] $Ensure = "Present", @@ -343,30 +370,39 @@ function Set-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [switch] + $CentralAdministrationIsSsl, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $CentralAdministrationSslHostHeader, + [Parameter()] [System.UInt32] $CentralAdministrationPort, [Parameter()] [System.String] - [ValidateSet("NTLM","Kerberos")] + [ValidateSet("NTLM", "Kerberos")] $CentralAdministrationAuth, [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] - [ValidateSet("Off","On","OnDemand")] + [ValidateSet("Off", "On", "OnDemand")] [System.String] $DeveloperDashboard, @@ -381,7 +417,7 @@ function Set-TargetResource if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $CurrentValues = Get-TargetResource @PSBoundParameters @@ -389,7 +425,22 @@ function Set-TargetResource # Set default values to ensure they are passed to Invoke-SPDSCCommand if (-not $PSBoundParameters.ContainsKey("CentralAdministrationPort")) { - $PSBoundParameters.Add("CentralAdministrationPort", 9999) + # If SSL and host header specified, let's default to port 443 and assume SNI will be used + if ($CentralAdministrationIsSsl -and ` + (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))) + { + $PSBoundParameters.Add("CentralAdministrationPort", 443) + } + else + { + $PSBoundParameters.Add("CentralAdministrationPort", 9999) + } + } + + # if we're not passing Ssl Host Header in, let's set it to $null for comparison to Current Values + if (-not $PSBoundParameters.ContainsKey("CentralAdministrationSslHostHeader")) + { + $CentralAdministrationSslHostHeader = $null } if (-not $PSBoundParameters.ContainsKey("CentralAdministrationAuth")) @@ -404,8 +455,8 @@ function Set-TargetResource if ($CurrentValues.RunCentralAdmin -ne $RunCentralAdmin) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] # Provision central administration @@ -416,16 +467,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" - $serviceInstance = Get-SPServiceInstance -Server $fqdn ` + $fqdn = "$($env:COMPUTERNAME).$domain" + $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -441,16 +492,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" + $fqdn = "$($env:COMPUTERNAME).$domain" $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -461,11 +512,45 @@ function Set-TargetResource } } } - if ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) + # For the following SSL scenarios, we should remove the CA web application and recreate it + # CentralAdministrationIsSsl = $true + # AND Current CentralAdministrationIsSsl is $false + # OR Current SSL HostHeader -ne desired SSL HostHeader (and desired host header is not null or empty) + # OR Current SecureBindings does not exist or doesn't match desired port + # The last condition might not be applicable if we rely on host header to be specified for SSL bindings + if ($CentralAdministrationIsSsl -and ` + ((-not $CurrentValues.CentralAdministrationIsSsl) -or ` + ($CurrentValues.CentralAdministrationSslHostHeader -ne $CentralAdministrationSslHostHeader -and ` + (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))))) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + $centralAdmin = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { + $_.IsAdministrationWebApplication + } + Remove-SPWebApplication -Identity $centralAdmin.Url -Zone Default -DeleteIisSite + + Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" + $webAppParams = @{ + Identity = "https://$($params.CentralAdministrationSslHostHeader)" + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = $params.CentralAdministrationSslHostHeader + Port = $params.CentralAdministrationPort + SecureSocketsLayer = $true + } + New-SPWebApplication @webAppParams + } + } + elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) + { + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Central Admin port" @@ -476,12 +561,12 @@ function Set-TargetResource if ($CurrentValues.DeveloperDashboard -ne $DeveloperDashboard) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -495,9 +580,9 @@ function Set-TargetResource Write-Verbose -Message "Server not part of farm, creating or joining farm" $actionResult = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments @($PSBoundParameters, $PSScriptRoot) ` - -ScriptBlock { - $params = $args[0] + -Arguments @($PSBoundParameters, $PSScriptRoot) ` + -ScriptBlock { + $params = $args[0] $scriptRoot = $args[1] $modulePath = "..\..\Modules\SharePointDsc.Farm\SPFarm.psm1" @@ -511,16 +596,16 @@ function Set-TargetResource } $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName while ($dbStatus.Locked -eq $true) { Write-Verbose -Message ("[$([DateTime]::Now.ToShortTimeString())] The configuration " + ` - "database is currently being provisioned by a remote " + ` - "server, this server will wait for this to complete") + "database is currently being provisioned by a remote " + ` + "server, this server will wait for this to complete") Start-Sleep -Seconds 30 $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } if ($dbStatus.ValidPermissions -eq $false) @@ -538,21 +623,23 @@ function Set-TargetResource $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 { + 15 + { Write-Verbose -Message "Detected Version: SharePoint 2013" } - 16 { + 16 + { if ($params.ContainsKey("ServerRole") -eq $true) { if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } $executeArgs.Add("LocalServerRole", $params.ServerRole) } @@ -561,30 +648,31 @@ function Set-TargetResource if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } $executeArgs.Add("ServerRoleOptional", $true) } } - Default { + Default + { throw [Exception] ("An unknown version of SharePoint (Major version $_) " + ` - "was detected. Only versions 15 (SharePoint 2013) and" + ` - "16 (SharePoint 2016 or SharePoint 2019) are supported.") + "was detected. Only versions 15 (SharePoint 2013) and" + ` + "16 (SharePoint 2016 or SharePoint 2019) are supported.") } } if ($dbStatus.DatabaseExists -eq $true) { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' already exists, so " + ` - "this server will join the farm.") + "'$($params.FarmConfigDatabaseName)' already exists, so " + ` + "this server will join the farm.") $createFarm = $false } elseif ($dbStatus.DatabaseExists -eq $false -and $params.RunCentralAdmin -eq $false) @@ -592,17 +680,17 @@ function Set-TargetResource # Only allow the farm to be created by a server that will run central admin # to avoid a ghost CA site appearing on this server and causing issues Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` - "this server will not be running the central admin " + ` - "website, so it will wait to join the farm rather than " + ` - "create one.") + "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` + "this server will not be running the central admin " + ` + "website, so it will wait to join the farm rather than " + ` + "create one.") $createFarm = $false } else { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` - "this server will create the farm.") + "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` + "this server will create the farm.") $createFarm = $true } @@ -633,10 +721,10 @@ function Set-TargetResource } Write-Verbose -Message ("The server will attempt to join the farm now once every " + ` - "60 seconds for the next 15 minutes.") - $loopCount = 0 + "60 seconds for the next 15 minutes.") + $loopCount = 0 $connectedToFarm = $false - $lastException = $null + $lastException = $null while ($connectedToFarm -eq $false -and $loopCount -lt 15) { try @@ -648,11 +736,11 @@ function Set-TargetResource { $lastException = $_.Exception Write-Verbose -Message ("$([DateTime]::Now.ToShortTimeString()) - An error " + ` - "occured joining config database " + ` - "'$($params.FarmConfigDatabaseName)' on " + ` - "'$($params.DatabaseServer)'. This resource will " + ` - "wait and retry automatically for up to 15 minutes. " + ` - "(waited $loopCount of 15 minutes)") + "occured joining config database " + ` + "'$($params.FarmConfigDatabaseName)' on " + ` + "'$($params.DatabaseServer)'. This resource will " + ` + "wait and retry automatically for up to 15 minutes. " + ` + "(waited $loopCount of 15 minutes)") $loopCount++ Start-Sleep -Seconds 60 } @@ -670,14 +758,14 @@ function Set-TargetResource Write-Verbose -Message "The database does not exist, so create a new farm" Write-Verbose -Message ("Creating Lock database to prevent two servers creating " + ` - "the same farm") + "the same farm") Add-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName try { $executeArgs += @{ - FarmCredentials = $params.FarmAccount + FarmCredentials = $params.FarmAccount AdministrationContentDatabaseName = $params.AdminContentDatabaseName } @@ -690,7 +778,7 @@ function Set-TargetResource { Write-Verbose -Message "Removing Lock database" Remove-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } } @@ -712,10 +800,9 @@ function Set-TargetResource { Write-Verbose -Message "RunCentralAdmin is True, provisioning Central Admin" $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } - + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } $centralAdminProvisioned = $false if ((New-Object -TypeName System.Uri $centralAdminSite.Url).Port -eq $params.CentralAdministrationPort) @@ -726,7 +813,34 @@ function Set-TargetResource if ($centralAdminProvisioned -eq $false) { New-SPCentralAdministration -Port $params.CentralAdministrationPort ` - -WindowsAuthProvider $params.CentralAdministrationAuth + -WindowsAuthProvider $params.CentralAdministrationAuth + + # if central admin is to be SSL and has a host name specified, let's remove and re-provision + if ($params.CentralAdministrationIsSsl -and ` + -not [string]::IsNullOrEmpty($params.CentralAdministrationSslHostHeader)) + { + Write-Verbose -Message "Removing Central Admin to properly provision as SSL" + + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } + + Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite + + Write-Verbose -Message "Reprovisioning Central Admin with SSL" + + $webAppParams = @{ + Identity = "https://$($params.CentralAdministrationSslHostHeader)" + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = $params.CentralAdministrationSslHostHeader + Port = $params.CentralAdministrationPort + SecureSocketsLayer = $true + } + + New-SPWebApplicationExtension @webAppParams + } } else { @@ -742,7 +856,7 @@ function Set-TargetResource { $serviceInstance = $serviceInstance | Where-Object -FilterScript { $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" + $_.Name -eq "WSS_Administration" } } @@ -760,7 +874,7 @@ function Set-TargetResource if ($params.ContainsKey("DeveloperDashboard") -and $params.DeveloperDashboard -ne "Off") { Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -775,10 +889,10 @@ function Set-TargetResource Start-Service -Name sptimerv4 Write-Verbose -Message ("Pausing for 5 minutes to allow the timer service to " + ` - "fully provision the server") + "fully provision the server") Start-Sleep -Seconds 300 Write-Verbose -Message ("Join farm complete. Restarting computer to allow " + ` - "configuration to continue") + "configuration to continue") $global:DSCMachineStatus = 1 } @@ -797,7 +911,7 @@ function Test-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present","Absent")] + [ValidateSet("Present", "Absent")] [System.String] $Ensure = "Present", @@ -825,30 +939,39 @@ function Test-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [switch] + $CentralAdministrationIsSsl, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $CentralAdministrationSslHostHeader, + [Parameter()] [System.UInt32] $CentralAdministrationPort, [Parameter()] [System.String] - [ValidateSet("NTLM","Kerberos")] + [ValidateSet("NTLM", "Kerberos")] $CentralAdministrationAuth, [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] - [ValidateSet("Off","On","OnDemand")] + [ValidateSet("Off", "On", "OnDemand")] [System.String] $DeveloperDashboard, @@ -865,11 +988,13 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters return Test-SPDscParameterState -CurrentValues $CurrentValues ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck @("Ensure", - "RunCentralAdmin", - "CentralAdministrationPort", - "DeveloperDashboard") + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("Ensure", + "RunCentralAdmin", + "CentralAdministrationIsSsl", + "CentralAdministrationSslHostHeader", + "CentralAdministrationPort", + "DeveloperDashboard") } Export-ModuleMember -Function *-TargetResource From da31a3fe3393d93eda3f65d497de049b85803296 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 21:21:45 -0500 Subject: [PATCH 11/53] restore most formatting, change argument for CA SSL, more changes coming --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 251 +++++++++--------- 1 file changed, 119 insertions(+), 132 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 372e64bd0..b772a6950 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -38,14 +38,10 @@ function Get-TargetResource [System.Boolean] $RunCentralAdmin, - [Parameter()] - [switch] - $CentralAdministrationIsSsl, - [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $CentralAdministrationSslHostHeader, + $CentralAdministrationUrl, [Parameter()] [System.UInt32] @@ -59,14 +55,14 @@ function Get-TargetResource [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] @@ -87,14 +83,14 @@ function Get-TargetResource if ($CentralAdministrationPort -notin 1..65535) { throw ("An invalid value for CentralAdministrationPort is specified: " + ` - "$CentralAdministrationPort") + "$CentralAdministrationPort") } } if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $installedVersion = Get-SPDSCInstalledProductVersion @@ -109,7 +105,7 @@ function Get-TargetResource if ($DeveloperDashboard -eq "OnDemand") { throw ("The DeveloperDashboard value 'OnDemand' is not allowed in SharePoint " + ` - "2016 and 2019") + "2016 and 2019") } if ($DeveloperDashboard -eq "On") @@ -131,40 +127,40 @@ function Get-TargetResource default { throw ("Detected an unsupported major version of SharePoint. SharePointDsc only " + ` - "supports SharePoint 2013, 2016 or 2019.") + "supports SharePoint 2013, 2016 or 2019.") } } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -ne 16) + -and $installedVersion.FileMajorPart -ne 16) { throw [Exception] "Server role is only supported in SharePoint 2016 and 2019." } if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) ` - -and $installedVersion.FileMajorPart -eq 16 ` - -and $installedVersion.FileBuildPart -lt 4456 ` - -and ($ServerRole -eq "ApplicationWithSearch" ` - -or $ServerRole -eq "WebFrontEndWithDistributedCache")) + -and $installedVersion.FileMajorPart -eq 16 ` + -and $installedVersion.FileBuildPart -lt 4456 ` + -and ($ServerRole -eq "ApplicationWithSearch" ` + -or $ServerRole -eq "WebFrontEndWithDistributedCache")) { throw [Exception] ("ServerRole values of 'ApplicationWithSearch' or " + ` - "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` - "Feature Pack 1 to be installed. See " + ` - "https://support.microsoft.com/en-us/kb/3127940") + "'WebFrontEndWithDistributedCache' require the SharePoint 2016 " + ` + "Feature Pack 1 to be installed. See " + ` + "https://support.microsoft.com/en-us/kb/3127940") } # Determine if a connection to a farm already exists $majorVersion = $installedVersion.FileMajorPart - $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" - $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue + $regPath = "hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\$majorVersion.0\Secure\ConfigDB" + $dsnValue = Get-SPDSCRegistryKey -Key $regPath -Value "dsn" -ErrorAction SilentlyContinue if ($null -ne $dsnValue) { # This node has already been connected to a farm $result = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] try @@ -186,7 +182,7 @@ function Get-TargetResource $_.Name -eq $spFarm.Name -and $_.Type -eq "Configuration Database" } $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { + | Where-Object -FilterScript { $_.IsAdministrationWebApplication -eq $true } $centralAdminIsSsl = ($null -ne $centralAdminSite -and ` @@ -218,10 +214,10 @@ function Get-TargetResource if ($null -ne $ca) { $ca = $ca | Where-Object -Filterscript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" -and ` - $_.Status -eq "Online" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" -and ` + $_.Status -eq "Online" + } } if ($null -ne $ca) @@ -238,9 +234,9 @@ function Get-TargetResource $centralAdminAuth = "NTLM" } - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings - $developerDashboardStatus = $developerDashboardSettings.DisplayLevel + $developerDashboardStatus = $developerDashboardSettings.DisplayLevel $returnValue = @{ IsSingleInstance = "Yes" @@ -284,10 +280,10 @@ function Get-TargetResource # The node is currently connected to a farm but was unable to retrieve the values # of current farm settings, most likely due to connectivity issues with the SQL box Write-Verbose -Message ("This server appears to be connected to a farm already, " + ` - "but the configuration database is currently unable to be " + ` - "accessed. Values returned from the get method will be " + ` - "incomplete, however the 'Ensure' property should be " + ` - "considered correct") + "but the configuration database is currently unable to be " + ` + "accessed. Values returned from the get method will be " + ` + "incomplete, however the 'Ensure' property should be " + ` + "considered correct") return @{ IsSingleInstance = "Yes" FarmConfigDatabaseName = $null @@ -370,14 +366,10 @@ function Set-TargetResource [System.Boolean] $RunCentralAdmin, - [Parameter()] - [switch] - $CentralAdministrationIsSsl, - [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $CentralAdministrationSslHostHeader, + $CentralAdministrationUrl, [Parameter()] [System.UInt32] @@ -391,14 +383,14 @@ function Set-TargetResource [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] @@ -417,7 +409,7 @@ function Set-TargetResource if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` - "ensure property to 'present'") + "ensure property to 'present'") } $CurrentValues = Get-TargetResource @PSBoundParameters @@ -455,8 +447,8 @@ function Set-TargetResource if ($CurrentValues.RunCentralAdmin -ne $RunCentralAdmin) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] # Provision central administration @@ -467,16 +459,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" + $fqdn = "$($env:COMPUTERNAME).$domain" $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -492,16 +484,16 @@ function Set-TargetResource if ($null -eq $serviceInstance) { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain - $fqdn = "$($env:COMPUTERNAME).$domain" + $fqdn = "$($env:COMPUTERNAME).$domain" $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) { $serviceInstance = $serviceInstance | Where-Object -FilterScript { - $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" - } + $_.GetType().Name -eq "SPWebServiceInstance" -and ` + $_.Name -eq "WSS_Administration" + } } if ($null -eq $serviceInstance) @@ -549,8 +541,8 @@ function Set-TargetResource elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Central Admin port" @@ -561,12 +553,12 @@ function Set-TargetResource if ($CurrentValues.DeveloperDashboard -ne $DeveloperDashboard) { Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { + -Arguments $PSBoundParameters ` + -ScriptBlock { $params = $args[0] Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -580,9 +572,9 @@ function Set-TargetResource Write-Verbose -Message "Server not part of farm, creating or joining farm" $actionResult = Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments @($PSBoundParameters, $PSScriptRoot) ` - -ScriptBlock { - $params = $args[0] + -Arguments @($PSBoundParameters, $PSScriptRoot) ` + -ScriptBlock { + $params = $args[0] $scriptRoot = $args[1] $modulePath = "..\..\Modules\SharePointDsc.Farm\SPFarm.psm1" @@ -596,16 +588,16 @@ function Set-TargetResource } $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName while ($dbStatus.Locked -eq $true) { Write-Verbose -Message ("[$([DateTime]::Now.ToShortTimeString())] The configuration " + ` - "database is currently being provisioned by a remote " + ` - "server, this server will wait for this to complete") + "database is currently being provisioned by a remote " + ` + "server, this server will wait for this to complete") Start-Sleep -Seconds 30 $dbStatus = Get-SPDSCConfigDBStatus -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } if ($dbStatus.ValidPermissions -eq $false) @@ -634,12 +626,12 @@ function Set-TargetResource if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - " + ` - "configuring server as $($params.ServerRole)") + "configuring server as $($params.ServerRole)") } $executeArgs.Add("LocalServerRole", $params.ServerRole) } @@ -648,14 +640,14 @@ function Set-TargetResource if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) { Write-Verbose -Message ("Detected Version: SharePoint 2016 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } else { Write-Verbose -Message ("Detected Version: SharePoint 2019 - no server " + ` - "role provided, configuring server without a " + ` - "specific role") + "role provided, configuring server without a " + ` + "specific role") } $executeArgs.Add("ServerRoleOptional", $true) } @@ -663,16 +655,16 @@ function Set-TargetResource Default { throw [Exception] ("An unknown version of SharePoint (Major version $_) " + ` - "was detected. Only versions 15 (SharePoint 2013) and" + ` - "16 (SharePoint 2016 or SharePoint 2019) are supported.") + "was detected. Only versions 15 (SharePoint 2013) and" + ` + "16 (SharePoint 2016 or SharePoint 2019) are supported.") } } if ($dbStatus.DatabaseExists -eq $true) { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' already exists, so " + ` - "this server will join the farm.") + "'$($params.FarmConfigDatabaseName)' already exists, so " + ` + "this server will join the farm.") $createFarm = $false } elseif ($dbStatus.DatabaseExists -eq $false -and $params.RunCentralAdmin -eq $false) @@ -680,17 +672,17 @@ function Set-TargetResource # Only allow the farm to be created by a server that will run central admin # to avoid a ghost CA site appearing on this server and causing issues Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` - "this server will not be running the central admin " + ` - "website, so it will wait to join the farm rather than " + ` - "create one.") + "'$($params.FarmConfigDatabaseName)' does not exist, but " + ` + "this server will not be running the central admin " + ` + "website, so it will wait to join the farm rather than " + ` + "create one.") $createFarm = $false } else { Write-Verbose -Message ("The SharePoint config database " + ` - "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` - "this server will create the farm.") + "'$($params.FarmConfigDatabaseName)' does not exist, so " + ` + "this server will create the farm.") $createFarm = $true } @@ -721,10 +713,10 @@ function Set-TargetResource } Write-Verbose -Message ("The server will attempt to join the farm now once every " + ` - "60 seconds for the next 15 minutes.") - $loopCount = 0 + "60 seconds for the next 15 minutes.") + $loopCount = 0 $connectedToFarm = $false - $lastException = $null + $lastException = $null while ($connectedToFarm -eq $false -and $loopCount -lt 15) { try @@ -736,11 +728,11 @@ function Set-TargetResource { $lastException = $_.Exception Write-Verbose -Message ("$([DateTime]::Now.ToShortTimeString()) - An error " + ` - "occured joining config database " + ` - "'$($params.FarmConfigDatabaseName)' on " + ` - "'$($params.DatabaseServer)'. This resource will " + ` - "wait and retry automatically for up to 15 minutes. " + ` - "(waited $loopCount of 15 minutes)") + "occured joining config database " + ` + "'$($params.FarmConfigDatabaseName)' on " + ` + "'$($params.DatabaseServer)'. This resource will " + ` + "wait and retry automatically for up to 15 minutes. " + ` + "(waited $loopCount of 15 minutes)") $loopCount++ Start-Sleep -Seconds 60 } @@ -758,14 +750,14 @@ function Set-TargetResource Write-Verbose -Message "The database does not exist, so create a new farm" Write-Verbose -Message ("Creating Lock database to prevent two servers creating " + ` - "the same farm") + "the same farm") Add-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName try { $executeArgs += @{ - FarmCredentials = $params.FarmAccount + FarmCredentials = $params.FarmAccount AdministrationContentDatabaseName = $params.AdminContentDatabaseName } @@ -778,7 +770,7 @@ function Set-TargetResource { Write-Verbose -Message "Removing Lock database" Remove-SPDscConfigDBLock -SQLServer $params.DatabaseServer ` - -Database $params.FarmConfigDatabaseName + -Database $params.FarmConfigDatabaseName } } @@ -800,9 +792,9 @@ function Set-TargetResource { Write-Verbose -Message "RunCentralAdmin is True, provisioning Central Admin" $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } $centralAdminProvisioned = $false if ((New-Object -TypeName System.Uri $centralAdminSite.Url).Port -eq $params.CentralAdministrationPort) @@ -813,7 +805,7 @@ function Set-TargetResource if ($centralAdminProvisioned -eq $false) { New-SPCentralAdministration -Port $params.CentralAdministrationPort ` - -WindowsAuthProvider $params.CentralAdministrationAuth + -WindowsAuthProvider $params.CentralAdministrationAuth # if central admin is to be SSL and has a host name specified, let's remove and re-provision if ($params.CentralAdministrationIsSsl -and ` @@ -856,7 +848,7 @@ function Set-TargetResource { $serviceInstance = $serviceInstance | Where-Object -FilterScript { $_.GetType().Name -eq "SPWebServiceInstance" -and ` - $_.Name -eq "WSS_Administration" + $_.Name -eq "WSS_Administration" } } @@ -874,7 +866,7 @@ function Set-TargetResource if ($params.ContainsKey("DeveloperDashboard") -and $params.DeveloperDashboard -ne "Off") { Write-Verbose -Message "Updating Developer Dashboard setting" - $admService = Get-SPDSCContentService + $admService = Get-SPDSCContentService $developerDashboardSettings = $admService.DeveloperDashboardSettings $developerDashboardSettings.DisplayLevel = [Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::$params.DeveloperDashboard $developerDashboardSettings.Update() @@ -889,10 +881,10 @@ function Set-TargetResource Start-Service -Name sptimerv4 Write-Verbose -Message ("Pausing for 5 minutes to allow the timer service to " + ` - "fully provision the server") + "fully provision the server") Start-Sleep -Seconds 300 Write-Verbose -Message ("Join farm complete. Restarting computer to allow " + ` - "configuration to continue") + "configuration to continue") $global:DSCMachineStatus = 1 } @@ -939,14 +931,10 @@ function Test-TargetResource [System.Boolean] $RunCentralAdmin, - [Parameter()] - [switch] - $CentralAdministrationIsSsl, - [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $CentralAdministrationSslHostHeader, + $CentralAdministrationUrl, [Parameter()] [System.UInt32] @@ -960,14 +948,14 @@ function Test-TargetResource [Parameter()] [System.String] [ValidateSet("Application", - "ApplicationWithSearch", - "Custom", - "DistributedCache", - "Search", - "SingleServer", - "SingleServerFarm", - "WebFrontEnd", - "WebFrontEndWithDistributedCache")] + "ApplicationWithSearch", + "Custom", + "DistributedCache", + "Search", + "SingleServer", + "SingleServerFarm", + "WebFrontEnd", + "WebFrontEndWithDistributedCache")] $ServerRole, [Parameter()] @@ -988,13 +976,12 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters return Test-SPDscParameterState -CurrentValues $CurrentValues ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck @("Ensure", - "RunCentralAdmin", - "CentralAdministrationIsSsl", - "CentralAdministrationSslHostHeader", - "CentralAdministrationPort", - "DeveloperDashboard") + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @("Ensure", + "RunCentralAdmin", + "CentralAdministrationUrl", + "CentralAdministrationPort", + "DeveloperDashboard") } Export-ModuleMember -Function *-TargetResource From 3666ddd581827eab436c1508fe4d0cacb925b6c2 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 21:23:38 -0500 Subject: [PATCH 12/53] restore additional formatting --- .../SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index b772a6950..a2a5f2882 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -111,8 +111,8 @@ function Get-TargetResource if ($DeveloperDashboard -eq "On") { Write-Verbose -Message ("Please make sure you also provision the Usage and Health " + ` - "service application to make sure the Developer Dashboard " + ` - "works properly") + "service application to make sure the Developer Dashboard " + ` + "works properly") } if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) From c6f7a976efb9b8b5fd927fb6528738b12289956b Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 12 Feb 2019 21:28:43 -0500 Subject: [PATCH 13/53] final formatting restoration --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index a2a5f2882..e13b563dd 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -10,7 +10,7 @@ function Get-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present", "Absent")] + [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", @@ -49,7 +49,7 @@ function Get-TargetResource [Parameter()] [System.String] - [ValidateSet("NTLM", "Kerberos")] + [ValidateSet("NTLM","Kerberos")] $CentralAdministrationAuth, [Parameter()] @@ -66,7 +66,7 @@ function Get-TargetResource $ServerRole, [Parameter()] - [ValidateSet("Off", "On", "OnDemand")] + [ValidateSet("Off","On","OnDemand")] [System.String] $DeveloperDashboard, @@ -96,12 +96,10 @@ function Get-TargetResource $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 - { + 15 { Write-Verbose -Message "Detected installation of SharePoint 2013" } - 16 - { + 16 { if ($DeveloperDashboard -eq "OnDemand") { throw ("The DeveloperDashboard value 'OnDemand' is not allowed in SharePoint " + ` @@ -124,8 +122,7 @@ function Get-TargetResource Write-Verbose -Message "Detected installation of SharePoint 2019" } } - default - { + default { throw ("Detected an unsupported major version of SharePoint. SharePointDsc only " + ` "supports SharePoint 2013, 2016 or 2019.") } @@ -338,7 +335,7 @@ function Set-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present", "Absent")] + [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", @@ -377,7 +374,7 @@ function Set-TargetResource [Parameter()] [System.String] - [ValidateSet("NTLM", "Kerberos")] + [ValidateSet("NTLM","Kerberos")] $CentralAdministrationAuth, [Parameter()] @@ -394,7 +391,7 @@ function Set-TargetResource $ServerRole, [Parameter()] - [ValidateSet("Off", "On", "OnDemand")] + [ValidateSet("Off","On","OnDemand")] [System.String] $DeveloperDashboard, @@ -615,12 +612,10 @@ function Set-TargetResource $installedVersion = Get-SPDSCInstalledProductVersion switch ($installedVersion.FileMajorPart) { - 15 - { + 15 { Write-Verbose -Message "Detected Version: SharePoint 2013" } - 16 - { + 16 { if ($params.ContainsKey("ServerRole") -eq $true) { if ($installedVersion.ProductBuildPart.ToString().Length -eq 4) @@ -652,8 +647,7 @@ function Set-TargetResource $executeArgs.Add("ServerRoleOptional", $true) } } - Default - { + Default { throw [Exception] ("An unknown version of SharePoint (Major version $_) " + ` "was detected. Only versions 15 (SharePoint 2013) and" + ` "16 (SharePoint 2016 or SharePoint 2019) are supported.") @@ -903,7 +897,7 @@ function Test-TargetResource $IsSingleInstance, [Parameter()] - [ValidateSet("Present", "Absent")] + [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", @@ -942,7 +936,7 @@ function Test-TargetResource [Parameter()] [System.String] - [ValidateSet("NTLM", "Kerberos")] + [ValidateSet("NTLM","Kerberos")] $CentralAdministrationAuth, [Parameter()] @@ -959,7 +953,7 @@ function Test-TargetResource $ServerRole, [Parameter()] - [ValidateSet("Off", "On", "OnDemand")] + [ValidateSet("Off","On","OnDemand")] [System.String] $DeveloperDashboard, From e875aa37d0c94e1d8770e4fbb2d8638826cac124 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Wed, 13 Feb 2019 11:12:31 -0500 Subject: [PATCH 14/53] udpate CA SSL code to use CentralAdministrationUrl param --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 196 ++++++++++-------- 1 file changed, 107 insertions(+), 89 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index e13b563dd..b00aca17e 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -87,6 +87,14 @@ function Get-TargetResource } } + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl")) + { + if ($CentralAdministrationUrl -match ':\d+') + { + throw ("CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead.") + } + } + if ($Ensure -eq "Absent") { throw ("SharePointDsc does not support removing a server from a farm, please set the " + ` @@ -182,20 +190,6 @@ function Get-TargetResource | Where-Object -FilterScript { $_.IsAdministrationWebApplication -eq $true } - $centralAdminIsSsl = ($null -ne $centralAdminSite -and ` - (New-Object -TypeName System.Uri $centralAdminSite.Url).Scheme -eq "https") - - # if central admin is SSL, there should be an entry in the SecureBindings - # object of the SPWebApplication's IisSettings for the default zone - $centralAdminSslHostHeader = $null - if ($centralAdminIsSsl) - { - $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings - if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) - { - $centralAdminSslHostHeader = $secureBindings[0].HostHeader - } - } if ($params.FarmAccount.UserName -eq $spFarm.DefaultServiceAccount.Name) { @@ -236,18 +230,17 @@ function Get-TargetResource $developerDashboardStatus = $developerDashboardSettings.DisplayLevel $returnValue = @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $spFarm.Name - DatabaseServer = $configDb.NormalizedDataSource - FarmAccount = $farmAccount # Need to return this as a credential to match the type expected - Passphrase = $null - AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name - RunCentralAdmin = $centralAdminProvisioned - CentralAdministrationIsSsl = $centralAdminIsSsl - CentralAdministrationSslHostHeader = $centralAdminSslHostHeader - CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port - CentralAdministrationAuth = $centralAdminAuth - DeveloperDashboard = $developerDashboardStatus + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $spFarm.Name + DatabaseServer = $configDb.NormalizedDataSource + FarmAccount = $farmAccount # Need to return this as a credential to match the type expected + Passphrase = $null + AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name + RunCentralAdmin = $centralAdminProvisioned + CentralAdministrationUrl = $centralAdminSite.Url + CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port + CentralAdministrationAuth = $centralAdminAuth + DeveloperDashboard = $developerDashboardStatus } $installedVersion = Get-SPDSCInstalledProductVersion if ($installedVersion.FileMajorPart -eq 16) @@ -282,18 +275,17 @@ function Get-TargetResource "incomplete, however the 'Ensure' property should be " + ` "considered correct") return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationIsSsl = $null - CentralAdministrationSslHostHeader = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Present" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationUrl = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Present" } } else @@ -306,18 +298,17 @@ function Get-TargetResource { # This node has never been connected to a farm, return the null return object return @{ - IsSingleInstance = "Yes" - FarmConfigDatabaseName = $null - DatabaseServer = $null - FarmAccount = $null - Passphrase = $null - AdminContentDatabaseName = $null - RunCentralAdmin = $null - CentralAdministrationIsSsl = $null - CentralAdministrationSslHostHeader = $null - CentralAdministrationPort = $null - CentralAdministrationAuth = $null - Ensure = "Absent" + IsSingleInstance = "Yes" + FarmConfigDatabaseName = $null + DatabaseServer = $null + FarmAccount = $null + Passphrase = $null + AdminContentDatabaseName = $null + RunCentralAdmin = $null + CentralAdministrationUrl = $null + CentralAdministrationPort = $null + CentralAdministrationAuth = $null + Ensure = "Absent" } } } @@ -414,11 +405,11 @@ function Set-TargetResource # Set default values to ensure they are passed to Invoke-SPDSCCommand if (-not $PSBoundParameters.ContainsKey("CentralAdministrationPort")) { - # If SSL and host header specified, let's default to port 443 and assume SNI will be used - if ($CentralAdministrationIsSsl -and ` - (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))) + # If CentralAdministrationUrl is specified and is SSL, let's infer the port from the Url + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl") -and ` + (New-Object -TypeName System.Uri $CentralAdministrationUrl).Scheme -eq 'https') { - $PSBoundParameters.Add("CentralAdministrationPort", 443) + $PSBoundParameters.Add("CentralAdministrationPort", (New-Object -TypeName System.Uri $CentralAdministrationUrl).Port) } else { @@ -427,10 +418,10 @@ function Set-TargetResource } # if we're not passing Ssl Host Header in, let's set it to $null for comparison to Current Values - if (-not $PSBoundParameters.ContainsKey("CentralAdministrationSslHostHeader")) - { - $CentralAdministrationSslHostHeader = $null - } + # if (-not $PSBoundParameters.ContainsKey("CentralAdministrationSslHostHeader")) + # { + # $CentralAdministrationSslHostHeader = $null + # } if (-not $PSBoundParameters.ContainsKey("CentralAdministrationAuth")) { @@ -502,37 +493,63 @@ function Set-TargetResource } } # For the following SSL scenarios, we should remove the CA web application and recreate it - # CentralAdministrationIsSsl = $true - # AND Current CentralAdministrationIsSsl is $false - # OR Current SSL HostHeader -ne desired SSL HostHeader (and desired host header is not null or empty) - # OR Current SecureBindings does not exist or doesn't match desired port - # The last condition might not be applicable if we rely on host header to be specified for SSL bindings - if ($CentralAdministrationIsSsl -and ` - ((-not $CurrentValues.CentralAdministrationIsSsl) -or ` - ($CurrentValues.CentralAdministrationSslHostHeader -ne $CentralAdministrationSslHostHeader -and ` - (-not [string]::IsNullOrEmpty($CentralAdministrationSslHostHeader))))) + # CentralAdministrationUrl is HTTPS + # AND Current CentralAdministrationUrl is not equal to new CentralAdministrationUrl + # OR Current SecureBindings does not exist or doesn't match desired url and port + if ((New-Object -TypeName System.Uri $CentralAdministrationUrl).Scheme -eq 'https') { Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { $params = $args[0] - Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" - $centralAdmin = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { + $reprovisionCentralAdmin = $false + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { $_.IsAdministrationWebApplication } - Remove-SPWebApplication -Identity $centralAdmin.Url -Zone Default -DeleteIisSite - - Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" - $webAppParams = @{ - Identity = "https://$($params.CentralAdministrationSslHostHeader)" - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = $params.CentralAdministrationSslHostHeader - Port = $params.CentralAdministrationPort - SecureSocketsLayer = $true + if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) + { + $reprovisionCentralAdmin = $true + } + else + { + # check securebindings + # there should be an entry in the SecureBindings object of the + # SPWebApplication's IisSettings for the default zone + $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings + if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + { + # check to see if secureBindings host header and port match what we want them to be + if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` + $params.CentralAdministrationPort -ne $secureBindings[0].Port) + { + $reprovisionCentralAdmin = $true + } + } + else + { + # secureBindings did not exist or did not contain a valid hostheader + $reprovisionCentralAdmin = $true + } + } + + if ($reprovisionCentralAdmin) + { + Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite + + Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" + $webAppParams = @{ + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + WindowsAuthProvider = $params.CentralAdministrationAuth + SecureSocketsLayer = $true + } + New-SPWebApplication @webAppParams } - New-SPWebApplication @webAppParams } } elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) @@ -801,9 +818,9 @@ function Set-TargetResource New-SPCentralAdministration -Port $params.CentralAdministrationPort ` -WindowsAuthProvider $params.CentralAdministrationAuth - # if central admin is to be SSL and has a host name specified, let's remove and re-provision - if ($params.CentralAdministrationIsSsl -and ` - -not [string]::IsNullOrEmpty($params.CentralAdministrationSslHostHeader)) + # if central admin is to be SSL, let's remove and re-provision + if (-not [string]::IsNullOrEmpty($params.CentralAdministrationUrl) -and ` + ([System.Uri]$params.CentralAdministrationUrl).Scheme -eq 'https') { Write-Verbose -Message "Removing Central Admin to properly provision as SSL" @@ -817,12 +834,13 @@ function Set-TargetResource Write-Verbose -Message "Reprovisioning Central Admin with SSL" $webAppParams = @{ - Identity = "https://$($params.CentralAdministrationSslHostHeader)" - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = $params.CentralAdministrationSslHostHeader - Port = $params.CentralAdministrationPort - SecureSocketsLayer = $true + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + WindowsAuthProvider = $params.CentralAdministrationAuth + SecureSocketsLayer = $true } New-SPWebApplicationExtension @webAppParams From 6d97243b887955042f5445e0cd340d371e69c02c Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Wed, 13 Feb 2019 12:13:50 -0500 Subject: [PATCH 15/53] Add CentralAdministrationUrl param to schema --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof index 8e013ce58..3e45d7166 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.schema.mof @@ -9,6 +9,7 @@ class MSFT_SPFarm : OMI_BaseResource [Required, Description("The passphrase to use to allow servers to join this farm"), EmbeddedInstance("MSFT_Credential")] String Passphrase; [Required, Description("The name of the admin content database")] String AdminContentDatabaseName; [Required, Description("Should the central admin site run on this specific server?")] Boolean RunCentralAdmin; + [Write, Description("Vanity URL for Central Administration to be used with SSL")] String CentralAdministrationUrl; [Write, Description("What port will Central Admin be provisioned to - default is 9999")] Uint32 CentralAdministrationPort; [Write, Description("The authentication provider of the CentralAdministration web application"), ValueMap{"NTLM","Kerberos"}, Values{"NTLM","Kerberos"}] String CentralAdministrationAuth; [Write, Description("SharePoint 2016 & 2019 only - the MinRole role to enroll this server as"), ValueMap{"Application","ApplicationWithSearch","Custom","DistributedCache","Search","SingleServer","SingleServerFarm","WebFrontEnd","WebFrontEndWithDistributedCache"}, Values{"Application","ApplicationWithSearch","Custom","DistributedCache","Search","SingleServer","SingleServerFarm","WebFrontEnd","WebFrontEndWithDistributedCache"}] String ServerRole; From c03333c79e637ada92bad9d4e60874d51f316eed Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Wed, 13 Feb 2019 21:31:24 -0500 Subject: [PATCH 16/53] fixes --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 133 +++++++++--------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index b00aca17e..2a639ac38 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -492,75 +492,80 @@ function Set-TargetResource } } } - # For the following SSL scenarios, we should remove the CA web application and recreate it - # CentralAdministrationUrl is HTTPS - # AND Current CentralAdministrationUrl is not equal to new CentralAdministrationUrl - # OR Current SecureBindings does not exist or doesn't match desired url and port - if ((New-Object -TypeName System.Uri $CentralAdministrationUrl).Scheme -eq 'https') - { - Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { - $params = $args[0] - $reprovisionCentralAdmin = $false - $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { - $_.IsAdministrationWebApplication - } - if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) - { - $reprovisionCentralAdmin = $true - } - else - { - # check securebindings - # there should be an entry in the SecureBindings object of the - # SPWebApplication's IisSettings for the default zone - $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings - if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + if ($RunCentralAdmin) + { + # For the following SSL scenarios, we should remove the CA web application and recreate it + # CentralAdministrationUrl is HTTPS + # AND Current CentralAdministrationUrl is not equal to new CentralAdministrationUrl + # OR Current SecureBindings does not exist or doesn't match desired url and port + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl") -and ` + ([System.Uri]$CentralAdministrationUrl).Scheme -eq 'https') + { + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + $reprovisionCentralAdmin = $false + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { + $_.IsAdministrationWebApplication + } + if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) { - # check to see if secureBindings host header and port match what we want them to be - if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` - $params.CentralAdministrationPort -ne $secureBindings[0].Port) + $reprovisionCentralAdmin = $true + } + else + { + # check securebindings + # there should be an entry in the SecureBindings object of the + # SPWebApplication's IisSettings for the default zone + $secureBindings = $centralAdminSite.GetIisSettingsWithFallback("Default").SecureBindings + if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) + { + # check to see if secureBindings host header and port match what we want them to be + if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` + $params.CentralAdministrationPort -ne $secureBindings[0].Port) + { + $reprovisionCentralAdmin = $true + } + } + else { + # secureBindings did not exist or did not contain a valid hostheader $reprovisionCentralAdmin = $true } } - else + + if ($reprovisionCentralAdmin) { - # secureBindings did not exist or did not contain a valid hostheader - $reprovisionCentralAdmin = $true - } - } + Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite - if ($reprovisionCentralAdmin) - { - Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" - Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite - - Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" - $webAppParams = @{ - Identity = $params.CentralAdministrationUrl - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host - Port = $params.CentralAdministrationPort - WindowsAuthProvider = $params.CentralAdministrationAuth - SecureSocketsLayer = $true + Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" + $webAppParams = @{ + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + AuthenticationMethod = $params.CentralAdministrationAuth + SecureSocketsLayer = $true + } + New-SPWebApplicationExtension @webAppParams } - New-SPWebApplication @webAppParams } } - } - elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) - { - Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { - $params = $args[0] + elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) + { + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] - Write-Verbose -Message "Updating Central Admin port" - Set-SPCentralAdministration -Port $params.CentralAdministrationPort + Write-Verbose -Message "Updating Central Admin port" + Set-SPCentralAdministration -Port $params.CentralAdministrationPort + } } } @@ -834,13 +839,13 @@ function Set-TargetResource Write-Verbose -Message "Reprovisioning Central Admin with SSL" $webAppParams = @{ - Identity = $params.CentralAdministrationUrl - Name = "SharePoint Central Administration v4" - Zone = "Default" - HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host - Port = $params.CentralAdministrationPort - WindowsAuthProvider = $params.CentralAdministrationAuth - SecureSocketsLayer = $true + Identity = $params.CentralAdministrationUrl + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + AuthenticationMethod = $params.CentralAdministrationAuth + SecureSocketsLayer = $true } New-SPWebApplicationExtension @webAppParams From 7d3f35b417929109234af80f02aa49a57514ec11 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 21 Feb 2019 15:13:29 -0500 Subject: [PATCH 17/53] Add verbose output for CA SSL. Fix Identity param during lookup. --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 2a639ac38..8ce165a7d 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -511,8 +511,9 @@ function Set-TargetResource $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { $_.IsAdministrationWebApplication } - if ($centralAdminSite.Url -ne $params.CentralAdministrationUrl) + if ($centralAdminSite.Url.TrimEnd('/') -ne $params.CentralAdministrationUrl.TrimEnd('/')) { + Write-Verbose -Message "Re-provisioning CA because $($centralAdminSite.Url.TrimEnd('/')) does not equal $($params.CentralAdministrationUrl.TrimEnd('/'))" $reprovisionCentralAdmin = $true } else @@ -527,24 +528,26 @@ function Set-TargetResource if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` $params.CentralAdministrationPort -ne $secureBindings[0].Port) { + Write-Verbose -Message "Re-provisioning CA because $(([System.Uri]$params.CentralAdministrationUrl).Host) does not equal $($secureBindings[0].HostHeader)" $reprovisionCentralAdmin = $true } } else { # secureBindings did not exist or did not contain a valid hostheader + Write-Verbose -Message "Re-provisioning CA because secureBindings does not exist or does not contain a valid host header" $reprovisionCentralAdmin = $true } } if ($reprovisionCentralAdmin) { - Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" + # Write-Verbose -Message "Removing Central Admin web application in order to reprovision it" Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" $webAppParams = @{ - Identity = $params.CentralAdministrationUrl + Identity = $centralAdminSite.Url Name = "SharePoint Central Administration v4" Zone = "Default" HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host @@ -839,7 +842,7 @@ function Set-TargetResource Write-Verbose -Message "Reprovisioning Central Admin with SSL" $webAppParams = @{ - Identity = $params.CentralAdministrationUrl + Identity = $centralAdminSite.Url Name = "SharePoint Central Administration v4" Zone = "Default" HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host From dad64a1fa5f2976db117818668b03da1cb3ef698 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 28 Feb 2019 15:08:57 -0500 Subject: [PATCH 18/53] Trim URL for comparison --- Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 8ce165a7d..b975b721b 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -237,7 +237,7 @@ function Get-TargetResource Passphrase = $null AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name RunCentralAdmin = $centralAdminProvisioned - CentralAdministrationUrl = $centralAdminSite.Url + CentralAdministrationUrl = $centralAdminSite.Url.TrimEnd('/') CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port CentralAdministrationAuth = $centralAdminAuth DeveloperDashboard = $developerDashboardStatus From 5c7273e089138a4125fe282dbadc00c2242ebd87 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 28 Mar 2019 14:36:33 -0400 Subject: [PATCH 19/53] Fix bug when empty CA URL is passed --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index b975b721b..f6fd24840 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -39,7 +39,6 @@ function Get-TargetResource $RunCentralAdmin, [Parameter()] - [ValidateNotNullOrEmpty()] [System.String] $CentralAdministrationUrl, @@ -355,7 +354,6 @@ function Set-TargetResource $RunCentralAdmin, [Parameter()] - [ValidateNotNullOrEmpty()] [System.String] $CentralAdministrationUrl, @@ -402,6 +400,13 @@ function Set-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters + # If CentralAdministrationUrl is passed but IsNullOrEmpty, remove it from the $PSBoundParameters hashtable + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl") -and ` + [string]::IsNullOrEmpty($CentralAdministrationUrl)) + { + $PSBoundParameters.Remove("CentralAdministrationUrl") | Out-Null + } + # Set default values to ensure they are passed to Invoke-SPDSCCommand if (-not $PSBoundParameters.ContainsKey("CentralAdministrationPort")) { @@ -952,7 +957,6 @@ function Test-TargetResource $RunCentralAdmin, [Parameter()] - [ValidateNotNullOrEmpty()] [System.String] $CentralAdministrationUrl, @@ -991,6 +995,13 @@ function Test-TargetResource Write-Verbose -Message "Testing local SP Farm settings" + # If CentralAdministrationUrl is passed but IsNullOrEmpty, remove it from the $PSBoundParameters hashtable + if ($PSBoundParameters.ContainsKey("CentralAdministrationUrl") -and ` + [string]::IsNullOrEmpty($CentralAdministrationUrl)) + { + $PSBoundParameters.Remove("CentralAdministrationUrl") | Out-Null + } + $PSBoundParameters.Ensure = $Ensure $CurrentValues = Get-TargetResource @PSBoundParameters From 81e5d4f75ceeb88e2fe2c4455b55bae0eb5b6aa5 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 2 Apr 2019 13:52:05 -0400 Subject: [PATCH 20/53] Adding comment for future reference --- Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index f6fd24840..8cf278e71 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -842,6 +842,8 @@ function Set-TargetResource $_.IsAdministrationWebApplication -eq $true } + # Wondering if -DeleteIisSite is necessary. Does this add more risk of ending up in + # a state without CA or a way to recover it? Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite Write-Verbose -Message "Reprovisioning Central Admin with SSL" From 7a617c1b21e7d5d584febadbc90d36f6ae8e6fbd Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Tue, 2 Apr 2019 14:16:15 -0400 Subject: [PATCH 21/53] Update CHANGELOG, Readme, and Example --- CHANGELOG.md | 1 + .../DSCResources/MSFT_SPFarm/Readme.md | 21 ++++--- .../Examples/Small Farm/SharePoint.SSL.ps1 | 58 ++++++++----------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d2fc3e6d..245e85c3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ the farm was not yet created * Fixed issue where an error was thrown when no DeveloperDashboard parameter was specfied + * Add support to provision Central Administration on HTTPS * SPInstall * Added check to unblock setup file if it is blocked because it is coming from a network location. This to prevent endless wait diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md index 62148d5cb..b3c7cb30f 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md @@ -22,18 +22,25 @@ credential is ignored, only the value of the password is used as the farm passphrase. 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. 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 default behavior of SharePoint). This means you -need to use SPDistributedCacheService on at least one server in the farm to -designate it as a cache server. +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. +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 +default behavior of SharePoint). This means you need to use +SPDistributedCacheService on at least one server in the farm to designate it +as a cache server. CentralAdministrationAuth can be specified as "NTLM" or "KERBEROS". If not specified, it defaults to NTLM. If using Kerberos, make sure to have appropriate SPNs setup for Farm account and Central Administration URI. +To provision Central Admin as an SSL web application, specify a value for +the CentralAdministrationUrl property that begins with https:// followed +by the vanity host name or server name you wish to use to access CA. +(e.g. https://admin.sharepoint.contoso.com). + DeveloperDashboard can be specified as "On", "Off" and (only when using SharePoint 2013) to "OnDemand". diff --git a/Modules/SharePointDsc/Examples/Small Farm/SharePoint.SSL.ps1 b/Modules/SharePointDsc/Examples/Small Farm/SharePoint.SSL.ps1 index 5a2851fbc..f5e3be1e3 100644 --- a/Modules/SharePointDsc/Examples/Small Farm/SharePoint.SSL.ps1 +++ b/Modules/SharePointDsc/Examples/Small Farm/SharePoint.SSL.ps1 @@ -65,10 +65,34 @@ Configuration Example FarmAccount = $FarmAccount PsDscRunAsCredential = $SPSetupAccount AdminContentDatabaseName = "SP_AdminContent" - CentralAdministrationPort = 9999 + CentralAdministrationUrl = "https://admin.contoso.com" + CentralAdministrationPort = 443 RunCentralAdmin = $true DependsOn = "[SPInstall]InstallSharePoint" } + + #********************************************************** + # Now set up binding Central Admin + #********************************************************** + xWebsite SslWebAppCentralAdmin + { + Ensure = 'Present' + Name = 'SharePoint Central Administration v4' + BindingInfo = @( + MSFT_xWebBindingInformation + { + Protocol = 'https' + IPAddress = '*' + Port = '443' + CertificateThumbprint = '' + CertificateStoreName = 'My' + HostName = 'admin.contoso.com' + SslFlags = 1 + } + ) + DependsOn = '[SPFarm]CreateSPFarm' + } + SPManagedAccount ServicePoolManagedAccount { AccountName = $ServicePoolManagedAccount.UserName @@ -200,38 +224,6 @@ Configuration Example DependsOn = "[SPWebApplication]SharePointSites" } - #********************************************************** - # Now set up binding and AAM for Central Admin - #********************************************************** - xWebsite SslWebAppCentralAdmin - { - Ensure = 'Present' - Name = 'SharePoint Central Administration v4' - BindingInfo = @( - MSFT_xWebBindingInformation - { - Protocol = 'https' - IPAddress = '*' - Port = '443' - CertificateThumbprint = '' - CertificateStoreName = 'My' - HostName = 'admin.contoso.com' - SslFlags = 1 - } - ) - DependsOn = '[xWebsite]SslWebAppSharePointSites' - } - - # Change AAM for Central Admin - SPAlternateUrl CentralAdminAam - { - WebAppName = "SharePoint Central Administration v4" - Zone = "Default" - Url = 'https://admin.contoso.com' - Ensure = "Present" - PsDscRunAsCredential = $SPSetupAccount - DependsOn = "[xWebsite]SslWebAppCentralAdmin" - } #********************************************************** From 331b9952fdff57a6a532617837e903c885176750 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 3 Apr 2019 08:20:23 +0200 Subject: [PATCH 22/53] Updated version number in appveyor.yml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index ade4050ab..91d0a738b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.1.0.{build} +version: 3.4.0.{build} install: From 42468b41049f43aedf2612ff32c10acd23d77b13 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Wed, 3 Apr 2019 22:27:17 -0400 Subject: [PATCH 23/53] Moving CA update to new unreleased section --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 245e85c3a..bc702a12d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log for SharePointDsc +## REALLY Unreleased + +* SPFarm + * Add support to provision Central Administration on HTTPS + ## Unreleased * SharePointDsc generic @@ -14,7 +19,6 @@ the farm was not yet created * Fixed issue where an error was thrown when no DeveloperDashboard parameter was specfied - * Add support to provision Central Administration on HTTPS * SPInstall * Added check to unblock setup file if it is blocked because it is coming from a network location. This to prevent endless wait From 9ebc00b4a50b9fafe7d8b67a318f6abcf0105df7 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 4 Apr 2019 10:41:44 -0400 Subject: [PATCH 24/53] rolling back changelog to prepare for merge --- CHANGELOG.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc702a12d..245e85c3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,5 @@ # Change log for SharePointDsc -## REALLY Unreleased - -* SPFarm - * Add support to provision Central Administration on HTTPS - ## Unreleased * SharePointDsc generic @@ -19,6 +14,7 @@ the farm was not yet created * Fixed issue where an error was thrown when no DeveloperDashboard parameter was specfied + * Add support to provision Central Administration on HTTPS * SPInstall * Added check to unblock setup file if it is blocked because it is coming from a network location. This to prevent endless wait From a70f821b7c30ac4c2dcc6a7145103fc9b03f743f Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 4 Apr 2019 10:52:22 -0400 Subject: [PATCH 25/53] Move CA HTTPS to Unreleased section --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8edf60c9..76e60bffd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log for SharePointDsc +## Unreleased + +* SPFarm + * Add support to provision Central Administration on HTTPS + ## v3.3 * SharePointDsc generic @@ -18,7 +23,6 @@ the farm was not yet created * Fixed issue where an error was thrown when no DeveloperDashboard parameter was specfied - * Add support to provision Central Administration on HTTPS * SPInstall * Added check to unblock setup file if it is blocked because it is coming from a network location. This to prevent endless wait From b2faaa18bf5de455213bf331e3bc9dbb5ab9cdc5 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 4 Apr 2019 11:04:39 -0400 Subject: [PATCH 26/53] Remove unused commented code --- .../SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 8cf278e71..c359b2ba2 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -422,12 +422,6 @@ function Set-TargetResource } } - # if we're not passing Ssl Host Header in, let's set it to $null for comparison to Current Values - # if (-not $PSBoundParameters.ContainsKey("CentralAdministrationSslHostHeader")) - # { - # $CentralAdministrationSslHostHeader = $null - # } - if (-not $PSBoundParameters.ContainsKey("CentralAdministrationAuth")) { $PSBoundParameters.Add("CentralAdministrationAuth", "NTLM") From a84ac2980df6c0e2d139c6a1f97de808577a6964 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Mon, 8 Apr 2019 15:31:38 -0400 Subject: [PATCH 27/53] Fix for CA using SSL and non-default port --- .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index c359b2ba2..5b6a92eb6 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -510,9 +510,12 @@ function Set-TargetResource $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { $_.IsAdministrationWebApplication } - if ($centralAdminSite.Url.TrimEnd('/') -ne $params.CentralAdministrationUrl.TrimEnd('/')) + + $desiredUri = [System.Uri]("{0}:{1}" -f $params.CentralAdministrationUrl.TrimEnd('/'), $params.CentralAdministrationPort) + $currentUri = [System.Uri]$centralAdminSite.Url + if ($desiredUri.AbsoluteUri -ne $currentUri.AbsoluteUri) { - Write-Verbose -Message "Re-provisioning CA because $($centralAdminSite.Url.TrimEnd('/')) does not equal $($params.CentralAdministrationUrl.TrimEnd('/'))" + Write-Verbose -Message "Re-provisioning CA because $($currentUri.AbsoluteUri) does not equal $($desiredUri.AbsoluteUri)" $reprovisionCentralAdmin = $true } else @@ -524,10 +527,10 @@ function Set-TargetResource if ($null -ne $secureBindings[0] -and (-not [string]::IsNullOrEmpty($secureBindings[0].HostHeader))) { # check to see if secureBindings host header and port match what we want them to be - if (([System.Uri]$params.CentralAdministrationUrl).Host -ne $secureBindings[0].HostHeader -or ` - $params.CentralAdministrationPort -ne $secureBindings[0].Port) + if ($desiredUri.Host -ne $secureBindings[0].HostHeader -or ` + $desiredUri.Port -ne $secureBindings[0].Port) { - Write-Verbose -Message "Re-provisioning CA because $(([System.Uri]$params.CentralAdministrationUrl).Host) does not equal $($secureBindings[0].HostHeader)" + Write-Verbose -Message "Re-provisioning CA because $($desiredUri.Host) does not equal $($secureBindings[0].HostHeader) or $($desiredUri.Port) does not equal $($secureBindings[0].Port)" $reprovisionCentralAdmin = $true } } @@ -549,8 +552,8 @@ function Set-TargetResource Identity = $centralAdminSite.Url Name = "SharePoint Central Administration v4" Zone = "Default" - HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host - Port = $params.CentralAdministrationPort + HostHeader = $desiredUri.Host + Port = $desiredUri.Port AuthenticationMethod = $params.CentralAdministrationAuth SecureSocketsLayer = $true } From aacca98e3e501aa63a7811771184141bd70b358e Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Tue, 9 Apr 2019 12:49:39 +0200 Subject: [PATCH 28/53] Implemented Blocked file and UNC checks in SPInstallPrereqs --- CHANGELOG.md | 9 ++ .../MSFT_SPInstallPrereqs.psm1 | 54 +++++++++ .../SharePointDsc.SPInstallPrereqs.Tests.ps1 | 110 ++++++++++++++++++ 3 files changed, 173 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79df66828..186bc195f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change log for SharePointDsc +## Unreleased + +* SPInstallPrereqs + * Added check to unblock setup file if it is blocked because it is coming + from a network location. This to prevent endless wait + * Added ability to install from a UNC path, by adding server + to IE Local Intranet Zone. This will prevent an endless wait + caused by security warning + ## v3.3 * SharePointDsc generic diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 index 8568a4d69..d9afbd267 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 @@ -196,6 +196,19 @@ function Get-TargetResource Write-Verbose -Message "Getting installation status of SharePoint prerequisites" + if (-not(Test-Path -Path $InstallerPath)) + { + throw "PrerequisitesInstaller cannot be found: {$InstallerPath}" + } + + Write-Verbose -Message "Checking file status of $InstallerPath" + $zone = Get-Item $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` + "$InstallerPath' to unblock the file before continuing.") + } + $majorVersion = (Get-SPDSCAssemblyVersion -PathToAssembly $InstallerPath) $buildVersion = (Get-SPDSCBuildVersion -PathToAssembly $InstallerPath) if ($majorVersion -eq 15) @@ -560,6 +573,19 @@ function Set-TargetResource "prerequisites. Please remove this manually.") } + if (-not(Test-Path -Path $InstallerPath)) + { + throw "PrerequisitesInstaller cannot be found: {$InstallerPath}" + } + + Write-Verbose -Message "Checking file status of $InstallerPath" + $zone = Get-Item $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` + "$InstallerPath' to unblock the file before continuing.") + } + Write-Verbose -Message "Detecting SharePoint version from binaries" $majorVersion = Get-SPDSCAssemblyVersion -PathToAssembly $InstallerPath $buildVersion = Get-SPDSCBuildVersion -PathToAssembly $InstallerPath @@ -752,10 +778,38 @@ function Set-TargetResource } } + Write-Verbose -Message "Checking if Path is an UNC path" + $uncInstall = $false + if ($InstallerPath.StartsWith("\\")) + { + Write-Verbose -Message ("Specified InstallerPath is an UNC path. Adding servername to Local " + + "Intranet Zone") + + $uncInstall = $true + + if ($InstallerPath -match "\\\\(.*?)\\.*") + { + $serverName = $Matches[1] + } + else + { + throw "Cannot extract servername from UNC path. Check if it is in the correct format." + } + + Set-SPDscZoneMap -Server $serverName + } + + Write-Verbose -Message "Calling the SharePoint Pre-req installer" Write-Verbose -Message "Args for prereq installer are: $prereqArgs" $process = Start-Process -FilePath $InstallerPath -ArgumentList $prereqArgs -Wait -PassThru + if ($uncInstall -eq $true) + { + Write-Verbose -Message "Removing added path from the Local Intranet Zone" + Remove-SPDscZoneMap -ServerName $serverName + } + switch ($process.ExitCode) { 0 diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 index 53bbe5e2e..a8cdeda7c 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 @@ -477,6 +477,66 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } + Context -Name "Prerequisites are not installed but should be and are to be installed in offline mode with UNC path specified" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + InstallerPath = "\\server\SPInstall\Prerequisiteinstaller.exe" + OnlineMode = $false + Ensure = "Present" + } + + Mock -CommandName Get-ItemProperty -MockWith { + return @() + } -ParameterFilter { $null -ne $Path } + + Mock -CommandName Get-Item -MockWith { + return $null + } -ParameterFilter { $Path.StartsWith("\\") } + + Mock -CommandName Start-Process -MockWith { + return @{ + ExitCode = 0 + } + } + Mock -CommandName Test-Path -MockWith { + return $true + } + + It "Should throw an exception in the set method if required parameters are not set" { + {Set-TargetResource @testParams} | Should Throw + } + + switch ($Global:SPDscHelper.CurrentStubBuildNumber.Major) + { + 15 { + $requiredParams = @("SQLNCli","PowerShell","NETFX","IDFX","Sync","AppFabric","IDFX11","MSIPCClient","WCFDataServices","KB2671763","WCFDataServices56") + } + 16 { + if ($Global:SPDscHelper.CurrentStubBuildNumber.Build -lt 10000) + { + # SharePoint 2016 + $requiredParams = @("SQLNCli","Sync","AppFabric","IDFX11","MSIPCClient","KB3092423","WCFDataServices56","DotNetFx","MSVCRT11","MSVCRT14","ODBC") + } + else + { + # SharePoint 2019 + $requiredParams = @("SQLNCli","Sync","AppFabric","IDFX11","MSIPCClient","KB3092423","WCFDataServices56","DotNet472","MSVCRT11","MSVCRT141") + } + } + Default { + throw [Exception] "A supported version of SharePoint was not used in testing" + } + } + + $requiredParams | ForEach-Object -Process { + $testParams.Add($_, "C:\fake\value.exe") + } + + It "does not throw an exception where the required parameters are included" { + {Set-TargetResource @testParams} | Should Not Throw + } + } + Context -Name "Prerequisites are not installed but should be and are to be installed in offline mode, but invalid paths have been passed" -Fixture { $testParams = @{ IsSingleInstance = "Yes" @@ -740,6 +800,56 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } } + + Context -Name "InstallerPath does not exist" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + InstallerPath = "C:\SPInstall\Prerequisiteinstaller.exe" + OnlineMode = $true + Ensure = "Present" + } + + Mock -CommandName Test-Path { + return $false + } + + It "throws an error in the get method" { + { Get-TargetResource @testParams } | Should Throw ("PrerequisitesInstaller cannot be found") + } + + It "throws an error in the set method" { + { Set-TargetResource @testParams } | Should Throw ("PrerequisitesInstaller cannot be found") + } + + It "throws an error in the test method" { + { Test-TargetResource @testParams } | Should Throw ("PrerequisitesInstaller cannot be found") + } + } + + Context -Name "InstallerPath is blocked" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + InstallerPath = "C:\SPInstall\Prerequisiteinstaller.exe" + OnlineMode = $true + Ensure = "Present" + } + + Mock -CommandName Get-Item { + return "data" + } + + It "throws an error in the get method" { + { Get-TargetResource @testParams } | Should Throw ("PrerequisitesInstaller is blocked!") + } + + It "throws an error in the set method" { + { Set-TargetResource @testParams } | Should Throw ("PrerequisitesInstaller is blocked!") + } + + It "throws an error in the test method" { + { Test-TargetResource @testParams } | Should Throw ("PrerequisitesInstaller is blocked!") + } + } } } From e94bf7223b8bb4c427f3168ef2c05a2f9f08b2b7 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Tue, 9 Apr 2019 15:52:48 +0200 Subject: [PATCH 29/53] Fixed issue in SPManagedMetadataServiceApp --- CHANGELOG.md | 3 +++ .../MSFT_SPManagedMetaDataServiceApp.psm1 | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 186bc195f..8589607ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ * Added ability to install from a UNC path, by adding server to IE Local Intranet Zone. This will prevent an endless wait caused by security warning +* SPManagedMetadataServiceApp + * Fixed issue where Get-TargetResource method throws an error when the + service app proxy does not exist and no proxy name is specified. ## v3.3 diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPManagedMetadataServiceApp/MSFT_SPManagedMetaDataServiceApp.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPManagedMetadataServiceApp/MSFT_SPManagedMetaDataServiceApp.psm1 index eb75440ec..58f3ecb68 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPManagedMetadataServiceApp/MSFT_SPManagedMetaDataServiceApp.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPManagedMetadataServiceApp/MSFT_SPManagedMetaDataServiceApp.psm1 @@ -91,7 +91,14 @@ function Get-TargetResource { $serviceAppProxies = Get-SPServiceApplicationProxy -ErrorAction SilentlyContinue - $proxyName = $params.ProxyName + if ($params.ContainsKey("ProxyName") -eq $true) + { + $proxyName = $params.ProxyName + } + else + { + $proxyName = "" + } if ($null -ne $serviceAppProxies) { From 5aff4b975f64678c4311c895cb1de6cc3231a8c6 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Tue, 9 Apr 2019 21:24:58 +0200 Subject: [PATCH 30/53] Added check for missing proxy in SPSubscriptionSettingsSA --- CHANGELOG.md | 3 + ...MSFT_SPSubscriptionSettingsServiceApp.psm1 | 168 ++++++++++----- ...PSubscriptionSettingsServiceApp.Tests.ps1} | 200 +++++++++++++----- 3 files changed, 259 insertions(+), 112 deletions(-) rename Tests/Unit/SharePointDsc/{SharePointDsc.SPSubscriptionSettings.Tests.ps1 => SharePointDsc.SPSubscriptionSettingsServiceApp.Tests.ps1} (72%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8589607ba..d35221fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ * SPManagedMetadataServiceApp * Fixed issue where Get-TargetResource method throws an error when the service app proxy does not exist and no proxy name is specified. +* SPSubscriptionSettingsServiceApp + * Fixed issue where the service app proxy isn't created when it wasn't + created during initial deployment. ## v3.3 diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPSubscriptionSettingsServiceApp/MSFT_SPSubscriptionSettingsServiceApp.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPSubscriptionSettingsServiceApp/MSFT_SPSubscriptionSettingsServiceApp.psm1 index 4b6405d5c..b4e9c80ea 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPSubscriptionSettingsServiceApp/MSFT_SPSubscriptionSettingsServiceApp.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPSubscriptionSettingsServiceApp/MSFT_SPSubscriptionSettingsServiceApp.psm1 @@ -4,29 +4,29 @@ function Get-TargetResource [OutputType([System.Collections.Hashtable])] param ( - [Parameter(Mandatory = $true)] - [System.String] + [Parameter(Mandatory = $true)] + [System.String] $Name, - [Parameter(Mandatory = $true)] - [System.String] + [Parameter(Mandatory = $true)] + [System.String] $ApplicationPool, [Parameter()] - [System.String] + [System.String] $DatabaseName, [Parameter()] - [System.String] + [System.String] $DatabaseServer, [Parameter()] - [ValidateSet("Present","Absent")] - [System.String] + [ValidateSet("Present","Absent")] + [System.String] $Ensure = "Present", [Parameter()] - [System.Management.Automation.PSCredential] + [System.Management.Automation.PSCredential] $InstallAccount ) @@ -36,16 +36,16 @@ function Get-TargetResource -Arguments $PSBoundParameters ` -ScriptBlock { $params = $args[0] - + $serviceApps = Get-SPServiceApplication -Name $params.Name ` - -ErrorAction SilentlyContinue + -ErrorAction SilentlyContinue $nullReturn = @{ Name = $params.Name ApplicationPool = $params.ApplicationPool Ensure = "Absent" } - if ($null -eq $serviceApps) + if ($null -eq $serviceApps) { return $nullReturn } @@ -53,11 +53,11 @@ function Get-TargetResource $_.GetType().FullName -eq "Microsoft.SharePoint.SPSubscriptionSettingsServiceApplication" } - if ($null -eq $serviceApp) + if ($null -eq $serviceApp) { return $nullReturn - } - else + } + else { $propertyFlags = [System.Reflection.BindingFlags]::Instance ` -bor [System.Reflection.BindingFlags]::NonPublic @@ -88,29 +88,29 @@ function Set-TargetResource [CmdletBinding()] param ( - [Parameter(Mandatory = $true)] - [System.String] + [Parameter(Mandatory = $true)] + [System.String] $Name, - [Parameter(Mandatory = $true)] - [System.String] + [Parameter(Mandatory = $true)] + [System.String] $ApplicationPool, [Parameter()] - [System.String] + [System.String] $DatabaseName, [Parameter()] - [System.String] + [System.String] $DatabaseServer, [Parameter()] - [ValidateSet("Present","Absent")] - [System.String] + [ValidateSet("Present","Absent")] + [System.String] $Ensure = "Present", [Parameter()] - [System.Management.Automation.PSCredential] + [System.Management.Automation.PSCredential] $InstallAccount ) @@ -118,33 +118,63 @@ function Set-TargetResource $result = Get-TargetResource @PSBoundParameters - if ($result.Ensure -eq "Absent" -and $Ensure -eq "Present") + if ($result.Ensure -eq "Absent" -and $Ensure -eq "Present") { Write-Verbose -Message "Creating Subscription Settings Service Application $Name" Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { $params = $args[0] - + $newParams = @{ - Name = $params.Name + Name = $params.Name ApplicationPool = $params.ApplicationPool } - if ($params.ContainsKey("DatabaseName") -eq $true) + if ($params.ContainsKey("DatabaseName") -eq $true) { - $newParams.Add("DatabaseName", $params.DatabaseName) + $newParams.Add("DatabaseName", $params.DatabaseName) } - if ($params.ContainsKey("DatabaseServer") -eq $true) + if ($params.ContainsKey("DatabaseServer") -eq $true) { - $newParams.Add("DatabaseServer", $params.DatabaseServer) + $newParams.Add("DatabaseServer", $params.DatabaseServer) } $serviceApp = New-SPSubscriptionSettingsServiceApplication @newParams - New-SPSubscriptionSettingsServiceApplicationProxy -ServiceApplication $serviceApp | Out-Null + New-SPSubscriptionSettingsServiceApplicationProxy -ServiceApplication $serviceApp | Out-Null } } - if ($result.Ensure -eq "Present" -and $Ensure -eq "Present") + if ($result.Ensure -eq "Present" -and $Ensure -eq "Present") { - if ($ApplicationPool -ne $result.ApplicationPool) + Write-Verbose -Message "Checking proxy for Subscription Settings Service Application $Name" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + $serviceApp = Get-SPServiceApplication -Name $params.Name ` + -ErrorAction SilentlyContinue + + $serviceAppProxies = Get-SPServiceApplicationProxy -ErrorAction SilentlyContinue + + if ($null -ne $serviceAppProxies) + { + # Checking if one of the proxies is connected to the service app + $serviceAppProxy = $serviceAppProxies | Where-Object -FilterScript { + $serviceApp.IsConnected($_) + } + if ($null -eq $serviceAppProxy) + { + # No proxy connected, create new proxy + New-SPSubscriptionSettingsServiceApplicationProxy -ServiceApplication $serviceApp | Out-Null + } + } + else + { + # No proxies exist in the environment, create new proxy + New-SPSubscriptionSettingsServiceApplicationProxy -ServiceApplication $serviceApp | Out-Null + } + } + + if ($ApplicationPool -ne $result.ApplicationPool) { Write-Verbose -Message "Updating Subscription Settings Service Application $Name" Invoke-SPDSCCommand -Credential $InstallAccount ` @@ -155,24 +185,24 @@ function Set-TargetResource $appPool = Get-SPServiceApplicationPool -Identity $params.ApplicationPool $service = Get-SPServiceApplication -Name $params.Name ` | Where-Object -FilterScript { - $_.GetType().FullName -eq "Microsoft.SharePoint.SPSubscriptionSettingsServiceApplication" - } + $_.GetType().FullName -eq "Microsoft.SharePoint.SPSubscriptionSettingsServiceApplication" + } $service.ApplicationPool = $appPool $service.Update() } } } - if ($Ensure -eq "Absent") + if ($Ensure -eq "Absent") { Write-Verbose -Message "Removing Subscription Settings Service Application $Name" Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { $params = $args[0] - + $service = Get-SPServiceApplication -Name $params.Name ` | Where-Object -FilterScript { - $_.GetType().FullName -eq "Microsoft.SharePoint.SPSubscriptionSettingsServiceApplication" + $_.GetType().FullName -eq "Microsoft.SharePoint.SPSubscriptionSettingsServiceApplication" } Remove-SPServiceApplication $service -Confirm:$false } @@ -185,45 +215,75 @@ function Test-TargetResource [OutputType([System.Boolean])] param ( - [Parameter(Mandatory = $true)] - [System.String] + [Parameter(Mandatory = $true)] + [System.String] $Name, - [Parameter(Mandatory = $true)] - [System.String] + [Parameter(Mandatory = $true)] + [System.String] $ApplicationPool, [Parameter()] - [System.String] + [System.String] $DatabaseName, [Parameter()] - [System.String] + [System.String] $DatabaseServer, [Parameter()] - [ValidateSet("Present","Absent")] - [System.String] + [ValidateSet("Present","Absent")] + [System.String] $Ensure = "Present", [Parameter()] - [System.Management.Automation.PSCredential] + [System.Management.Automation.PSCredential] $InstallAccount ) - + Write-Verbose -Message "Testing Subscription Settings Service '$Name'" $PSBoundParameters.Ensure = $Ensure - + $CurrentValues = Get-TargetResource @PSBoundParameters - if ($Ensure -eq "Present") + if ($Ensure -eq "Present") { + if ($CurrentValues.Ensure -eq "Present") + { + $result = Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + $serviceApp = Get-SPServiceApplication -Name $params.Name ` + -ErrorAction SilentlyContinue + + $serviceAppProxies = Get-SPServiceApplicationProxy -ErrorAction SilentlyContinue + + if ($null -ne $serviceAppProxies) + { + $serviceAppProxy = $serviceAppProxies | Where-Object -FilterScript { + $serviceApp.IsConnected($_) + } + if ($null -eq $serviceAppProxy) + { + return $false + } + } + } + + if ($result -eq $false) + { + return $false + } + } + return Test-SPDscParameterState -CurrentValues $CurrentValues ` -DesiredValues $PSBoundParameters ` - -ValuesToCheck @("ApplicationPool", "Ensure") - } - else + -ValuesToCheck @("ApplicationPool", "Ensure") + } + else { return Test-SPDscParameterState -CurrentValues $CurrentValues ` -DesiredValues $PSBoundParameters ` diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPSubscriptionSettings.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPSubscriptionSettingsServiceApp.Tests.ps1 similarity index 72% rename from Tests/Unit/SharePointDsc/SharePointDsc.SPSubscriptionSettings.Tests.ps1 rename to Tests/Unit/SharePointDsc/SharePointDsc.SPSubscriptionSettingsServiceApp.Tests.ps1 index 0c577f3d1..1fa6678ff 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPSubscriptionSettings.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPSubscriptionSettingsServiceApp.Tests.ps1 @@ -1,7 +1,7 @@ [CmdletBinding()] param( [Parameter()] - [string] + [string] $SharePointCmdletModule = (Join-Path -Path $PSScriptRoot ` -ChildPath "..\Stubs\SharePoint\15.0.4805.1000\Microsoft.SharePoint.PowerShell.psm1" ` -Resolve) @@ -21,11 +21,11 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { # Initialize tests $getTypeFullName = "Microsoft.SharePoint.SPSubscriptionSettingsServiceApplication" - # Mocks for all contexts + # Mocks for all contexts Mock -CommandName New-SPSubscriptionSettingsServiceApplication -MockWith { - return @{} + return @{} } - Mock -CommandName New-SPSubscriptionSettingsServiceApplicationProxy -MockWith { + Mock -CommandName New-SPSubscriptionSettingsServiceApplicationProxy -MockWith { return @{} } Mock -CommandName Set-SPSubscriptionSettingsServiceApplication -MockWith { } @@ -41,20 +41,20 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure = "Present" } - Mock -CommandName Get-SPServiceApplication -MockWith { - return $null + Mock -CommandName Get-SPServiceApplication -MockWith { + return $null } - - Mock -CommandName New-SPSubscriptionSettingsServiceApplication -MockWith { + + Mock -CommandName New-SPSubscriptionSettingsServiceApplication -MockWith { return @{} } - - Mock -CommandName New-SPSubscriptionSettingsServiceApplicationProxy -MockWith { + + Mock -CommandName New-SPSubscriptionSettingsServiceApplicationProxy -MockWith { return @{} } - + It "Should return absent from the Get method" { - (Get-TargetResource @testParams).Ensure | Should Be "Absent" + (Get-TargetResource @testParams).Ensure | Should Be "Absent" } It "Should return false when the Test method is called" { @@ -77,22 +77,106 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure = "Present" } - Mock -CommandName Get-SPServiceApplication -MockWith { - $spServiceApp = [PSCustomObject]@{ - DisplayName = $testParams.Name - } + Mock -CommandName Get-SPServiceApplication -MockWith { + $spServiceApp = [PSCustomObject]@{ + DisplayName = $testParams.Name + } $spServiceApp | Add-Member -MemberType ScriptMethod ` -Name GetType ` - -Value { - return @{ - FullName = "Microsoft.Office.UnKnownWebServiceApplication" - } - } -PassThru -Force - return $spServiceApp + -Value { + return @{ + FullName = "Microsoft.Office.UnKnownWebServiceApplication" + } + } -PassThru -Force + return $spServiceApp } It "Should return absent from the Get method" { - (Get-TargetResource @testParams).Ensure | Should Be "Absent" + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + } + } + + Context -Name "When the service application exist in the current farm but has no proxy" -Fixture { + $testParams = @{ + Name = "Test App" + ApplicationPool = "Test App Pool" + DatabaseName = "Test_DB" + DatabaseServer = "TestServer\Instance" + Ensure = "Present" + } + + Mock -CommandName Get-SPServiceApplication -MockWith { + $spServiceApp = [PSCustomObject]@{ + TypeName = "Microsoft SharePoint Foundation Subscription Settings Service Application" + DisplayName = $testParams.Name + ApplicationPool = @{ + Name = $testParams.ApplicationPool + } + } + + $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod -Name GetType -Value { + New-Object -TypeName "Object" | + Add-Member -MemberType NoteProperty ` + -Name FullName ` + -Value $getTypeFullName ` + -PassThru | + Add-Member -MemberType ScriptMethod ` + -Name GetProperties ` + -Value { + param($x) + return @( + (New-Object -TypeName "Object" | + Add-Member -MemberType NoteProperty ` + -Name Name ` + -Value "Database" ` + -PassThru | + Add-Member -MemberType ScriptMethod ` + -Name GetValue ` + -Value { + param($x) + return (@{ + FullName = $getTypeFullName + Name = "Test_DB" + NormalizedDataSource = "TestServer\Instance" + FailoverServer = @{ + Name = "DBServer_Failover" + } + }) + } -PassThru + ) + ) + } -PassThru + } -PassThru -Force + + $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod ` + -Name IsConnected ` + -Value { + param($x) + return $false + } -PassThru -Force + + return $spServiceApp + } + + Mock -CommandName Get-SPServiceApplicationProxy -MockWith { + return @( + @{ + Name = "Managed Metadata Service Application Proxy" + } + ) + } + + It "Should return Present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should create the proxy in the Set method" { + Set-TargetResource @testParams + Assert-MockCalled New-SPSubscriptionSettingsServiceApplicationProxy + } + + It "Should return false from the Test method" { + Test-TargetResource @testParams | Should Be $false } } @@ -105,21 +189,21 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure = "Present" } - Mock -CommandName Get-SPServiceApplication -MockWith { + Mock -CommandName Get-SPServiceApplication -MockWith { $spServiceApp = [PSCustomObject]@{ TypeName = "Microsoft SharePoint Foundation Subscription Settings Service Application" DisplayName = $testParams.Name - ApplicationPool = @{ - Name = $testParams.ApplicationPool + ApplicationPool = @{ + Name = $testParams.ApplicationPool } } - $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod -Name GetType -Value { + $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod -Name GetType -Value { New-Object -TypeName "Object" | Add-Member -MemberType NoteProperty ` -Name FullName ` -Value $getTypeFullName ` - -PassThru | + -PassThru | Add-Member -MemberType ScriptMethod ` -Name GetProperties ` -Value { @@ -134,7 +218,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { -Name GetValue ` -Value { param($x) - return (@{ + return (@{ FullName = $getTypeFullName Name = "Test_DB" NormalizedDataSource = "TestServer\Instance" @@ -152,7 +236,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } It "Should return present from the get method" { - (Get-TargetResource @testParams).Ensure | Should Be "Present" + (Get-TargetResource @testParams).Ensure | Should Be "Present" } It "Should return true when the Test method is called" { @@ -168,7 +252,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { DatabaseServer = "TestServer\Instance" Ensure = "Present" } - + Mock -CommandName Get-SPServiceApplication -MockWith { $spServiceApp = [pscustomobject]@{ TypeName = "Microsoft SharePoint Foundation Subscription Settings Service Application" @@ -179,14 +263,14 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { -Name Update ` -Value { $Global:SPDscSubscriptionServiceUpdateCalled = $true - } -PassThru + } -PassThru - $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod -Name GetType -Value { + $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod -Name GetType -Value { New-Object -TypeName "Object" | Add-Member -MemberType NoteProperty ` -Name FullName ` -Value $getTypeFullName ` - -PassThru | + -PassThru | Add-Member -MemberType ScriptMethod ` -Name GetProperties ` -Value { @@ -201,7 +285,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { -Name GetValue ` -Value { param($x) - return (@{ + return (@{ FullName = $getTypeFullName Name = "Test_DB" NormalizedDataSource = "TestServer\Instance" @@ -218,10 +302,10 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { return $spServiceApp } - Mock -CommandName Get-SPServiceApplicationPool { - return @{ - Name = $testParams.ApplicationPool - } + Mock -CommandName Get-SPServiceApplicationPool { + return @{ + Name = $testParams.ApplicationPool + } } It "Should return false when the Test method is called" { @@ -243,8 +327,8 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure = "Present" } - Mock -CommandName Get-SPServiceApplication -MockWith { - return $null + Mock -CommandName Get-SPServiceApplication -MockWith { + return $null } It "should not throw an exception in the set method" { @@ -253,7 +337,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Assert-MockCalled New-SPSubscriptionSettingsServiceApplicationProxy } } - + Context -Name "When the service app exists but it shouldn't" -Fixture { $testParams = @{ Name = "Test App" @@ -261,20 +345,20 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure = "Absent" } - Mock -CommandName Get-SPServiceApplication -MockWith { + Mock -CommandName Get-SPServiceApplication -MockWith { $spServiceApp = [PSCustomObject]@{ TypeName = "Microsoft SharePoint Foundation Subscription Settings Service Application" DisplayName = $testParams.Name - ApplicationPool = @{ - Name = $testParams.ApplicationPool + ApplicationPool = @{ + Name = $testParams.ApplicationPool } } - $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod -Name GetType -Value { + $spServiceApp = $spServiceApp | Add-Member -MemberType ScriptMethod -Name GetType -Value { New-Object -TypeName "Object" | Add-Member -MemberType NoteProperty ` -Name FullName ` -Value $getTypeFullName ` - -PassThru | + -PassThru | Add-Member -MemberType ScriptMethod ` -Name GetProperties ` -Value { @@ -289,7 +373,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { -Name GetValue ` -Value { param($x) - return (@{ + return (@{ FullName = $getTypeFullName Name = "Test_DB" NormalizedDataSource = "TestServer\Instance" @@ -304,21 +388,21 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } -PassThru -Force return $spServiceApp } - + It "Should return present from the Get method" { - (Get-TargetResource @testParams).Ensure | Should Be "Present" + (Get-TargetResource @testParams).Ensure | Should Be "Present" } - + It "Should return false from the test method" { Test-TargetResource @testParams | Should Be $false } - + It "Should remove the service application in the set method" { Set-TargetResource @testParams Assert-MockCalled Remove-SPServiceApplication } } - + Context -Name "When the service app doesn't exist and shouldn't" -Fixture { $testParams = @{ Name = "Test App" @@ -326,14 +410,14 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure = "Absent" } - Mock -CommandName Get-SPServiceApplication -MockWith { - return $null + Mock -CommandName Get-SPServiceApplication -MockWith { + return $null } - + It "Should return absent from the Get method" { - (Get-TargetResource @testParams).Ensure | Should Be "Absent" + (Get-TargetResource @testParams).Ensure | Should Be "Absent" } - + It "Should return false from the test method" { Test-TargetResource @testParams | Should Be $true } From 8437aed54bbc6a3975328726047dfe2b203f36a2 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 10 Apr 2019 09:09:47 +0200 Subject: [PATCH 31/53] Added new parameters to DCClientSettings and InfoPathConfig --- CHANGELOG.md | 4 + ...MSFT_SPDistributedCacheClientSettings.psm1 | 431 ++++++++++++++++-- ...PDistributedCacheClientSettings.schema.mof | 15 + .../MSFT_SPInfoPathFormsServiceConfig.psm1 | 20 + ...FT_SPInfoPathFormsServiceConfig.schema.mof | 1 + ...SPDistributedCacheClientSettings.Tests.ps1 | 99 +++- ...Dsc.SPInfoPathFormsServiceConfig.Tests.ps1 | 40 ++ 7 files changed, 570 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d35221fb7..792ffae5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* SPDistributedCacheClientSettings + * Added 15 new SharePoint 2016 parameters +* SPInfoPathFormsServiceConfig + * Added the AllowEventPropagation parameter * SPInstallPrereqs * Added check to unblock setup file if it is blocked because it is coming from a network location. This to prevent endless wait diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 index 800d7dd7f..dafa295dd 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 @@ -129,12 +129,101 @@ function Get-TargetResource [System.UInt32] $DSTACChannelOpenTimeOut, + [Parameter()] + [System.UInt32] + $DFLTCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DFLTCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DFLTCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DSWUCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DSWUCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DSWUCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DUGCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DUGCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DUGCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DRTCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DRTCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DRTCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DHSCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DHSCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DHSCChannelOpenTimeOut, + [Parameter()] [System.Management.Automation.PSCredential] $InstallAccount ) Write-Verbose -Message "Getting the Distributed Cache Client Settings" + $test = $PSBoundParameters + + if ($PSBoundParameters.ContainsKey("DFLTCMaxConnectionsToServer") -eq $true -or + $PSBoundParameters.ContainsKey("DFLTCRequestTimeout") -eq $true -or + $PSBoundParameters.ContainsKey("DFLTCChannelOpenTimeOut") -eq $true -or + $PSBoundParameters.ContainsKey("DSWUCMaxConnectionsToServer") -eq $true -or + $PSBoundParameters.ContainsKey("DSWUCRequestTimeout") -eq $true -or + $PSBoundParameters.ContainsKey("DSWUCChannelOpenTimeOut") -eq $true -or + $PSBoundParameters.ContainsKey("DUGCMaxConnectionsToServer") -eq $true -or + $PSBoundParameters.ContainsKey("DUGCRequestTimeout") -eq $true -or + $PSBoundParameters.ContainsKey("DUGCChannelOpenTimeOut") -eq $true -or + $PSBoundParameters.ContainsKey("DRTCMaxConnectionsToServer") -eq $true -or + $PSBoundParameters.ContainsKey("DRTCRequestTimeout") -eq $true -or + $PSBoundParameters.ContainsKey("DRTCChannelOpenTimeOut") -eq $true -or + $PSBoundParameters.ContainsKey("DHSCMaxConnectionsToServer") -eq $true -or + $PSBoundParameters.ContainsKey("DHSCRequestTimeout") -eq $true -or + $PSBoundParameters.ContainsKey("DHSCChannelOpenTimeOut") -eq $true) + { + $installedVersion = Get-SPDSCInstalledProductVersion + if ($installedVersion.FileMajorPart -eq 15) + { + throw ("The following parameters are only supported in SharePoint 2016 and above: " + ` + "DFLTCMaxConnectionsToServer, DFLTCRequestTimeout, DFLTCChannelOpenTimeOut, " + ` + "DSWUCMaxConnectionsToServer, DSWUCRequestTimeout, DSWUCChannelOpenTimeOut, " + ` + "DUGCMaxConnectionsToServer, DUGCRequestTimeout, DUGCChannelOpenTimeOut, " + ` + "DRTCMaxConnectionsToServer, DRTCRequestTimeout, DRTCChannelOpenTimeOut, " + ` + "DHSCMaxConnectionsToServer, DHSCRequestTimeout and DHSCChannelOpenTimeOut") + } + } $result = Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` @@ -173,7 +262,21 @@ function Get-TargetResource DSTACMaxConnectionsToServer = $null DSTACRequestTimeout = $null DSTACChannelOpenTimeOut = $null - InstallAccount = $params.InstallAccount + DFLTCMaxConnectionsToServer = $null + DFLTCRequestTimeout = $null + DFLTCChannelOpenTimeOut = $null + DSWUCMaxConnectionsToServer = $null + DSWUCRequestTimeout = $null + DSWUCChannelOpenTimeOut = $null + DUGCMaxConnectionsToServer = $null + DUGCRequestTimeout = $null + DUGCChannelOpenTimeOut = $null + DRTCMaxConnectionsToServer = $null + DRTCRequestTimeout = $null + DRTCChannelOpenTimeOut = $null + DHSCMaxConnectionsToServer = $null + DHSCRequestTimeout = $null + DHSCChannelOpenTimeOut = $null } try @@ -188,6 +291,11 @@ function Get-TargetResource $DSC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedSearchCache" $DTC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedSecurityTrimmingCache" $DSTAC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedServerToAppServerAccessTokenCache" + $DFLTC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedFileLockThrottlerCache" + $DSWUC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedSharedWithUserCache" + $DUGC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedUnifiedGroupsCache" + $DRTC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedResourceTallyCache" + $DHSC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedHealthScoreCache" $returnValue = @{ IsSingleInstance = "Yes" @@ -221,6 +329,21 @@ function Get-TargetResource DSTACMaxConnectionsToServer = $DSTAC.MaxConnectionsToServer DSTACRequestTimeout = $DSTAC.RequestTimeout DSTACChannelOpenTimeOut = $DSTAC.ChannelOpenTimeOut + DFLTCMaxConnectionsToServer = $DFLTC.MaxConnectionsToServer + DFLTCRequestTimeout = $DFLTC.RequestTimeout + DFLTCChannelOpenTimeOut = $DFLTC.ChannelOpenTimeOut + DSWUCMaxConnectionsToServer = $DSWUC.MaxConnectionsToServer + DSWUCRequestTimeout = $DSWUC.RequestTimeout + DSWUCChannelOpenTimeOut = $DSWUC.ChannelOpenTimeOut + DUGCMaxConnectionsToServer = $DUGC.MaxConnectionsToServer + DUGCRequestTimeout = $DUGC.RequestTimeout + DUGCChannelOpenTimeOut = $DUGC.ChannelOpenTimeOut + DRTCMaxConnectionsToServer = $DRTC.MaxConnectionsToServer + DRTCRequestTimeout = $DRTC.RequestTimeout + DRTCChannelOpenTimeOut = $DRTC.ChannelOpenTimeOut + DHSCMaxConnectionsToServer = $DHSC.MaxConnectionsToServer + DHSCRequestTimeout = $DHSC.RequestTimeout + DHSCChannelOpenTimeOut = $DHSC.ChannelOpenTimeOut InstallAccount = $params.InstallAccount } return $returnValue @@ -364,6 +487,66 @@ function Set-TargetResource [System.UInt32] $DSTACChannelOpenTimeOut = 3000, + [Parameter()] + [System.UInt32] + $DFLTCMaxConnectionsToServer = 1, + + [Parameter()] + [System.UInt32] + $DFLTCRequestTimeout = 3000, + + [Parameter()] + [System.UInt32] + $DFLTCChannelOpenTimeOut = 3000, + + [Parameter()] + [System.UInt32] + $DSWUCMaxConnectionsToServer = 1, + + [Parameter()] + [System.UInt32] + $DSWUCRequestTimeout = 3000, + + [Parameter()] + [System.UInt32] + $DSWUCChannelOpenTimeOut = 3000, + + [Parameter()] + [System.UInt32] + $DUGCMaxConnectionsToServer = 1, + + [Parameter()] + [System.UInt32] + $DUGCRequestTimeout = 3000, + + [Parameter()] + [System.UInt32] + $DUGCChannelOpenTimeOut = 3000, + + [Parameter()] + [System.UInt32] + $DRTCMaxConnectionsToServer = 1, + + [Parameter()] + [System.UInt32] + $DRTCRequestTimeout = 3000, + + [Parameter()] + [System.UInt32] + $DRTCChannelOpenTimeOut = 3000, + + [Parameter()] + [System.UInt32] + $DHSCMaxConnectionsToServer = 1, + + [Parameter()] + [System.UInt32] + $DHSCRequestTimeout = 3000, + + [Parameter()] + [System.UInt32] + $DHSCChannelOpenTimeOut = 3000, + [Parameter()] [System.Management.Automation.PSCredential] $InstallAccount @@ -371,6 +554,34 @@ function Set-TargetResource Write-Verbose -Message "Setting the Distributed Cache Client Settings" + if ($PSBoundParameters.ContainsKey("DFLTCMaxConnectionsToServer") -or + $PSBoundParameters.ContainsKey("DFLTCRequestTimeout") -or + $PSBoundParameters.ContainsKey("DFLTCChannelOpenTimeOut") -or + $PSBoundParameters.ContainsKey("DSWUCMaxConnectionsToServer") -or + $PSBoundParameters.ContainsKey("DSWUCRequestTimeout") -or + $PSBoundParameters.ContainsKey("DSWUCChannelOpenTimeOut") -or + $PSBoundParameters.ContainsKey("DUGCMaxConnectionsToServer") -or + $PSBoundParameters.ContainsKey("DUGCRequestTimeout") -or + $PSBoundParameters.ContainsKey("DUGCChannelOpenTimeOut") -or + $PSBoundParameters.ContainsKey("DRTCMaxConnectionsToServer") -or + $PSBoundParameters.ContainsKey("DRTCRequestTimeout") -or + $PSBoundParameters.ContainsKey("DRTCChannelOpenTimeOut") -or + $PSBoundParameters.ContainsKey("DHSCMaxConnectionsToServer") -or + $PSBoundParameters.ContainsKey("DHSCRequestTimeout") -or + $PSBoundParameters.ContainsKey("DHSCChannelOpenTimeOut")) + { + $installedVersion = Get-SPDSCInstalledProductVersion + if ($installedVersion.FileMajorPart -eq 15) + { + throw ("The following parameters are only supported in SharePoint 2016 and above: " + ` + "DFLTCMaxConnectionsToServer, DFLTCRequestTimeout, DFLTCChannelOpenTimeOut, " + ` + "DSWUCMaxConnectionsToServer, DSWUCRequestTimeout, DSWUCChannelOpenTimeOut, " + ` + "DUGCMaxConnectionsToServer, DUGCRequestTimeout, DUGCChannelOpenTimeOut, " + ` + "DRTCMaxConnectionsToServer, DRTCRequestTimeout, DRTCChannelOpenTimeOut, " + ` + "DHSCMaxConnectionsToServer, DHSCRequestTimeout and DHSCChannelOpenTimeOut") + } + } + Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { @@ -536,6 +747,91 @@ function Set-TargetResource $DSTAC.ChannelOpenTimeOut = $params.DSTACChannelOpenTimeOut } Set-SPDistributedCacheClientSetting -ContainerType "DistributedServerToAppServerAccessTokenCache" $DSTAC + + # The following parameters are only required on SharePoint 2016 and above + $installedVersion = Get-SPDSCInstalledProductVersion + if ($installedVersion.FileMajorPart -ne 15) + { + #DistributedFileLockThrottlerCache + $DFLTC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedFileLockThrottlerCache" + if($params.DFLTCMaxConnectionsToServer) + { + $DFLTC.MaxConnectionsToServer = $params.DFLTCMaxConnectionsToServer + } + if($params.DFLTCRequestTimeout) + { + $DFLTC.RequestTimeout = $params.DFLTCRequestTimeout + } + if($params.DFLTCChannelOpenTimeOut) + { + $DFLTC.ChannelOpenTimeOut = $params.DFLTCChannelOpenTimeOut + } + Set-SPDistributedCacheClientSetting -ContainerType "DistributedFileLockThrottlerCache" $DFLTC + + #DistributedSharedWithUserCache + $DSWUC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedSharedWithUserCache" + if($params.DSWUCMaxConnectionsToServer) + { + $DSWUC.MaxConnectionsToServer = $params.DSWUCMaxConnectionsToServer + } + if($params.DSWUCRequestTimeout) + { + $DSWUC.RequestTimeout = $params.DSWUCRequestTimeout + } + if($params.DSWUCChannelOpenTimeOut) + { + $DSWUC.ChannelOpenTimeOut = $params.DSWUCChannelOpenTimeOut + } + Set-SPDistributedCacheClientSetting -ContainerType "DistributedSharedWithUserCache" $DSWUC + + #DistributedUnifiedGroupsCache + $DUGC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedUnifiedGroupsCache" + if($params.DUGCMaxConnectionsToServer) + { + $DUGC.MaxConnectionsToServer = $params.DUGCMaxConnectionsToServer + } + if($params.DUGCRequestTimeout) + { + $DUGC.RequestTimeout = $params.DUGCRequestTimeout + } + if($params.DUGCChannelOpenTimeOut) + { + $DUGC.ChannelOpenTimeOut = $params.DUGCChannelOpenTimeOut + } + Set-SPDistributedCacheClientSetting -ContainerType "DistributedUnifiedGroupsCache" $DUGC + + #DistributedResourceTallyCache + $DRTC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedResourceTallyCache" + if($params.DRTCMaxConnectionsToServer) + { + $DRTC.MaxConnectionsToServer = $params.DRTCMaxConnectionsToServer + } + if($params.DRTCRequestTimeout) + { + $DRTC.RequestTimeout = $params.DRTCRequestTimeout + } + if($params.DRTCChannelOpenTimeOut) + { + $DRTC.ChannelOpenTimeOut = $params.DRTCChannelOpenTimeOut + } + Set-SPDistributedCacheClientSetting -ContainerType "DistributedResourceTallyCache" $DRTC + + #DistributedHealthScoreCache + $DHSC = Get-SPDistributedCacheClientSetting -ContainerType "DistributedHealthScoreCache" + if($params.DHSCMaxConnectionsToServer) + { + $DHSC.MaxConnectionsToServer = $params.DHSCMaxConnectionsToServer + } + if($params.DHSCRequestTimeout) + { + $DHSC.RequestTimeout = $params.DHSCRequestTimeout + } + if($params.DHSCChannelOpenTimeOut) + { + $DHSC.ChannelOpenTimeOut = $params.DHSCChannelOpenTimeOut + } + Set-SPDistributedCacheClientSetting -ContainerType "DistributedHealthScoreCache" $DHSC + } } } @@ -670,6 +966,66 @@ function Test-TargetResource [System.UInt32] $DSTACChannelOpenTimeOut, + [Parameter()] + [System.UInt32] + $DFLTCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DFLTCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DFLTCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DSWUCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DSWUCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DSWUCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DUGCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DUGCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DUGCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DRTCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DRTCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DRTCChannelOpenTimeOut, + + [Parameter()] + [System.UInt32] + $DHSCMaxConnectionsToServer, + + [Parameter()] + [System.UInt32] + $DHSCRequestTimeout, + + [Parameter()] + [System.UInt32] + $DHSCChannelOpenTimeOut, + [Parameter()] [System.Management.Automation.PSCredential] $InstallAccount @@ -682,35 +1038,50 @@ function Test-TargetResource return Test-SPDscParameterState -CurrentValues $CurrentValues ` -DesiredValues $PSBoundParameters ` -ValuesToCheck @("DLTCMaxConnectionsToServer", - "DLTCRequestTimeout", - "DLTCChannelOpenTimeOut", - "DVSCMaxConnectionsToServer", - "DVSCRequestTimeout", - "DVSCChannelOpenTimeOut", - "DACMaxConnectionsToServer", - "DACRequestTimeout", - "DACChannelOpenTimeOut", - "DAFMaxConnectionsToServer", - "DAFRequestTimeout", - "DAFChannelOpenTimeOut", - "DAFCMaxConnectionsToServer", - "DAFCRequestTimeout", - "DAFCChannelOpenTimeOut", - "DBCMaxConnectionsToServer", - "DBCRequestTimeout", - "DBCChannelOpenTimeOut", - "DDCMaxConnectionsToServer", - "DDCRequestTimeout", - "DDCChannelOpenTimeOut", - "DSCMaxConnectionsToServer", - "DSCRequestTimeout", - "DSCChannelOpenTimeOut", - "DTCMaxConnectionsToServer", - "DTCRequestTimeout", - "DTCChannelOpenTimeOut", - "DSTACMaxConnectionsToServer", - "DSTACRequestTimeout", - "DSTACChannelOpenTimeOut" + "DLTCRequestTimeout", + "DLTCChannelOpenTimeOut", + "DVSCMaxConnectionsToServer", + "DVSCRequestTimeout", + "DVSCChannelOpenTimeOut", + "DACMaxConnectionsToServer", + "DACRequestTimeout", + "DACChannelOpenTimeOut", + "DAFMaxConnectionsToServer", + "DAFRequestTimeout", + "DAFChannelOpenTimeOut", + "DAFCMaxConnectionsToServer", + "DAFCRequestTimeout", + "DAFCChannelOpenTimeOut", + "DBCMaxConnectionsToServer", + "DBCRequestTimeout", + "DBCChannelOpenTimeOut", + "DDCMaxConnectionsToServer", + "DDCRequestTimeout", + "DDCChannelOpenTimeOut", + "DSCMaxConnectionsToServer", + "DSCRequestTimeout", + "DSCChannelOpenTimeOut", + "DTCMaxConnectionsToServer", + "DTCRequestTimeout", + "DTCChannelOpenTimeOut", + "DSTACMaxConnectionsToServer", + "DSTACRequestTimeout", + "DSTACChannelOpenTimeOut", + "DFLTCMaxConnectionsToServer", + "DFLTCRequestTimeout", + "DFLTCChannelOpenTimeOut", + "DSWUCMaxConnectionsToServer", + "DSWUCRequestTimeout", + "DSWUCChannelOpenTimeOut", + "DUGCMaxConnectionsToServer", + "DUGCRequestTimeout", + "DUGCChannelOpenTimeOut", + "DRTCMaxConnectionsToServer", + "DRTCRequestTimeout", + "DRTCChannelOpenTimeOut", + "DHSCMaxConnectionsToServer", + "DHSCRequestTimeout", + "DHSCChannelOpenTimeOut" ) } diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.schema.mof b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.schema.mof index e899e0ebb..852683162 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.schema.mof +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.schema.mof @@ -32,5 +32,20 @@ class MSFT_SPDistributedCacheClientSettings : OMI_BaseResource [Write, Description("Maximum number of connections to the Distributed Server to Application Server Cache")] UInt32 DSTACMaxConnectionsToServer; [Write, Description("Request timeout for the Distributed Server to Application Server Cache")] UInt32 DSTACRequestTimeout; [Write, Description("Channel timeout for the Distributed Server to Application Server Cache")] UInt32 DSTACChannelOpenTimeOut; + [Write, Description("Maximum number of connections to the Distributed File Lock Throttler Cache (SP2016 and above)")] UInt32 DFLTCMaxConnectionsToServer; + [Write, Description("Request timeout for the Distributed File Lock Throttler Cache (SP2016 and above)")] UInt32 DFLTCRequestTimeout; + [Write, Description("Channel timeout for the Distributed File Lock Throttler Cache (SP2016 and above)")] UInt32 DFLTCChannelOpenTimeOut; + [Write, Description("Maximum number of connections to the Distributed Shared With User Cache (SP2016 and above)")] UInt32 DSWUCMaxConnectionsToServer; + [Write, Description("Request timeout for the Distributed Shared With User Cache (SP2016 and above)")] UInt32 DSWUCRequestTimeout; + [Write, Description("Channel timeout for the Distributed Shared With User Cache (SP2016 and above)")] UInt32 DSWUCChannelOpenTimeOut; + [Write, Description("Maximum number of connections to the Distributed Unified Groups Cache (SP2016 and above)")] UInt32 DUGCMaxConnectionsToServer; + [Write, Description("Request timeout for the Distributed Unified Groups Cache (SP2016 and above)")] UInt32 DUGCRequestTimeout; + [Write, Description("Channel timeout for the Distributed Unified Groups Cache (SP2016 and above)")] UInt32 DUGCChannelOpenTimeOut; + [Write, Description("Maximum number of connections to the Distributed Resource Tally Cache (SP2016 and above)")] UInt32 DRTCMaxConnectionsToServer; + [Write, Description("Request timeout for the Distributed Resource Tally Cache (SP2016 and above)")] UInt32 DRTCRequestTimeout; + [Write, Description("Channel timeout for the Distributed Resource Tally Cache (SP2016 and above)")] UInt32 DRTCChannelOpenTimeOut; + [Write, Description("Maximum number of connections to the Distributed Health Score Cache (SP2016 and above)")] UInt32 DHSCMaxConnectionsToServer; + [Write, Description("Request timeout for the Distributed Health Score Cache (SP2016 and above)")] UInt32 DHSCRequestTimeout; + [Write, Description("Channel timeout for the Distributed Health Score Cache (SP2016 and above)")] UInt32 DHSCChannelOpenTimeOut; [Write, Description("POWERSHELL 4 ONLY: The account to run this resource as, use PsDscRunAsCredential if using PowerShell 5"), EmbeddedInstance("MSFT_Credential")] String InstallAccount; }; diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.psm1 index 56a01397d..8c5f737e4 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.psm1 @@ -50,6 +50,10 @@ function Get-TargetResource [System.Boolean] $AllowUserFormCrossDomainDataConnections, + [Parameter()] + [System.Boolean] + $AllowEventPropagation, + [Parameter()] [System.UInt16] $MaxPostbacksPerSession, @@ -90,6 +94,7 @@ function Get-TargetResource AllowEmbeddedSqlForDataConnections = $params.AllowEmbeddedSqlForDataConnections AllowUdcAuthenticationForDataConnections = $params.AllowUdcAuthenticationForDataConnections AllowUserFormCrossDomainDataConnections = $params.AllowUserFormCrossDomainDataConnections + AllowEventPropagation = $params.AllowEventPropagation MaxPostbacksPerSession = $params.MaxPostbacksPerSession MaxUserActionsPerPostback = $params.MaxUserActionsPerPostback ActiveSessionsTimeout = $params.ActiveSessionsTimeout @@ -113,6 +118,7 @@ function Get-TargetResource AllowEmbeddedSqlForDataConnections = $config.AllowEmbeddedSqlForDataConnections AllowUdcAuthenticationForDataConnections = $config.AllowUdcAuthenticationForDataConnections AllowUserFormCrossDomainDataConnections = $config.AllowUserFormCrossDomainDataConnections + AllowEventPropagation = $config.AllowEventPropagation MaxPostbacksPerSession = $config.MaxPostbacksPerSession MaxUserActionsPerPostback = $config.MaxUserActionsPerPostback ActiveSessionsTimeout = $config.ActiveSessionsTimeout @@ -175,6 +181,10 @@ function Set-TargetResource [System.Boolean] $AllowUserFormCrossDomainDataConnections, + [Parameter()] + [System.Boolean] + $AllowEventPropagation, + [Parameter()] [System.UInt16] $MaxPostbacksPerSession, @@ -255,6 +265,11 @@ function Set-TargetResource $config.AllowUserFormCrossDomainDataConnections = $params.AllowUserFormCrossDomainDataConnections } + if($params.ContainsKey("AllowEventPropagation")) + { + $config.AllowEventPropagation = $params.AllowEventPropagation + } + if($params.ContainsKey("MaxPostbacksPerSession")) { $config.MaxPostbacksPerSession = $params.MaxPostbacksPerSession @@ -331,6 +346,10 @@ function Test-TargetResource [System.Boolean] $AllowUserFormCrossDomainDataConnections, + [Parameter()] + [System.Boolean] + $AllowEventPropagation, + [Parameter()] [System.UInt16] $MaxPostbacksPerSession, @@ -370,6 +389,7 @@ function Test-TargetResource "AllowEmbeddedSqlForDataConnections", "AllowUdcAuthenticationForDataConnections", "AllowUserFormCrossDomainDataConnections", + "AllowEventPropagation", "MaxPostbacksPerSession", "MaxUserActionsPerPostback", "ActiveSessionsTimeout", diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof b/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof index f372fe867..806a7edc6 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof @@ -12,6 +12,7 @@ class MSFT_SPInfoPathFormsServiceConfig : OMI_BaseResource [Write, Description("True sets the InfoPath Forms Service to allow embedded SQL sonnections in Forms")] Boolean AllowEmbeddedSqlForDataConnections; [Write, Description("True sets the InfoPath Forms Service to allow User Defined connections")] Boolean AllowUdcAuthenticationForDataConnections; [Write, Description("True sets the InfoPath Forms Service to allow Cross-Domain connections")] Boolean AllowUserFormCrossDomainDataConnections; + [Write, Description("True enable the original performance optimization")] Boolean AllowEventPropagation; [Write, Description("Maximum number of postback allowed per session")] Uint16 MaxPostbacksPerSession; [Write, Description("Maximum number of actions that can be triggered per postback")] Uint16 MaxUserActionsPerPostback; [Write, Description("Timeout in minutes for active sessions")] Uint16 ActiveSessionsTimeout; diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPDistributedCacheClientSettings.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPDistributedCacheClientSettings.Tests.ps1 index bef1f6ef1..d82bca720 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPDistributedCacheClientSettings.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPDistributedCacheClientSettings.Tests.ps1 @@ -27,13 +27,13 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Context -Name "Some Distributed Cache Client Settings are Not Properly Configured" -Fixture { Mock -CommandName Get-SPDistributedCacheClientSetting -MockWith { return @{ - MaxConnectionsToServer = 3 - RequestTimeout = 1000 - ChannelOpenTimeOut = 1000 + MaxConnectionsToServer = 5 + RequestTimeout = 2000 + ChannelOpenTimeOut = 2000 } } $testParams = @{ IsSingleInstance = "Yes" - DLTCMaxConnectionsToServer = 5 + DLTCMaxConnectionsToServer = 3 DLTCRequestTimeout = 1000 DLTCChannelOpenTimeOut = 1000 DVSCMaxConnectionsToServer = 3 @@ -54,36 +54,58 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { DDCMaxConnectionsToServer = 3 DDCRequestTimeout = 1000 DDCChannelOpenTimeOut = 1000 - DSCMaxConnectionsToServer = 5 + DSCMaxConnectionsToServer = 3 DSCRequestTimeout = 1000 DSCChannelOpenTimeOut = 1000 DTCMaxConnectionsToServer = 3 DTCRequestTimeout = 1000 - DTCChannelOpenTimeOut = 1500 + DTCChannelOpenTimeOut = 1000 DSTACMaxConnectionsToServer = 3 DSTACRequestTimeout = 1000 DSTACChannelOpenTimeOut = 1000 } - It "Should return IsSingleInstance equals Yes" { - (Get-TargetResource @testParams).IsSingleInstance | Should Be "Yes" + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -ne 15) + { + $testparams.add("DFLTCMaxConnectionsToServer", 3) + $testparams.add("DFLTCRequestTimeout", 1000) + $testparams.add("DFLTCChannelOpenTimeOut", 1000) + $testparams.add("DSWUCMaxConnectionsToServer", 3) + $testparams.add("DSWUCRequestTimeout", 1000) + $testparams.add("DSWUCChannelOpenTimeOut", 1000) + $testparams.add("DUGCMaxConnectionsToServer", 3) + $testparams.add("DUGCRequestTimeout", 1000) + $testparams.add("DUGCChannelOpenTimeOut", 1000) + $testparams.add("DRTCMaxConnectionsToServer", 3) + $testparams.add("DRTCRequestTimeout", 1000) + $testparams.add("DRTCChannelOpenTimeOut", 1000) + $testparams.add("DHSCMaxConnectionsToServer", 3) + $testparams.add("DHSCRequestTimeout", 1000) + $testparams.add("DHSCChannelOpenTimeOut", 1000) + } + + It "Should return DLTCMaxConnectionsToServer equals 5" { + (Get-TargetResource @testParams).DLTCMaxConnectionsToServer | Should Be 5 } It "Should properly set the settings" { Set-TargetResource @testParams + Assert-MockCalled Set-SPDistributedCacheClientSetting } It "Should return false from Test-TargetResource" { (Test-TargetResource @testParams) | Should Be $false } } - Context -Name "Some Distributed Cache Client Settings are Not Properly Configured" -Fixture { + + Context -Name "All Distributed Cache Client Settings are properly Configured" -Fixture { Mock -CommandName Get-SPDistributedCacheClientSetting -MockWith { return @{ MaxConnectionsToServer = 1 RequestTimeout = 3000 ChannelOpenTimeOut = 3000 } } + $testParams = @{ IsSingleInstance = "Yes" DLTCMaxConnectionsToServer = 1 @@ -117,10 +139,67 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { DSTACRequestTimeout = 3000 DSTACChannelOpenTimeOut = 3000 } - It "Should successfully test the resource" { + + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -ne 15) + { + $testparams.add("DFLTCMaxConnectionsToServer", 1) + $testparams.add("DFLTCRequestTimeout", 3000) + $testparams.add("DFLTCChannelOpenTimeOut", 3000) + $testparams.add("DSWUCMaxConnectionsToServer", 1) + $testparams.add("DSWUCRequestTimeout", 3000) + $testparams.add("DSWUCChannelOpenTimeOut", 3000) + $testparams.add("DUGCMaxConnectionsToServer", 1) + $testparams.add("DUGCRequestTimeout", 3000) + $testparams.add("DUGCChannelOpenTimeOut", 3000) + $testparams.add("DRTCMaxConnectionsToServer", 1) + $testparams.add("DRTCRequestTimeout", 3000) + $testparams.add("DRTCChannelOpenTimeOut", 3000) + $testparams.add("DHSCMaxConnectionsToServer", 1) + $testparams.add("DHSCRequestTimeout", 3000) + $testparams.add("DHSCChannelOpenTimeOut", 3000) + } + + It "Should return DLTCMaxConnectionsToServer equals 5" { + (Get-TargetResource @testParams).DLTCMaxConnectionsToServer | Should Be 1 + } + + It "Should return true from test the resource" { (Test-TargetResource @testParams) | Should Be $true } } + + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 15) + { + Context -Name "SP2016+ parameters specified with SP2013" -Fixture { + Mock -CommandName Get-SPDistributedCacheClientSetting -MockWith { + return @{ + MaxConnectionsToServer = 1 + RequestTimeout = 3000 + ChannelOpenTimeOut = 3000 + } } + $testParams = @{ + IsSingleInstance = "Yes" + DLTCMaxConnectionsToServer = 1 + DLTCRequestTimeout = 3000 + DLTCChannelOpenTimeOut = 3000 + DFLTCMaxConnectionsToServer = 1 + DFLTCRequestTimeout = 3000 + DFLTCChannelOpenTimeOut = 3000 + } + + It "Should throw exception in the Get method" { + { Get-TargetResource @testParams } | Should Throw "The following parameters are only supported in SharePoint 2016 and above" + } + + It "Should throw exception in the Set method" { + { Set-TargetResource @testParams } | Should Throw "The following parameters are only supported in SharePoint 2016 and above" + } + + It "Should throw exception in the Test method" { + { Test-TargetResource @testParams } | Should Throw "The following parameters are only supported in SharePoint 2016 and above" + } + } + } } } diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPInfoPathFormsServiceConfig.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPInfoPathFormsServiceConfig.Tests.ps1 index 3239ad3db..c89b9ae46 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPInfoPathFormsServiceConfig.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPInfoPathFormsServiceConfig.Tests.ps1 @@ -30,11 +30,13 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { AllowEmbeddedSqlForDataConnections = $false AllowUdcAuthenticationForDataConnections = $false AllowUserFormCrossDomainDataConnections = $false + AllowEventPropagation = $false MaxPostbacksPerSession = 75 MaxUserActionsPerPostback = 200 ActiveSessionsTimeout = 1440 MaxSizeOfUserFormState = 4194304 }| Add-Member ScriptMethod Update { + $global:InfoPathSettingsUpdated = $true } -PassThru } @@ -55,6 +57,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { AllowEmbeddedSqlForDataConnections = $false AllowUdcAuthenticationForDataConnections = $false AllowUserFormCrossDomainDataConnections = $false + AllowEventPropagation = $false MaxPostbacksPerSession = 75 MaxUserActionsPerPostback = 200 ActiveSessionsTimeout = 1440 @@ -79,6 +82,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { AllowEmbeddedSqlForDataConnections = $false AllowUdcAuthenticationForDataConnections = $false AllowUserFormCrossDomainDataConnections = $false + AllowEventPropagation = $false MaxPostbacksPerSession = 75 MaxUserActionsPerPostback = 200 ActiveSessionsTimeout = 1440 @@ -91,6 +95,41 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } + Context -Name "When the InfoPath Form Services is not properly configured" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Ensure = "Present" + AllowUserFormBrowserEnabling = $false + AllowUserFormBrowserRendering = $false + MaxDataConnectionTimeout = 20001 + DefaultDataConnectionTimeout = 10001 + MaxDataConnectionResponseSize = 1501 + RequireSslForDataConnections = $false + AllowEmbeddedSqlForDataConnections = $true + AllowUdcAuthenticationForDataConnections = $true + AllowUserFormCrossDomainDataConnections = $true + AllowEventPropagation = $true + MaxPostbacksPerSession = 76 + MaxUserActionsPerPostback = 201 + ActiveSessionsTimeout = 1439 + MaxSizeOfUserFormState = 4095 + } + + It "Should return true when the Test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should return the proper MaxSizeOfUserFormState value" { + (Get-TargetResource @testParams).MaxSizeOfUserFormState | Should be 4096 + } + + $global:InfoPathSettingsUpdated = $false + It "Should properly configure the InfoPath Forms Service" { + Set-TargetResource @testParams + $global:InfoPathSettingsUpdated | Should Be $true + } + } + Context -Name "When the InfoPath Form Services is properly configured" -Fixture { $testParams = @{ IsSingleInstance = "Yes" @@ -104,6 +143,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { AllowEmbeddedSqlForDataConnections = $false AllowUdcAuthenticationForDataConnections = $false AllowUserFormCrossDomainDataConnections = $false + AllowEventPropagation = $false MaxPostbacksPerSession = 75 MaxUserActionsPerPostback = 200 ActiveSessionsTimeout = 1440 From c94599946ca3a2136cd806123107de0083d15801 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 10 Apr 2019 09:11:55 +0200 Subject: [PATCH 32/53] Removed test code --- .../MSFT_SPDistributedCacheClientSettings.psm1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 index dafa295dd..800795f7f 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 @@ -195,7 +195,6 @@ function Get-TargetResource ) Write-Verbose -Message "Getting the Distributed Cache Client Settings" - $test = $PSBoundParameters if ($PSBoundParameters.ContainsKey("DFLTCMaxConnectionsToServer") -eq $true -or $PSBoundParameters.ContainsKey("DFLTCRequestTimeout") -eq $true -or From 1efcb430acb270075bc7a090203d6bdad4c7fd4a Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 10 Apr 2019 15:44:47 +0200 Subject: [PATCH 33/53] Updated DCClientSettings default values --- ...MSFT_SPDistributedCacheClientSettings.psm1 | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 index 800795f7f..555c28848 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 @@ -368,31 +368,31 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DLTCMaxConnectionsToServer = 1, + $DLTCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] - $DLTCRequestTimeout = 3000, + $DLTCRequestTimeout = 500, [Parameter()] [System.UInt32] - $DLTCChannelOpenTimeOut = 3000, + $DLTCChannelOpenTimeOut = 20, [Parameter()] [System.UInt32] - $DVSCMaxConnectionsToServer = 1, + $DVSCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] - $DVSCRequestTimeout = 3000, + $DVSCRequestTimeout = 20, [Parameter()] [System.UInt32] - $DVSCChannelOpenTimeOut = 3000, + $DVSCChannelOpenTimeOut = 20, [Parameter()] [System.UInt32] - $DACMaxConnectionsToServer = 1, + $DACMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -404,7 +404,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DAFMaxConnectionsToServer = 1, + $DAFMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -416,7 +416,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DAFCMaxConnectionsToServer = 1, + $DAFCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -428,7 +428,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DBCMaxConnectionsToServer = 1, + $DBCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -440,7 +440,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DDCMaxConnectionsToServer = 1, + $DDCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -452,7 +452,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DSCMaxConnectionsToServer = 1, + $DSCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -464,7 +464,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DTCMaxConnectionsToServer = 1, + $DTCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -476,7 +476,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DSTACMaxConnectionsToServer = 1, + $DSTACMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -488,7 +488,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DFLTCMaxConnectionsToServer = 1, + $DFLTCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -500,7 +500,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DSWUCMaxConnectionsToServer = 1, + $DSWUCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -512,39 +512,39 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DUGCMaxConnectionsToServer = 1, + $DUGCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] - $DUGCRequestTimeout = 3000, + $DUGCRequestTimeout = 500, [Parameter()] [System.UInt32] - $DUGCChannelOpenTimeOut = 3000, + $DUGCChannelOpenTimeOut = 100, [Parameter()] [System.UInt32] - $DRTCMaxConnectionsToServer = 1, + $DRTCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] - $DRTCRequestTimeout = 3000, + $DRTCRequestTimeout = 500, [Parameter()] [System.UInt32] - $DRTCChannelOpenTimeOut = 3000, + $DRTCChannelOpenTimeOut = 20, [Parameter()] [System.UInt32] - $DHSCMaxConnectionsToServer = 1, + $DHSCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] - $DHSCRequestTimeout = 3000, + $DHSCRequestTimeout = 500, [Parameter()] [System.UInt32] - $DHSCChannelOpenTimeOut = 3000, + $DHSCChannelOpenTimeOut = 20, [Parameter()] [System.Management.Automation.PSCredential] From 1b1949625dc1b5adc35fb95da010129c1effd8ec Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 10 Apr 2019 15:55:32 +0200 Subject: [PATCH 34/53] Removed check for incremental with continuous crawl --- CHANGELOG.md | 11 +++-- .../MSFT_SPSearchContentSource.psm1 | 6 --- ...rePointDsc.SPSearchContentSource.Tests.ps1 | 45 ------------------- 3 files changed, 7 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 792ffae5d..8d8c4633f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,18 +3,21 @@ ## Unreleased * SPDistributedCacheClientSettings - * Added 15 new SharePoint 2016 parameters + * Added 15 new SharePoint 2016 parameters. * SPInfoPathFormsServiceConfig - * Added the AllowEventPropagation parameter + * Added the AllowEventPropagation parameter. * SPInstallPrereqs * Added check to unblock setup file if it is blocked because it is coming - from a network location. This to prevent endless wait + from a network location. This to prevent endless wait. * Added ability to install from a UNC path, by adding server to IE Local Intranet Zone. This will prevent an endless wait - caused by security warning + caused by security warning. * SPManagedMetadataServiceApp * Fixed issue where Get-TargetResource method throws an error when the service app proxy does not exist and no proxy name is specified. +* SPSearchContent Source + * Removed check that prevents configuring an incremental schedule when + using continuous crawl. * SPSubscriptionSettingsServiceApp * Fixed issue where the service app proxy isn't created when it wasn't created during initial deployment. diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 index d467b5bd4..f087ea5b3 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 @@ -301,12 +301,6 @@ function Set-TargetResource { throw "Parameter LimitServerHops is not valid for SharePoint content sources" } - if ($ContinuousCrawl -eq $true -and ` - $PSBoundParameters.ContainsKey("IncrementalSchedule") -eq $true) - { - throw ("You can not specify an incremental crawl schedule on a content source " + ` - "that will use continous crawl") - } if ($CrawlSetting -eq "Custom") { throw ("Parameter CrawlSetting can only be set to custom for website content " + ` diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPSearchContentSource.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPSearchContentSource.Tests.ps1 index 5c25339fa..5eb608470 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPSearchContentSource.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPSearchContentSource.Tests.ps1 @@ -159,32 +159,6 @@ namespace Microsoft.Office.Server.Search.Administration { } } - Context -Name "ContinuousCrawl should not be used with Incremental Schedule" { - $testParams = @{ - Name = "Example content source" - ServiceAppName = "Search Service Application" - ContentSourceType = "SharePoint" - ContinuousCrawl = $true - IncrementalSchedule = (New-CimInstance -ClassName MSFT_SPSearchCrawlSchedule -Property @{ - ScheduleType = "Weekly" - StartHour = "0" - StartMinute = "0" - CrawlScheduleDaysOfWeek = @("Monday", "Wednesday") - } -ClientOnly) - Addresses = @("http://site.contoso.com") - CrawlSetting = "CrawlEverything" - Ensure = "Present" - } - - It "Should create the content source in the test method" { - { Test-TargetResource @testParams } | Should Throw "You can not specify an incremental crawl schedule on a content source that will use continous crawl" - } - - It "Should create the content source in the set method" { - { Set-TargetResource @testParams } | Should Throw "You can not specify an incremental crawl schedule on a content source that will use continous crawl" - } - } - Context -Name "LimitPageDepth should not be used with Content Source Type FileShare" { $testParams = @{ Name = "Example content source" @@ -1218,25 +1192,6 @@ namespace Microsoft.Office.Server.Search.Administration { { Test-TargetResource @testParams } | Should Throw "Parameter LimitServerHops is not valid for SharePoint content sources" } - $testParams = @{ - Name = "Example content source" - ServiceAppName = "Search Service Application" - ContentSourceType = "SharePoint" - IncrementalSchedule = (New-CimInstance -ClassName MSFT_SPSearchCrawlSchedule -Property @{ - ScheduleType = "Weekly" - StartHour = "0" - StartMinute = "0" - CrawlScheduleDaysOfWeek = @("Monday", "Wednesday", "Friday") - } -ClientOnly) - ContinuousCrawl = $true - Ensure = "Present" - } - - It "Should throw Invalid parameter error" { - { Set-TargetResource @testParams } | Should Throw "You can not specify an incremental crawl schedule on a content source that will use continous crawl" - { Test-TargetResource @testParams } | Should Throw "You can not specify an incremental crawl schedule on a content source that will use continous crawl" - } - $testParams = @{ Name = "Example content source" ServiceAppName = "Search Service Application" From 0cf1cf29b614aa7001d8ecbf67e078d33e6ef096 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 10 Apr 2019 16:13:21 +0200 Subject: [PATCH 35/53] Added 2016 example --- .../2-ConfigureClientSettings 2016.ps1 | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Modules/SharePointDsc/Examples/Resources/SPDistributedCacheClientSettings/2-ConfigureClientSettings 2016.ps1 diff --git a/Modules/SharePointDsc/Examples/Resources/SPDistributedCacheClientSettings/2-ConfigureClientSettings 2016.ps1 b/Modules/SharePointDsc/Examples/Resources/SPDistributedCacheClientSettings/2-ConfigureClientSettings 2016.ps1 new file mode 100644 index 000000000..b1b1d3043 --- /dev/null +++ b/Modules/SharePointDsc/Examples/Resources/SPDistributedCacheClientSettings/2-ConfigureClientSettings 2016.ps1 @@ -0,0 +1,68 @@ +<# +.EXAMPLE + This example configures the distributed cache client settings + in SharePoint 2016. +#> + + Configuration Example + { + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $SetupAccount + ) + Import-DscResource -ModuleName SharePointDsc + + node localhost { + SPDistributedCacheClientSettings Settings + { + IsSingleInstance = "Yes" + DLTCMaxConnectionsToServer = 3 + DLTCRequestTimeout = 1000 + DLTCChannelOpenTimeOut = 1000 + DVSCMaxConnectionsToServer = 3 + DVSCRequestTimeout = 1000 + DVSCChannelOpenTimeOut = 1000 + DACMaxConnectionsToServer = 3 + DACRequestTimeout = 1000 + DACChannelOpenTimeOut = 1000 + DAFMaxConnectionsToServer = 3 + DAFRequestTimeout = 1000 + DAFChannelOpenTimeOut = 1000 + DAFCMaxConnectionsToServer = 3 + DAFCRequestTimeout = 1000 + DAFCChannelOpenTimeOut = 1000 + DBCMaxConnectionsToServer = 3 + DBCRequestTimeout = 1000 + DBCChannelOpenTimeOut = 1000 + DDCMaxConnectionsToServer = 3 + DDCRequestTimeout = 1000 + DDCChannelOpenTimeOut = 1000 + DSCMaxConnectionsToServer = 3 + DSCRequestTimeout = 1000 + DSCChannelOpenTimeOut = 1000 + DTCMaxConnectionsToServer = 3 + DTCRequestTimeout = 1000 + DTCChannelOpenTimeOut = 1000 + DSTACMaxConnectionsToServer = 3 + DSTACRequestTimeout = 1000 + DSTACChannelOpenTimeOut = 1000 + DFLTCMaxConnectionsToServer = 3 + DFLTCRequestTimeout = 1000 + DFLTCChannelOpenTimeOut = 1000 + DSWUCMaxConnectionsToServer = 3 + DSWUCRequestTimeout = 1000 + DSWUCChannelOpenTimeOut = 1000 + DUGCMaxConnectionsToServer = 3 + DUGCRequestTimeout = 1000 + DUGCChannelOpenTimeOut = 1000 + DRTCMaxConnectionsToServer = 3 + DRTCRequestTimeout = 1000 + DRTCChannelOpenTimeOut = 1000 + DHSCMaxConnectionsToServer = 3 + DHSCRequestTimeout = 1000 + DHSCChannelOpenTimeOut = 1000 + PsDscRunAscredential = $SetupAccount + } + } + } From 0f510128fe95eb533c25b98e7bf2f69f431a90ec Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 10 Apr 2019 19:43:49 +0200 Subject: [PATCH 36/53] Corrected typo --- .../MSFT_SPInfoPathFormsServiceConfig.schema.mof | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof b/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof index 806a7edc6..d20524425 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInfoPathFormsServiceConfig/MSFT_SPInfoPathFormsServiceConfig.schema.mof @@ -12,7 +12,7 @@ class MSFT_SPInfoPathFormsServiceConfig : OMI_BaseResource [Write, Description("True sets the InfoPath Forms Service to allow embedded SQL sonnections in Forms")] Boolean AllowEmbeddedSqlForDataConnections; [Write, Description("True sets the InfoPath Forms Service to allow User Defined connections")] Boolean AllowUdcAuthenticationForDataConnections; [Write, Description("True sets the InfoPath Forms Service to allow Cross-Domain connections")] Boolean AllowUserFormCrossDomainDataConnections; - [Write, Description("True enable the original performance optimization")] Boolean AllowEventPropagation; + [Write, Description("True enables the original performance optimization")] Boolean AllowEventPropagation; [Write, Description("Maximum number of postback allowed per session")] Uint16 MaxPostbacksPerSession; [Write, Description("Maximum number of actions that can be triggered per postback")] Uint16 MaxUserActionsPerPostback; [Write, Description("Timeout in minutes for active sessions")] Uint16 ActiveSessionsTimeout; From 79a194421822c0f2783ef95f5d675cb790a264a6 Mon Sep 17 00:00:00 2001 From: Farnhill Date: Tue, 16 Apr 2019 17:25:42 +1000 Subject: [PATCH 37/53] Fixes #1056 --- .../MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 index d9afbd267..66886b90d 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 @@ -85,7 +85,7 @@ $Script:SP2019Win19Features = @("Web-Server", "Web-WebServer", "Web-Http-Logging", "Web-Log-Libraries", "Web-Request-Monitor", "Web-Http-Tracing", "Web-Performance", "Web-Stat-Compression", "Web-Dyn-Compression", "Web-Security", "Web-Filtering", "Web-Basic-Auth", - "Web-Digest-Auth", "Web-Windows-Auth", "Web-App-Dev", "Web-Net-Ext", + "Web-Windows-Auth", "Web-App-Dev", "Web-Net-Ext", "Web-Net-Ext45", "Web-Asp-Net", "Web-Asp-Net45", "Web-ISAPI-Ext", "Web-ISAPI-Filter", "Web-Mgmt-Tools", "Web-Mgmt-Console", "NET-Framework-Features", "NET-HTTP-Activation", "NET-Non-HTTP-Activ", From 86c68ab237c2b2246e454e9c1a6dd514f7f98bd1 Mon Sep 17 00:00:00 2001 From: Farnhill Date: Tue, 16 Apr 2019 17:33:57 +1000 Subject: [PATCH 38/53] Added fix details to change log --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8c4633f..70d38ac43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ * Added ability to install from a UNC path, by adding server to IE Local Intranet Zone. This will prevent an endless wait caused by security warning. + * Fixed an issue that would prevent the resource failing a test when the + prerequisites have been install successfully on Windows Server 2019 * SPManagedMetadataServiceApp * Fixed issue where Get-TargetResource method throws an error when the service app proxy does not exist and no proxy name is specified. From 2c50277be7a24df8377e3ffe7e8500a31e98e6e2 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Fri, 19 Apr 2019 18:26:14 -0400 Subject: [PATCH 39/53] Working on code coverage --- .../SharePointDsc.SPFarm.Tests.ps1 | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 index b358f82f1..8ee0c1032 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 @@ -102,6 +102,32 @@ namespace Microsoft.SharePoint.Administration { It "Should throw exception in the set method" { { Set-TargetResource @testParams } | Should Throw "An invalid value for CentralAdministrationPort is specified:" } + + # Repeat tests for invalid URL + $testParams = @{ + IsSingleInstance = "Yes" + Ensure = "Present" + FarmConfigDatabaseName = "SP_Config" + CentralAdministrationPort = 443 + CentralAdministrationUrl = "https://admin.contoso.com:443" + DatabaseServer = "sql.contoso.com" + FarmAccount = $mockFarmAccount + Passphrase = $mockPassphrase + AdminContentDatabaseName = "SP_AdminContent" + RunCentralAdmin = $true + } + + It "Should throw exception in the get method" { + { Get-TargetResource @testParams } | Should Throw "CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead." + } + + It "Should throw exception in the test method" { + { Test-TargetResource @testParams } | Should Throw "CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead." + } + + It "Should throw exception in the set method" { + { Set-TargetResource @testParams } | Should Throw "CentralAdministrationUrl should not specify port. Use CentralAdministrationPort instead." + } } Context -Name "No config databaes exists, and this server should be connected to one" -Fixture { @@ -300,6 +326,7 @@ namespace Microsoft.SharePoint.Administration { FarmAccount = $mockFarmAccount Passphrase = $mockPassphrase AdminContentDatabaseName = "SP_AdminContent" + CentralAdministrationUrl = "" RunCentralAdmin = $true } @@ -432,6 +459,7 @@ namespace Microsoft.SharePoint.Administration { } } + # Adding coverage here for when CA URL is HTTPS but port is not specified Context -Name "Server is connected to farm, but Central Admin isn't started" -Fixture { $testParams = @{ IsSingleInstance = "Yes" @@ -442,6 +470,7 @@ namespace Microsoft.SharePoint.Administration { Passphrase = $mockPassphrase AdminContentDatabaseName = "SP_AdminContent" RunCentralAdmin = $true + CentralAdministrationUrl = "https://admin.contoso.com" } Mock -CommandName Get-SPDSCRegistryKey -MockWith { @@ -627,6 +656,242 @@ namespace Microsoft.SharePoint.Administration { } } + class fake_sp_iis_settings { + [hashtable[]] $SecureBindings = @( + @{ + HostHeader = "admin.contoso.com" + Port = "443" + } + ) + [bool] $DisableKerberos = $true + + fake_sp_iis_settings([string] $HostHeader) { + $this.SecureBindings[0].HostHeader = $HostHeader + } + } + + class fake_sp_web_application { + [fake_sp_iis_settings] $IisSettings + [bool] $IsAdministrationWebApplication = $true + [string] $Url + [hashtable[]] $ContentDatabases = @(@{ + Name = "SP_AdminContent" + }) + + fake_sp_web_application([string] $Url, [string] $IisHostHeader) { + $this.Url = $Url + $this.IisSettings = [fake_sp_iis_settings]::new($IisHostHeader) + } + + [fake_sp_iis_settings] GetIisSettingsWithFallback([string] $Zone) { + return $this.IisSettings + } + } + + Context -Name "This server is running CA on HTTPS, but secure bindings do not match CA URL" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Ensure = "Present" + FarmConfigDatabaseName = "SP_Config" + DatabaseServer = "sql.contoso.com" + FarmAccount = $mockFarmAccount + Passphrase = $mockPassphrase + AdminContentDatabaseName = "SP_AdminContent" + RunCentralAdmin = $true + CentralAdministrationUrl = "https://admin.contoso.com" + CentralAdministrationPort = 443 + } + + 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 + } + } + Mock -CommandName Get-SPDSCConfigDBStatus -MockWith { + return @{ + Locked = $false + ValidPermissions = $true + DatabaseExists = $true + } + } + Mock -CommandName "Get-SPDSCSQLInstanceStatus" -MockWith { + return @{ + MaxDOPCorrect = $true + } + } + Mock -CommandName Get-SPDatabase -MockWith { + return @(@{ + Name = $testParams.FarmConfigDatabaseName + Type = "Configuration Database" + NormalizedDataSource = $testParams.DatabaseServer + }) + } + Mock -CommandName Get-SPWebApplication -MockWith { + return [fake_sp_web_application]::new($testParams.CentralAdministrationUrl, "different.contoso.com") + } + Mock -CommandName Get-CimInstance -MockWith { + return @{ + Domain = "domain.com" + } + } + + Mock -CommandName Get-SPServiceInstance -MockWith { + switch ($global:SPDscSIRunCount) + { + { 2 -contains $_ } + { + $global:SPDscSIRunCount++ + return @( + @{ + Name = "WSS_Administration" + Status = "Online" + } | Add-Member -MemberType ScriptMethod ` + -Name GetType ` + -Value { + return @{ + Name = "SPWebServiceInstance" + } + } -PassThru -Force + ) + } + { 0,1 -contains $_ } + { + $global:SPDscSIRunCount++ + return $null + } + } + } + + $global:SPDscSIRunCount = 0 + It "Should return current values for the Get method" { + $result = Get-TargetResource @testParams + $result.RunCentralAdmin | Should Be $false + $result.CentralAdministrationUrl | Should Be $testParams.CentralAdministrationUrl + $result.CentralAdministrationPort | Should Be $testParams.CentralAdministrationPort + } + + $global:SPDscSIRunCount = 0 + It "Should start the central administration instance" { + Set-TargetResource @testParams + Assert-MockCalled -CommandName "Start-SPServiceInstance" + } + + $global:SPDscCentralAdminCheckDone = $false + It "Should return false from the test method" { + Test-TargetResource @testParams | Should be $false + } + } + + Context -Name "This server is running CA on HTTPS, but secure bindings do not contain valid hostname" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Ensure = "Present" + FarmConfigDatabaseName = "SP_Config" + DatabaseServer = "sql.contoso.com" + FarmAccount = $mockFarmAccount + Passphrase = $mockPassphrase + AdminContentDatabaseName = "SP_AdminContent" + RunCentralAdmin = $true + CentralAdministrationUrl = "https://admin.contoso.com" + CentralAdministrationPort = 443 + } + + 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 + } + } + Mock -CommandName Get-SPDSCConfigDBStatus -MockWith { + return @{ + Locked = $false + ValidPermissions = $true + DatabaseExists = $true + } + } + Mock -CommandName "Get-SPDSCSQLInstanceStatus" -MockWith { + return @{ + MaxDOPCorrect = $true + } + } + Mock -CommandName Get-SPDatabase -MockWith { + return @(@{ + Name = $testParams.FarmConfigDatabaseName + Type = "Configuration Database" + NormalizedDataSource = $testParams.DatabaseServer + }) + } + Mock -CommandName Get-SPWebApplication -MockWith { + return [fake_sp_web_application]::new($testParams.CentralAdministrationUrl, "") + } + Mock -CommandName Get-CimInstance -MockWith { + return @{ + Domain = "domain.com" + } + } + + Mock -CommandName Get-SPServiceInstance -MockWith { + switch ($global:SPDscSIRunCount) + { + { 2 -contains $_ } + { + $global:SPDscSIRunCount++ + return @( + @{ + Name = "WSS_Administration" + Status = "Online" + } | Add-Member -MemberType ScriptMethod ` + -Name GetType ` + -Value { + return @{ + Name = "SPWebServiceInstance" + } + } -PassThru -Force + ) + } + { 0,1 -contains $_ } + { + $global:SPDscSIRunCount++ + return $null + } + } + } + + $global:SPDscSIRunCount = 0 + It "Should return current values for the Get method" { + $result = Get-TargetResource @testParams + $result.RunCentralAdmin | Should Be $false + $result.CentralAdministrationUrl | Should Be $testParams.CentralAdministrationUrl + $result.CentralAdministrationPort | Should Be $testParams.CentralAdministrationPort + } + + $global:SPDscSIRunCount = 0 + It "Should start the central administration instance" { + Set-TargetResource @testParams + Assert-MockCalled -CommandName "Start-SPServiceInstance" + } + + $global:SPDscCentralAdminCheckDone = $false + It "Should return false from the test method" { + Test-TargetResource @testParams | Should be $false + } + } + Context -Name "This server is connected to the farm and is running CA, but shouldn't" -Fixture { $testParams = @{ IsSingleInstance = "Yes" From d0ac29b949d9f630adbba6756084fc1132054ad8 Mon Sep 17 00:00:00 2001 From: Farnhill Date: Sat, 20 Apr 2019 09:38:01 +1000 Subject: [PATCH 40/53] Fixed typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d38ac43..6e97346ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ to IE Local Intranet Zone. This will prevent an endless wait caused by security warning. * Fixed an issue that would prevent the resource failing a test when the - prerequisites have been install successfully on Windows Server 2019 + prerequisites have been installed successfully on Windows Server 2019 * SPManagedMetadataServiceApp * Fixed issue where Get-TargetResource method throws an error when the service app proxy does not exist and no proxy name is specified. From 755cca0b55d44a7b9e54e12664d3460625dd06e0 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Tue, 23 Apr 2019 13:46:39 +0200 Subject: [PATCH 41/53] Updated SPFarm and SearchContentSource --- CHANGELOG.md | 2 ++ .../DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 15 ++++++++------- .../MSFT_SPSearchContentSource.psm1 | 6 ------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8c4633f..6a1173569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * SPDistributedCacheClientSettings * Added 15 new SharePoint 2016 parameters. +* SPFarm + * Implemented Null check in Get method to prevent errors * SPInfoPathFormsServiceConfig * Added the AllowEventPropagation parameter. * SPInstallPrereqs diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 7c36cc357..3369ee838 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -149,7 +149,7 @@ function Get-TargetResource if ($null -ne $dsnValue) { - # This node has already been connected to a farm + Write-Verbose -Message "This node has already been connected to a farm" $result = Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { @@ -173,10 +173,6 @@ function Get-TargetResource $configDb = Get-SPDatabase | Where-Object -FilterScript { $_.Name -eq $spFarm.Name -and $_.Type -eq "Configuration Database" } - $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } if ($params.FarmAccount.UserName -eq $spFarm.DefaultServiceAccount.Name) { @@ -208,7 +204,9 @@ function Get-TargetResource $centralAdminProvisioned = $true } - if ($centralAdminSite.IisSettings[0].DisableKerberos -eq $false) + $centralAdminAuth = $null + if ($null -ne $centralAdminSite -and ` + $centralAdminSite.IisSettings[0].DisableKerberos -eq $false) { $centralAdminAuth = "Kerberos" } @@ -286,7 +284,8 @@ function Get-TargetResource } else { - # This node has never been connected to a farm, return the null return object + Write-Verbose -Message "This node has never been connected to a farm" + # Return the null return object return @{ IsSingleInstance = "Yes" FarmConfigDatabaseName = $null @@ -463,6 +462,7 @@ function Set-TargetResource } if ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) { + Write-Verbose -Message "Updating CentralAdmin port to $CentralAdministrationPort" Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { @@ -475,6 +475,7 @@ function Set-TargetResource if ($CurrentValues.DeveloperDashboard -ne $DeveloperDashboard) { + Write-Verbose -Message "Updating DeveloperDashboard to $DeveloperDashboard" Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 index f087ea5b3..e3a93a14e 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 @@ -763,12 +763,6 @@ function Test-TargetResource { throw "Parameter LimitServerHops is not valid for SharePoint content sources" } - if ($ContinuousCrawl -eq $true -and ` - $PSBoundParameters.ContainsKey("IncrementalSchedule") -eq $true) - { - throw ("You can not specify an incremental crawl schedule on a content source " + ` - "that will use continous crawl") - } if ($CrawlSetting -eq "Custom") { throw ("Parameter CrawlSetting can only be set to custom for website content " + ` From fce4f4f59cb54289ccefdbb77dd0aa3963981851 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Tue, 23 Apr 2019 16:03:01 +0200 Subject: [PATCH 42/53] Improved logging output messages --- CHANGELOG.md | 7 +++++++ .../MSFT_SPInstall/MSFT_SPInstall.psm1 | 14 ++++++------- .../MSFT_SPInstallLanguagePack.psm1 | 21 ++++++++++--------- .../MSFT_SPInstallPrereqs.psm1 | 6 ++++-- .../MSFT_SPProductUpdate.psm1 | 13 +++++++----- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1173569..7d229e9b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,15 +8,22 @@ * Implemented Null check in Get method to prevent errors * SPInfoPathFormsServiceConfig * Added the AllowEventPropagation parameter. +* SPInstall + * Improved logging ouput +* SPInstallLanguagePack + * Improved logging ouput * SPInstallPrereqs * Added check to unblock setup file if it is blocked because it is coming from a network location. This to prevent endless wait. * Added ability to install from a UNC path, by adding server to IE Local Intranet Zone. This will prevent an endless wait caused by security warning. + * Improved logging ouput * SPManagedMetadataServiceApp * Fixed issue where Get-TargetResource method throws an error when the service app proxy does not exist and no proxy name is specified. +* SPProductUpdate + * Improved logging ouput * SPSearchContent Source * Removed check that prevents configuring an incremental schedule when using continuous crawl. diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 index 66db2af26..d2d85062e 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 @@ -33,7 +33,7 @@ function Get-TargetResource Write-Verbose -Message "Getting install status of SharePoint" - # Check if Binary folder exists + Write-Verbose -Message "Check if Binary folder exists" if (-not(Test-Path -Path $BinaryDir)) { throw "Specified path cannot be found: {$BinaryDir}" @@ -46,7 +46,7 @@ function Get-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` @@ -132,7 +132,7 @@ function Set-TargetResource "its prerequisites. Please remove this manually.") } - # Check if Binary folder exists + Write-Verbose -Message "Check if Binary folder exists" if (-not(Test-Path -Path $BinaryDir)) { throw "Specified path cannot be found: {$BinaryDir}" @@ -187,7 +187,7 @@ function Set-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { @@ -279,9 +279,9 @@ function Set-TargetResource $pr2 = ("HKLM:\Software\Microsoft\Windows\CurrentVersion\" + ` "WindowsUpdate\Auto Update\RebootRequired") $pr3 = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" - if ( ($null -ne (Get-Item $pr1 -ErrorAction SilentlyContinue)) ` - -or ($null -ne (Get-Item $pr2 -ErrorAction SilentlyContinue)) ` - -or ((Get-Item $pr3 | Get-ItemProperty).PendingFileRenameOperations.count -gt 0) ` + if ( ($null -ne (Get-Item -Path $pr1 -ErrorAction SilentlyContinue)) ` + -or ($null -ne (Get-Item -Path $pr2 -ErrorAction SilentlyContinue)) ` + -or ((Get-Item -Path $pr3 | Get-ItemProperty).PendingFileRenameOperations.count -gt 0) ` ) { diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 index 036af1c64..f1d212ddb 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 @@ -29,7 +29,7 @@ function Get-TargetResource Write-Verbose -Message "Getting install status of SharePoint Language Pack" - # Check if Binary folder exists + Write-Verbose -Message "Check if Binary folder exists" if (-not(Test-Path -Path $BinaryDir)) { throw "Specified path cannot be found: {$BinaryDir}" @@ -42,7 +42,7 @@ function Get-TargetResource throw "Setup.exe cannot be found in {$BinaryDir}" } - $zone = Get-Item $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue + $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` @@ -99,7 +99,7 @@ function Get-TargetResource $englishProducts += $languageEN } - # Extract language from filename + Write-Verbose -Message "Extract language from filename" if ($osrvFolder.Name -match "\w*.(\w{2,3}-\w*-?\w*)") { $language = $matches[1] @@ -125,7 +125,7 @@ function Get-TargetResource throw "Error while converting language information: $language" } - # Extract English name of the language code + Write-Verbose -Message "Extract English name of the language code" $updateLanguage = $cultureInfo.EnglishName switch ($cultureInfo.EnglishName) { @@ -215,7 +215,7 @@ function Set-TargetResource return } - # Check if Binary folder exists + Write-Verbose -Message "Check if Binary folder exists" if (-not(Test-Path -Path $BinaryDir)) { throw "Specified path cannot be found: {$BinaryDir}" @@ -228,7 +228,7 @@ function Set-TargetResource throw "Setup.exe cannot be found in {$BinaryDir}" } - $zone = Get-Item $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue + $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` @@ -236,9 +236,10 @@ function Set-TargetResource } $now = Get-Date + Write-Verbose -Message "Check if BinaryInstallDays parameter exists" if ($BinaryInstallDays) { - # BinaryInstallDays parameter exists, check if current day is specified + Write-Verbose -Message "BinaryInstallDays parameter exists, check if current day is specified" $currentDayOfWeek = $now.DayOfWeek.ToString().ToLower().Substring(0,3) if ($BinaryInstallDays -contains $currentDayOfWeek) @@ -258,10 +259,10 @@ function Set-TargetResource Write-Verbose -Message "No BinaryInstallDays specified, Update can be ran on any day." } - # Check if BinaryInstallTime parameter exists + Write-Verbose -Message "Check if BinaryInstallTime parameter exists" if ($BinaryInstallTime) { - # Check if current time is inside of time window + Write-Verbose -Message "BinaryInstallTime parameter exists, check if current time is inside of time window" $upgradeTimes = $BinaryInstallTime.Split(" ") $starttime = 0 $endtime = 0 @@ -306,7 +307,7 @@ function Set-TargetResource "any time. Starting update.") } - # To prevent an endless loop: Check if an upgrade is required. + Write-Verbose -Message "To prevent an endless loop: Check if an upgrade is required." if ((Get-SPDSCInstalledProductVersion).FileMajorPart -eq 15) { $wssRegKey ="hklm:SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\15.0\WSS" diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 index d9afbd267..22467c692 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 @@ -196,13 +196,14 @@ function Get-TargetResource Write-Verbose -Message "Getting installation status of SharePoint prerequisites" + Write-Verbose -Message "Check if InstallerPath folder exists" if (-not(Test-Path -Path $InstallerPath)) { throw "PrerequisitesInstaller cannot be found: {$InstallerPath}" } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` @@ -573,13 +574,14 @@ function Set-TargetResource "prerequisites. Please remove this manually.") } + Write-Verbose -Message "Check if InstallerPath folder exists" if (-not(Test-Path -Path $InstallerPath)) { throw "PrerequisitesInstaller cannot be found: {$InstallerPath}" } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 index 319161e17..1777457db 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 @@ -43,7 +43,7 @@ function Get-TargetResource $servicepack = $false $language = "" - # Get file information from setup file + Write-Verbose -Message "Check if the setup file exists" if (-not(Test-Path -Path $SetupFile)) { throw "Setup file cannot be found: {$SetupFile}" @@ -60,6 +60,7 @@ function Get-TargetResource $nullVersion = New-Object -TypeName System.Version + Write-Verbose -Message "Get file information from setup file" $setupFileInfo = Get-ItemProperty -Path $SetupFile $fileVersion = $setupFileInfo.VersionInfo.FileVersion Write-Verbose -Message "Update has version $fileVersion" @@ -240,7 +241,7 @@ function Set-TargetResource return } - # Check if setup file exists + Write-Verbose -Message "Check if the setup file exists" if (-not(Test-Path -Path $SetupFile)) { throw "Setup file cannot be found: {$SetupFile}" @@ -256,9 +257,10 @@ function Set-TargetResource } $now = Get-Date + Write-Verbose -Message "Check if BinaryInstallDays is specified" if ($BinaryInstallDays) { - # BinaryInstallDays parameter exists, check if current day is specified + Write-Verbose -Message "BinaryInstallDays parameter exists, check if current day is specified" $currentDayOfWeek = $now.DayOfWeek.ToString().ToLower().Substring(0, 3) if ($BinaryInstallDays -contains $currentDayOfWeek) @@ -278,10 +280,11 @@ function Set-TargetResource Write-Verbose -Message "No BinaryInstallDays specified, Update can be ran on any day." } - # Check if BinaryInstallTime parameter exists + Write-Verbose -Message "Check if BinaryInstallTime is specified" if ($BinaryInstallTime) { - # Check if current time is inside of time window + Write-Verbose -Message ("BinaryInstallTime parameter exists, check if current time is inside " + ` + "of time window") $upgradeTimes = $BinaryInstallTime.Split(" ") $starttime = 0 $endtime = 0 From 92003b6cbf1cbc270ffe1835f18d119ac09a714f Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 24 Apr 2019 20:42:06 +0200 Subject: [PATCH 43/53] Fixes issues #885 and #1058 --- CHANGELOG.md | 14 +++- .../MSFT_SPInstall/MSFT_SPInstall.psm1 | 71 ++++++++++++++++-- .../MSFT_SPInstallLanguagePack.psm1 | 74 +++++++++++++++++-- .../MSFT_SPInstallPrereqs.psm1 | 72 ++++++++++++++++-- .../MSFT_SPProductUpdate.psm1 | 72 ++++++++++++++++-- .../MSFT_SPSitePropertyBag.psm1 | 14 ++-- .../SharePointDsc.SPSitePropertyBag.Tests.ps1 | 6 +- 7 files changed, 279 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d229e9b1..462230267 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,23 +10,31 @@ * Added the AllowEventPropagation parameter. * SPInstall * Improved logging ouput + * Updated blocked setup file check to prevent errors when BinaryDir + is a CD-ROM drive or mounted ISO * SPInstallLanguagePack * Improved logging ouput + * Updated blocked setup file check to prevent errors when BinaryDir + is a CD-ROM drive or mounted ISO * SPInstallPrereqs - * Added check to unblock setup file if it is blocked because it is coming - from a network location. This to prevent endless wait. + * Improved logging ouput + * Added the updated check to unblock setup file if it is blocked because + it is coming from a network location. This to prevent endless wait. * Added ability to install from a UNC path, by adding server to IE Local Intranet Zone. This will prevent an endless wait caused by security warning. - * Improved logging ouput * SPManagedMetadataServiceApp * Fixed issue where Get-TargetResource method throws an error when the service app proxy does not exist and no proxy name is specified. * SPProductUpdate * Improved logging ouput + * Updated blocked setup file check to prevent errors when SetupFile + is a CD-ROM drive or mounted ISO * SPSearchContent Source * Removed check that prevents configuring an incremental schedule when using continuous crawl. +* SPSitePropertyBag + * Fixed issue where properties were set on the wrong level. * SPSubscriptionSettingsServiceApp * Fixed issue where the service app proxy isn't created when it wasn't created during initial deployment. diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 index d2d85062e..e1f17710b 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 @@ -46,11 +46,39 @@ function Get-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue - if ($null -ne $zone) + $checkBlockedFile = $true + if (Split-Path -Path $InstallerPath -IsAbsolute) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` - "to unblock the file before continuing.") + $driveLetter = (Split-Path -Path $InstallerPath -Qualifier).TrimEnd(":") + Write-Verbose -Message "BinaryDir refers to drive $driveLetter" + + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } + + if ($checkBlockedFile -eq $true) + { + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` + "to unblock the file before continuing.") + } } $x86Path = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" @@ -187,12 +215,39 @@ function Set-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + $checkBlockedFile = $true + if (Split-Path -Path $InstallerPath -IsAbsolute) + { + $driveLetter = (Split-Path -Path $InstallerPath -Qualifier).TrimEnd(":") + Write-Verbose -Message "BinaryDir refers to drive $driveLetter" - if ($null -ne $zone) + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } + + if ($checkBlockedFile -eq $true) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` - "to unblock the file before continuing.") + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` + "to unblock the file before continuing.") + } } Write-Verbose -Message "Checking if Path is an UNC path" diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 index f1d212ddb..aeee18c66 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 @@ -42,11 +42,40 @@ function Get-TargetResource throw "Setup.exe cannot be found in {$BinaryDir}" } - $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue - if ($null -ne $zone) + Write-Verbose -Message "Checking file status of $setupExe" + $checkBlockedFile = $true + if (Split-Path -Path $setupExe -IsAbsolute) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` - "to unblock the file before continuing.") + $driveLetter = (Split-Path -Path $setupExe -Qualifier).TrimEnd(":") + Write-Verbose -Message "BinaryDir refers to drive $driveLetter" + + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } + + if ($checkBlockedFile -eq $true) + { + $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` + "to unblock the file before continuing.") + } } $osrvFolder = Get-ChildItem -Path (Join-Path -Path $BinaryDir ` @@ -228,11 +257,40 @@ function Set-TargetResource throw "Setup.exe cannot be found in {$BinaryDir}" } - $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue - if ($null -ne $zone) + Write-Verbose -Message "Checking file status of $setupExe" + $checkBlockedFile = $true + if (Split-Path -Path $setupExe -IsAbsolute) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` - "to unblock the file before continuing.") + $driveLetter = (Split-Path -Path $setupExe -Qualifier).TrimEnd(":") + Write-Verbose -Message "BinaryDir refers to drive $driveLetter" + + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } + + if ($checkBlockedFile -eq $true) + { + $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` + "to unblock the file before continuing.") + } } $now = Get-Date diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 index 22467c692..dfa8ae99c 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 @@ -203,11 +203,39 @@ function Get-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue - if ($null -ne $zone) + $checkBlockedFile = $true + if (Split-Path -Path $InstallerPath -IsAbsolute) { - throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` - "$InstallerPath' to unblock the file before continuing.") + $driveLetter = (Split-Path -Path $InstallerPath -Qualifier).TrimEnd(":") + Write-Verbose -Message "InstallerPath refers to drive $driveLetter" + + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } + + if ($checkBlockedFile -eq $true) + { + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` + "to unblock the file before continuing.") + } } $majorVersion = (Get-SPDSCAssemblyVersion -PathToAssembly $InstallerPath) @@ -581,11 +609,39 @@ function Set-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue - if ($null -ne $zone) + $checkBlockedFile = $true + if (Split-Path -Path $InstallerPath -IsAbsolute) { - throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` - "$InstallerPath' to unblock the file before continuing.") + $driveLetter = (Split-Path -Path $InstallerPath -Qualifier).TrimEnd(":") + Write-Verbose -Message "InstallerPath refers to drive $driveLetter" + + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } + + if ($checkBlockedFile -eq $true) + { + $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` + "to unblock the file before continuing.") + } } Write-Verbose -Message "Detecting SharePoint version from binaries" diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 index 1777457db..75515f450 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 @@ -50,12 +50,40 @@ function Get-TargetResource } Write-Verbose -Message "Checking file status of $SetupFile" - $zone = Get-Item -Path $SetupFile -Stream "Zone.Identifier" -EA SilentlyContinue + $checkBlockedFile = $true + if (Split-Path -Path $SetupFile -IsAbsolute) + { + $driveLetter = (Split-Path -Path $SetupFile -Qualifier).TrimEnd(":") + Write-Verbose -Message "SetupFile refers to drive $driveLetter" + + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } - if ($null -ne $zone) + if ($checkBlockedFile -eq $true) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $SetupFile' " + ` - "to unblock the file before continuing.") + $zone = Get-Item -Path $SetupFile -Stream "Zone.Identifier" -EA SilentlyContinue + + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $SetupFile' " + ` + "to unblock the file before continuing.") + } } $nullVersion = New-Object -TypeName System.Version @@ -248,12 +276,40 @@ function Set-TargetResource } Write-Verbose -Message "Checking file status of $SetupFile" - $zone = Get-Item -Path $SetupFile -Stream "Zone.Identifier" -EA SilentlyContinue + $checkBlockedFile = $true + if (Split-Path -Path $SetupFile -IsAbsolute) + { + $driveLetter = (Split-Path -Path $SetupFile -Qualifier).TrimEnd(":") + Write-Verbose -Message "SetupFile refers to drive $driveLetter" + + $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction SilentlyContinue + if ($null -ne $volume) + { + if ($volume.DriveType -ne "CD-ROM") + { + Write-Verbose -Message "Volume is a fixed drive: Perform Blocked File test" + } + else + { + Write-Verbose -Message "Volume is a CD-ROM drive: Skipping Blocked File test" + $checkBlockedFile = $false + } + } + else + { + Write-Verbose -Message "Volume not found. Unable to determine the type. Continuing." + } + } - if ($null -ne $zone) + if ($checkBlockedFile -eq $true) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $SetupFile' " + ` - "to unblock the file before continuing.") + $zone = Get-Item -Path $SetupFile -Stream "Zone.Identifier" -EA SilentlyContinue + + if ($null -ne $zone) + { + throw ("Setup file is blocked! Please use 'Unblock-File -Path $SetupFile' " + ` + "to unblock the file before continuing.") + } } $now = Get-Date diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 index fe907ecca..3c3eda66f 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 @@ -42,12 +42,12 @@ function Get-TargetResource() } else { - if ($spSite.Properties) + if ($spSite.RootWeb.Properties) { - if ($spSite.Properties.Contains($params.Key) -eq $true) + if ($spSite.RootWeb.Properties.Contains($params.Key) -eq $true) { $localEnsure = 'Present' - $currentValue = $spSite.Properties[$params.Key] + $currentValue = $spSite.RootWeb.Properties[$params.Key] } else { @@ -105,14 +105,14 @@ function Set-TargetResource() if ($params.Ensure -eq 'Present') { - Write-Verbose -Message "Adding property '$($params.Key)'='$($params.value)' to SPSite.Properties" - $spSite.Properties[$params.Key] = $params.Value + Write-Verbose -Message "Adding property '$($params.Key)'='$($params.value)' to SPSite.RootWeb.Properties" + $spSite.RootWeb.Properties[$params.Key] = $params.Value $spSite.Update() } else { - Write-Verbose -Message "Removing property '$($params.Key)' from SPSite.Properties" - $spSite.Properties.Remove($params.Key) + Write-Verbose -Message "Removing property '$($params.Key)' from SPSite.RootWeb.Properties" + $spSite.RootWeb.Properties.Remove($params.Key) $spSite.Update() } } diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 index df8f2bff8..e4a7c3235 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 @@ -20,8 +20,10 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Mock -CommandName Get-SPSite -MockWith { $spSite = [pscustomobject]@{ - Properties = @{ - PropertyKey = 'PropertyValue' + RootWeb = @{ + Properties = @{ + PropertyKey = 'PropertyValue' + } } } $spSite = $spSite | Add-Member ScriptMethod Update { From c79b0f0bb80810b53716c382037ea267b4520ab1 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Wed, 24 Apr 2019 20:48:46 +0200 Subject: [PATCH 44/53] Fixed copy/paste issue --- .../MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 index dfa8ae99c..bc9a0f7c3 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 @@ -233,8 +233,8 @@ function Get-TargetResource $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` - "to unblock the file before continuing.") + throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` + "$InstallerPath' to unblock the file before continuing.") } } @@ -639,8 +639,8 @@ function Set-TargetResource $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { - throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` - "to unblock the file before continuing.") + throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` + "$InstallerPath' to unblock the file before continuing.") } } From 54e7196ebab4d952174f4d3b5968b2aab2418f19 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Thu, 25 Apr 2019 17:10:34 +0200 Subject: [PATCH 45/53] Improved logging and fixed Site PropBag --- .../MSFT_SPInstall/MSFT_SPInstall.psm1 | 4 ++ .../MSFT_SPInstallLanguagePack.psm1 | 4 ++ .../MSFT_SPInstallPrereqs.psm1 | 4 ++ .../MSFT_SPProductUpdate.psm1 | 4 ++ .../MSFT_SPSitePropertyBag.psm1 | 54 +++++++++++-------- .../SharePointDsc.SPSitePropertyBag.Tests.ps1 | 45 ++++++++++------ 6 files changed, 76 insertions(+), 39 deletions(-) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 index e1f17710b..23233c058 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 @@ -73,12 +73,14 @@ function Get-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` "to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } $x86Path = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" @@ -242,12 +244,14 @@ function Set-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("Setup file is blocked! Please use 'Unblock-File -Path $InstallerPath' " + ` "to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } Write-Verbose -Message "Checking if Path is an UNC path" diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 index aeee18c66..f02a71a35 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallLanguagePack/MSFT_SPInstallLanguagePack.psm1 @@ -70,12 +70,14 @@ function Get-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` "to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } $osrvFolder = Get-ChildItem -Path (Join-Path -Path $BinaryDir ` @@ -285,12 +287,14 @@ function Set-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $setupExe -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("Setup file is blocked! Please use 'Unblock-File -Path $setupExe' " + ` "to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } $now = Get-Date diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 index ec57dcf15..962469846 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPInstallPrereqs/MSFT_SPInstallPrereqs.psm1 @@ -230,12 +230,14 @@ function Get-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` "$InstallerPath' to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } $majorVersion = (Get-SPDSCAssemblyVersion -PathToAssembly $InstallerPath) @@ -636,12 +638,14 @@ function Set-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $InstallerPath -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) { throw ("PrerequisitesInstaller is blocked! Please use 'Unblock-File -Path " + ` "$InstallerPath' to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } Write-Verbose -Message "Detecting SharePoint version from binaries" diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 index 75515f450..5763d4210 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 @@ -77,6 +77,7 @@ function Get-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $SetupFile -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) @@ -84,6 +85,7 @@ function Get-TargetResource throw ("Setup file is blocked! Please use 'Unblock-File -Path $SetupFile' " + ` "to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } $nullVersion = New-Object -TypeName System.Version @@ -303,6 +305,7 @@ function Set-TargetResource if ($checkBlockedFile -eq $true) { + Write-Verbose -Message "Checking status now" $zone = Get-Item -Path $SetupFile -Stream "Zone.Identifier" -EA SilentlyContinue if ($null -ne $zone) @@ -310,6 +313,7 @@ function Set-TargetResource throw ("Setup file is blocked! Please use 'Unblock-File -Path $SetupFile' " + ` "to unblock the file before continuing.") } + Write-Verbose -Message "File not blocked, continuing." } $now = Get-Date diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 index 3c3eda66f..645c7c474 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 @@ -37,24 +37,19 @@ function Get-TargetResource() if ($null -eq $spSite) { - $currentValue = $null - $localEnsure = 'Absent' + throw "Specified site collection could not be found." + } + + if ($null -ne $spSite.RootWeb.Properties -and ` + $spSite.RootWeb.Properties.ContainsKey($params.Key) -eq $true) + { + $localEnsure = 'Present' + $currentValue = $spSite.RootWeb.Properties[$params.Key] } else { - if ($spSite.RootWeb.Properties) - { - if ($spSite.RootWeb.Properties.Contains($params.Key) -eq $true) - { - $localEnsure = 'Present' - $currentValue = $spSite.RootWeb.Properties[$params.Key] - } - else - { - $localEnsure = 'Absent' - $currentValue = $null - } - } + $localEnsure = 'Absent' + $currentValue = $null } return @{ @@ -103,17 +98,32 @@ function Set-TargetResource() $spSite = Get-SPSite -Identity $params.Url -ErrorAction SilentlyContinue - if ($params.Ensure -eq 'Present') + if ($null -eq $spSite) + { + throw "Specified site collection could not be found." + } + + $spWeb = $spSite.OpenWeb() + + if ($null -ne $spWeb.Properties) { - Write-Verbose -Message "Adding property '$($params.Key)'='$($params.value)' to SPSite.RootWeb.Properties" - $spSite.RootWeb.Properties[$params.Key] = $params.Value - $spSite.Update() + if ($params.Ensure -eq 'Present') + { + Write-Verbose -Message "Adding property '$($params.Key)'='$($params.value)' to SPWeb.Properties" + $spWeb.Properties[$params.Key] = $params.Value + $spWeb.Properties.Update() + $spWeb.Update() + } + else + { + Write-Verbose -Message "Removing property '$($params.Key)' from SPWeb.AllProperties" + $spWeb.AllProperties.Remove($params.Key.ToLower()) + $spWeb.Update() + } } else { - Write-Verbose -Message "Removing property '$($params.Key)' from SPSite.RootWeb.Properties" - $spSite.RootWeb.Properties.Remove($params.Key) - $spSite.Update() + throw "Cannot retrieve the property bag. Please check if you have the correct permissions." } } } diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 index e4a7c3235..cf34de32e 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 @@ -26,11 +26,24 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } } - $spSite = $spSite | Add-Member ScriptMethod Update { - $Global:SPDscSitePropertyUpdated = $true - } -PassThru - $spSite = $spSite | Add-Member ScriptMethod Remove { - $Global:SPDscSitePropertyUpdated = $true + + $spSite = $spSite | Add-Member ScriptMethod OpenWeb { + $prop = @{ + PropertyKey = 'PropertyValue' + } + $prop = $prop | Add-Member ScriptMethod Update { + } -PassThru + + $returnval = @{ + Properties = $prop + AllProperties = @{} + } + + $returnval = $returnval | Add-Member ScriptMethod Update { + $Global:SPDscSitePropertyUpdated = $true + } -PassThru + + return $returnval } -PassThru return $spSite } @@ -45,14 +58,16 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { return $null } - $result = Get-TargetResource @testParams + It 'Should throw exception in the get method' { + { Get-TargetResource @testParams } | Should Throw "Specified site collection could not be found." + } - It 'Should return absent from the get method' { - $result.Ensure | Should Be 'absent' + It 'Should throw exception in the set method' { + { Set-TargetResource @testParams } | Should Throw "Specified site collection could not be found." } - It 'Should return null value from the get method' { - $result.Value | Should Be $null + It 'Should throw exception in the test method' { + { Test-TargetResource @testParams } | Should Throw "Specified site collection could not be found." } } @@ -64,14 +79,10 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure ='Present' } - $result = Get-TargetResource @testParams - It 'Should return present from the get method' { - $result.Ensure | Should Be 'present' - } - - It 'Should return the same key value as passed as parameter' { - $result.Key | Should Be $testParams.Key + $result = Get-TargetResource @testParams + $result.Ensure | Should Be 'Present' + $result.Key | Should Be $testParams.Key } It 'Should return false from the test method' { From 6364a8ce79dbcd5a6d5f8b260d175de93fff8642 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 25 Apr 2019 15:00:16 -0400 Subject: [PATCH 46/53] Adding Pester test for extending CA with SSL --- .../SharePointDsc.SPFarm.Tests.ps1 | 117 +++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-) diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 index 8ee0c1032..b7e4c14e2 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 @@ -51,6 +51,8 @@ namespace Microsoft.SharePoint.Administration { Mock -CommandName Install-SPService -MockWith { } Mock -CommandName Install-SPFeature -MockWith { } Mock -CommandName New-SPCentralAdministration -MockWith { } + Mock -CommandName Remove-SPWebApplication -MockWith { } + Mock -CommandName New-SPWebApplicationExtension -MockWith { } Mock -CommandName Start-Sleep -MockWith { } Mock -CommandName Start-Service -MockWith { } Mock -CommandName Stop-Service -MockWith { } @@ -102,8 +104,9 @@ namespace Microsoft.SharePoint.Administration { It "Should throw exception in the set method" { { Set-TargetResource @testParams } | Should Throw "An invalid value for CentralAdministrationPort is specified:" } + } - # Repeat tests for invalid URL + Context -Name "Invalid CA URL has been passed in" -Fixture { $testParams = @{ IsSingleInstance = "Yes" Ensure = "Present" @@ -735,8 +738,42 @@ namespace Microsoft.SharePoint.Administration { }) } Mock -CommandName Get-SPWebApplication -MockWith { - return [fake_sp_web_application]::new($testParams.CentralAdministrationUrl, "different.contoso.com") + # return [fake_sp_web_application]::new($testParams.CentralAdministrationUrl, "different.contoso.com") + $webapp = @{ + ContentDatabases = @( + @{ + Name = $testParams.AdminContentDatabaseName + } + ) + Url = $testParams.CentralAdministrationUrl + IsAdministrationWebApplication = $true + IisSettings = [ordered]@{ + Default = @{ + DisableKerberos = $true + SecureBindings = @( + @{ + HostHeader = "different.contoso.com" + Port = "443" + } + ) + } + } + } + + $webapp | Add-Member -MemberType ScriptMethod -Name GetIisSettingsWithFallback -Value { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string] + $Zone + ) + + return $this.IisSettings[$Zone] + } + + return $webapp } + Mock -CommandName Get-CimInstance -MockWith { return @{ Domain = "domain.com" @@ -790,6 +827,82 @@ namespace Microsoft.SharePoint.Administration { } } + Context -Name "Server not yet part of the farm, and will run Central Admin on HTTPS" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Ensure = "Present" + FarmConfigDatabaseName = "SP_Config" + DatabaseServer = "sql.contoso.com" + FarmAccount = $mockFarmAccount + Passphrase = $mockPassphrase + AdminContentDatabaseName = "SP_AdminContent" + CentralAdministrationUrl = "https://admin.contoso.com" + RunCentralAdmin = $true + } + + Mock -CommandName "Get-SPDSCRegistryKey" -MockWith { return $null } + Mock -CommandName "Get-SPFarm" -MockWith { return $null } + Mock -CommandName "Get-SPDSCConfigDBStatus" -MockWith { + return @{ + Locked = $false + ValidPermissions = $true + DatabaseExists = $true + } + } + Mock -CommandName "Get-SPDSCSQLInstanceStatus" -MockWith { + return @{ + MaxDOPCorrect = $true + } + } + + Mock -CommandName "Get-SPWebApplication" -MockWith { + return @{ + IsAdministrationWebApplication = $true + ContentDatabases = @(@{ + Name = $testParams.AdminContentDatabaseName + }) + Url = "http://localhost:9999" + } + } + Mock -CommandName "Get-SPServiceInstance" -MockWith { + if ($global:SPDscCentralAdminCheckDone -eq $true) + { + return @( + @{ + Name = "WSS_Administration" + } | Add-Member -MemberType ScriptMethod ` + -Name GetType ` + -Value { + return @{ + Name = "SPWebServiceInstance" + } + } -PassThru -Force + ) + } + else + { + $global:SPDscCentralAdminCheckDone = $true + return $null + } + } + + It "Should return absent from the get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + } + + It "Should return false from the test method" { + Test-TargetResource @testParams | Should be $false + } + + $global:SPDscCentralAdminCheckDone = $false + It "Should provision, remove, and re-extend CA web application in the set method" { + Set-TargetResource @testParams + Assert-MockCalled -CommandName "New-SPCentralAdministration" + Assert-MockCalled -CommandName "Remove-SPWebApplication" + Assert-MockCalled -CommandName "New-SPWebApplicationExtension" + } + } + Context -Name "This server is running CA on HTTPS, but secure bindings do not contain valid hostname" -Fixture { $testParams = @{ IsSingleInstance = "Yes" From b8b223755ae0e31d4d7da9fa72a61b17fe055ef9 Mon Sep 17 00:00:00 2001 From: Rob Christie Date: Thu, 25 Apr 2019 15:04:34 -0400 Subject: [PATCH 47/53] Replace mock classes with glorified hashtables --- .../SharePointDsc.SPFarm.Tests.ps1 | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 index b7e4c14e2..704b4100d 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 @@ -659,38 +659,6 @@ namespace Microsoft.SharePoint.Administration { } } - class fake_sp_iis_settings { - [hashtable[]] $SecureBindings = @( - @{ - HostHeader = "admin.contoso.com" - Port = "443" - } - ) - [bool] $DisableKerberos = $true - - fake_sp_iis_settings([string] $HostHeader) { - $this.SecureBindings[0].HostHeader = $HostHeader - } - } - - class fake_sp_web_application { - [fake_sp_iis_settings] $IisSettings - [bool] $IsAdministrationWebApplication = $true - [string] $Url - [hashtable[]] $ContentDatabases = @(@{ - Name = "SP_AdminContent" - }) - - fake_sp_web_application([string] $Url, [string] $IisHostHeader) { - $this.Url = $Url - $this.IisSettings = [fake_sp_iis_settings]::new($IisHostHeader) - } - - [fake_sp_iis_settings] GetIisSettingsWithFallback([string] $Zone) { - return $this.IisSettings - } - } - Context -Name "This server is running CA on HTTPS, but secure bindings do not match CA URL" -Fixture { $testParams = @{ IsSingleInstance = "Yes" @@ -738,7 +706,6 @@ namespace Microsoft.SharePoint.Administration { }) } Mock -CommandName Get-SPWebApplication -MockWith { - # return [fake_sp_web_application]::new($testParams.CentralAdministrationUrl, "different.contoso.com") $webapp = @{ ContentDatabases = @( @{ @@ -950,7 +917,39 @@ namespace Microsoft.SharePoint.Administration { }) } Mock -CommandName Get-SPWebApplication -MockWith { - return [fake_sp_web_application]::new($testParams.CentralAdministrationUrl, "") + $webapp = @{ + ContentDatabases = @( + @{ + Name = $testParams.AdminContentDatabaseName + } + ) + Url = $testParams.CentralAdministrationUrl + IsAdministrationWebApplication = $true + IisSettings = [ordered]@{ + Default = @{ + DisableKerberos = $true + SecureBindings = @( + @{ + HostHeader = "" + Port = "443" + } + ) + } + } + } + + $webapp | Add-Member -MemberType ScriptMethod -Name GetIisSettingsWithFallback -Value { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string] + $Zone + ) + + return $this.IisSettings[$Zone] + } + + return $webapp } Mock -CommandName Get-CimInstance -MockWith { return @{ From cde7503af7eda7440a2a47145ed3f99e8475d414 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Fri, 3 May 2019 23:15:40 +0200 Subject: [PATCH 48/53] Fixed issue introduced in merge with Dev --- .../SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 8d44723ce..17f8148ef 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -195,6 +195,11 @@ function Get-TargetResource $farmAccount = $spFarm.DefaultServiceAccount.Name } + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } + $centralAdminProvisioned = $false $ca = Get-SPServiceInstance -Server $env:ComputerName if ($null -ne $ca) From a9d804ffa96c9ceef8d73142168826fc79b621d9 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Mon, 6 May 2019 13:11:04 +0200 Subject: [PATCH 49/53] Updated tests to cover changes --- .../SharePointDsc.SPInstall.Tests.ps1 | 41 +++++- ...rePointDsc.SPInstallLanguagePack.Tests.ps1 | 69 +++++++++ .../SharePointDsc.SPInstallPrereqs.Tests.ps1 | 64 +++++++++ .../SharePointDsc.SPProductUpdate.Tests.ps1 | 133 ++++++++++++++++++ 4 files changed, 306 insertions(+), 1 deletion(-) diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstall.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstall.Tests.ps1 index f42894f31..8f425e15f 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstall.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstall.Tests.ps1 @@ -169,8 +169,47 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } - It "Should return absent from the get method" { + It "Should add unc as trusted source and run install in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Start-Process + } + } + + Context -Name "SharePoint binaries are not installed but should be using CDROM drive" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + BinaryDir = "C:\SPInstall" + ProductKey = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" + Ensure = "Present" + } + + Mock -CommandName Test-Path -MockWith { + return $false + } -ParameterFilter { $Path -eq (Join-Path -Path $BinaryDir -ChildPath "updates\svrsetup.dll") } + + Mock -CommandName Get-Item -MockWith { + return $null + } + + Mock -CommandName Get-Volume -MockWith { + return @{ + DriveType = "CD-ROM" + } + } + + Mock -CommandName Get-ItemProperty -MockWith { + return $null + } + + Mock -CommandName Start-Process -MockWith { + return @{ + ExitCode = 0 + } + } + + It "Should not run unblock test and run install in the set method" { Set-TargetResource @testParams + Assert-MockCalled Get-Item -Times 0 Assert-MockCalled Start-Process } } diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallLanguagePack.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallLanguagePack.Tests.ps1 index 8f83646cb..6b8f75e22 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallLanguagePack.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallLanguagePack.Tests.ps1 @@ -684,6 +684,75 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } + Context -Name "Language Pack is not installed, installation executed successfully using CDROM drive" -Fixture { + $testParams = @{ + BinaryDir = "C:\SPInstall" + Ensure = "Present" + } + + Mock -CommandName Get-SPDscFarmProductsInfo -MockWith { + switch ($Global:SPDscHelper.CurrentStubBuildNumber.Major) + { + 15 { + return @("Microsoft SharePoint Server 2013") + } + 16 { + if($Global:SPDscHelper.CurrentStubBuildNumber.Minor.ToString().Length -le 4) + { + return @("Microsoft SharePoint Server 2016") + } + else + { + return @("Microsoft SharePoint Server 2019") + } + } + Default { + throw [Exception] "A supported version of SharePoint was not used in testing" + } + } + } + + Mock -CommandName Get-SPDscRegProductsInfo -MockWith { + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 15) + { + return @("Microsoft SharePoint Server 2013") + } + else + { + if($Global:SPDscHelper.CurrentStubBuildNumber.Minor.ToString().Length -le 4) + { + return @("Microsoft SharePoint Server 2016") + } + else + { + return @("Microsoft SharePoint Server 2019") + } + } + } + + Mock -CommandName Get-Volume -MockWith { + return @{ + DriveType = "CD-ROM" + } + } + + Mock -CommandName Get-Item -MockWith { + return $null + } + + Mock -CommandName Start-Process -MockWith { + return @{ + ExitCode = 0 + } + } + + It "Should not unblock file and run the Start-Process function in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Get-Item -Times 0 + Assert-MockCalled Start-Process + } + } + Context -Name "Language Pack is not installed, installation executed, reboot required" -Fixture { $testParams = @{ BinaryDir = "C:\SPInstall" diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 index a8cdeda7c..b994a81fe 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 @@ -537,6 +537,70 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } + Context -Name "Prerequisites are not installed but should be and are to be installed in offline mode from CDROM" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + InstallerPath = "C:\SPInstall\Prerequisiteinstaller.exe" + OnlineMode = $false + Ensure = "Present" + } + + Mock -CommandName Get-ItemProperty -MockWith { + return @() + } -ParameterFilter { $null -ne $Path } + + Mock -CommandName Get-Item -MockWith { + return $null + } -ParameterFilter { $Path.StartsWith("C:\") } + + Mock -CommandName Get-Volume -MockWith { + return @{ + DriveType = "CD-ROM" + } + } + + Mock -CommandName Start-Process -MockWith { + return @{ + ExitCode = 0 + } + } + Mock -CommandName Test-Path -MockWith { + return $true + } + + switch ($Global:SPDscHelper.CurrentStubBuildNumber.Major) + { + 15 { + $requiredParams = @("SQLNCli","PowerShell","NETFX","IDFX","Sync","AppFabric","IDFX11","MSIPCClient","WCFDataServices","KB2671763","WCFDataServices56") + } + 16 { + if ($Global:SPDscHelper.CurrentStubBuildNumber.Build -lt 10000) + { + # SharePoint 2016 + $requiredParams = @("SQLNCli","Sync","AppFabric","IDFX11","MSIPCClient","KB3092423","WCFDataServices56","DotNetFx","MSVCRT11","MSVCRT14","ODBC") + } + else + { + # SharePoint 2019 + $requiredParams = @("SQLNCli","Sync","AppFabric","IDFX11","MSIPCClient","KB3092423","WCFDataServices56","DotNet472","MSVCRT11","MSVCRT141") + } + } + Default { + throw [Exception] "A supported version of SharePoint was not used in testing" + } + } + + $requiredParams | ForEach-Object -Process { + $testParams.Add($_, "C:\fake\value.exe") + } + + It "does not throw an exception where the required parameters are included" { + Set-TargetResource @testParams + Assert-MockCalled Get-Item -Times 0 + Assert-MockCalled Start-Process + } + } + Context -Name "Prerequisites are not installed but should be and are to be installed in offline mode, but invalid paths have been passed" -Fixture { $testParams = @{ IsSingleInstance = "Yes" diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPProductUpdate.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPProductUpdate.Tests.ps1 index 787cfd50a..7769d49b6 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPProductUpdate.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPProductUpdate.Tests.ps1 @@ -1136,6 +1136,139 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } + Context -Name "Update CU has higher version, update required - Install from CDROM" -Fixture { + $testParams = @{ + SetupFile = "C:\ubersrv2013-kb3115029-fullfile-x64-glb.exe" + ShutdownServices = $true + Ensure = "Present" + } + + Add-TestRegistryData -PatchLevel "CU" + + Mock -CommandName Get-Item -MockWith { + return $null + } + + Mock -CommandName Get-Volume -MockWith { + return @{ + DriveType = "CD-ROM" + } + } + + Mock -CommandName Get-ItemProperty -MockWith { + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 15) + { + return @{ + VersionInfo = @{ + FileVersion = "15.0.5119" + FileDescription = "Cumulative Update" + } + Name = "serverlpksp2013-kb2880554-fullfile-x64-en-us.exe" + } + } + else + { + if ($Global:SPDscHelper.CurrentStubBuildNumber.Build.ToString().Length -eq 4) + { + return @{ + VersionInfo = @{ + FileVersion = "16.0.4882" + FileDescription = "Cumulative Update" + } + Name = "serverlpksp2016-kb2880554-fullfile-x64-en-us.exe" + } + } + else + { + return @{ + VersionInfo = @{ + FileVersion = "16.0.10342" + FileDescription = "Cumulative Update" + } + Name = "serverlpksp2019-kb2880554-fullfile-x64-en-us.exe" + } + } + } + } -ParameterFilter { + $Path -and $Path.Length -eq 1 -and $Path[0].StartsWith("C:\") + } + + $installerMock = New-Module -AsCustomObject -ScriptBlock { + function GetType { # Installer + New-Module -AsCustomObject -ScriptBlock { + function InvokeMember { + New-Module -AsCustomObject -ScriptBlock { + function GetType { # InstallerDB + New-Module -AsCustomObject -ScriptBlock { + function InvokeMember { + New-Module -AsCustomObject -ScriptBlock { + function GetType { # DBView + New-Module -AsCustomObject -ScriptBlock { + function InvokeMember { + param ($a, $b, $c, $d, $e) + if ($a -eq "Fetch") + { + New-Module -AsCustomObject -ScriptBlock { + function GetType { # Value + New-Module -AsCustomObject -ScriptBlock { + function InvokeMember { + param ($a, $b, $c, $d, $e) + if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 15) + { + return "15.0.5075" + } + else + { + if ($Global:SPDscHelper.CurrentStubBuildNumber.Build.ToString().Length -eq 4) + { + return "16.0.4705" + } + else + { + return "16.0.10340" + } + } + } + } + } + } + } + else + { + return $null + } + } + } + } + } + } + } + } + } + } + } + } + Export-ModuleMember -Variable * -Function * + } + + Mock New-Object { return $installerMock } -ParameterFilter { $ComObject -eq 'WindowsInstaller.Installer' } + + It "Should return Ensure is Absent from the get method" { + $result = Get-TargetResource @testParams + $result.Ensure | Should Be "Absent" + } + + It "Should run the Start-Process function in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Get-Item -Times 0 + Assert-MockCalled Start-Process + } + + It "Should return false from the test method" { + Test-TargetResource @testParams | Should Be $false + } + } + Context -Name "Update CU has higher version, update required - Update requires reboot" -Fixture { $testParams = @{ SetupFile = "C:\Install\CUMay2016\ubersrv2013-kb3115029-fullfile-x64-glb.exe" From 06d481e25877e2f1e63e4035edbaa27f13735e4a Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Thu, 9 May 2019 21:11:02 +0200 Subject: [PATCH 50/53] Added FilePath option for SPTrustedRootAuthority #945 --- CHANGELOG.md | 2 + .../MSFT_SPTrustedRootAuthority.psm1 | 172 ++++++++- .../MSFT_SPTrustedRootAuthority.schema.mof | 3 +- ... => 1-AddRootAuthorityCertInCertStore.ps1} | 10 +- .../2-AddRootAuthorityCertInFilePath.ps1 | 24 ++ ...-RemoveExample.ps1 => 3-RemoveExample.ps1} | 10 +- ...Dsc.SPTrustedIdentityTokenIssuer.Tests.ps1 | 44 +-- ...ePointDsc.SPTrustedRootAuthority.Tests.ps1 | 336 ++++++++++++++++-- 8 files changed, 517 insertions(+), 84 deletions(-) rename Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/{1-Example.ps1 => 1-AddRootAuthorityCertInCertStore.ps1} (57%) create mode 100644 Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-AddRootAuthorityCertInFilePath.ps1 rename Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/{2-RemoveExample.ps1 => 3-RemoveExample.ps1} (57%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b68289af..c86163d0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ * SPSubscriptionSettingsServiceApp * Fixed issue where the service app proxy isn't created when it wasn't created during initial deployment. +* SPTrustedRootAuthority + * Added possibility to get certificate from file. ## v3.3 diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.psm1 index 900aa622d..81efed1d5 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.psm1 @@ -8,10 +8,14 @@ function Get-TargetResource [System.String] $Name, - [Parameter(Mandatory = $true)] + [Parameter()] [System.String] $CertificateThumbprint, + [Parameter()] + [String] + $CertificateFilePath, + [Parameter()] [ValidateSet("Present","Absent")] [System.String] @@ -23,6 +27,29 @@ function Get-TargetResource ) Write-Verbose "Getting Trusted Root Authority with name '$Name'" + + if ($PSBoundParameters.ContainsKey("CertificateThumbprint") -and ` + $PSBoundParameters.ContainsKey("CertificateFilePath")) + { + Write-Verbose -Message ("Cannot use both parameters CertificateThumbprint and " + ` + "CertificateFilePath at the same time.") + } + + if (-not ($PSBoundParameters.ContainsKey("CertificateThumbprint")) -and ` + -not($PSBoundParameters.ContainsKey("CertificateFilePath"))) + { + Write-Verbose -Message ("At least one of the following parameters must be specified: " + ` + "CertificateThumbprint, CertificateFilePath.") + } + + if ($PSBoundParameters.ContainsKey("CertificateFilePath")) + { + if (-not(Test-Path -Path $CertificateFilePath)) + { + throw ("Specified CertificateFilePath does not exist: $CertificateFilePath") + } + } + $result = Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { @@ -32,12 +59,13 @@ function Get-TargetResource $ensure = "Absent" - if($null -eq $rootCert) + if ($null -eq $rootCert) { return @{ - Name = $params.Name + Name = $params.Name CertificateThumbprint = [string]::Empty - Ensure = $ensure + CertificateFilePath = "" + Ensure = $ensure } } else @@ -45,9 +73,10 @@ function Get-TargetResource $ensure = "Present" return @{ - Name = $params.Name + Name = $params.Name CertificateThumbprint = $rootCert.Certificate.Thumbprint - Ensure = $ensure + CertificateFilePath = "" + Ensure = $ensure } } } @@ -64,10 +93,14 @@ function Set-TargetResource [System.String] $Name, - [Parameter(Mandatory = $true)] + [Parameter()] [System.String] $CertificateThumbprint, + [Parameter()] + [String] + $CertificateFilePath, + [Parameter()] [ValidateSet("Present","Absent")] [System.String] @@ -80,6 +113,28 @@ function Set-TargetResource Write-Verbose -Message "Setting SPTrustedRootAuthority '$Name'" + if ($PSBoundParameters.ContainsKey("CertificateThumbprint") -and ` + $PSBoundParameters.ContainsKey("CertificateFilePath")) + { + throw ("Cannot use both parameters CertificateThumbprint and CertificateFilePath " + ` + "at the same time.") + } + + if (-not ($PSBoundParameters.ContainsKey("CertificateThumbprint")) -and ` + -not($PSBoundParameters.ContainsKey("CertificateFilePath"))) + { + throw ("At least one of the following parameters must be specified: " + ` + "CertificateThumbprint, CertificateFilePath.") + } + + if ($PSBoundParameters.ContainsKey("CertificateFilePath")) + { + if (-not(Test-Path -Path $CertificateFilePath)) + { + throw ("Specified CertificateFilePath does not exist: $CertificateFilePath") + } + } + $CurrentValues = Get-TargetResource @PSBoundParameters if ($Ensure -eq "Present" -and $CurrentValues.Ensure -eq "Present") { @@ -88,25 +143,52 @@ function Set-TargetResource -Arguments $PSBoundParameters ` -ScriptBlock { $params = $args[0] - $cert = Get-Item -Path "CERT:\LocalMachine\My\$($params.CertificateThumbprint)" ` - -ErrorAction SilentlyContinue - if ($null -eq $cert) + if ($params.ContainsKey("CertificateThumbprint")) { - throw "Certificate not found in the local Certificate Store" + Write-Verbose -Message "Importing certificate from CertificateThumbprint" + $cert = Get-Item -Path "CERT:\LocalMachine\My\$($params.CertificateThumbprint)" ` + -ErrorAction SilentlyContinue + + if ($null -eq $cert) + { + throw "Certificate not found in the local Certificate Store" + } + } + + if ($params.ContainsKey("CertificateFilePath")) + { + Write-Verbose -Message "Importing certificate from CertificateFilePath" + try + { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 + $cert.Import($CertificateFilePath) + } + catch + { + throw "An error occured: $($_.Exception.Message)" + } + + if ($null -eq $cert) + { + throw "Import of certificate failed." + } } if ($cert.HasPrivateKey) { + Write-Verbose -Message "Certificate has private key. Removing private key." $pubKeyBytes = $cert.Export("cert") $cert2 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert2.Import($pubKeyBytes) $cert = $cert2 } + Write-Verbose -Message "Updating Root Authority" Set-SPTrustedRootAuthority -Identity $params.Name -Certificate $cert } } + if ($Ensure -eq "Present" -and $CurrentValues.Ensure -eq "Absent") { Write-Verbose -Message "Adding SPTrustedRootAuthority '$Name'" @@ -115,22 +197,47 @@ function Set-TargetResource -ScriptBlock { $params = $args[0] - $cert = Get-Item -Path "CERT:\LocalMachine\My\$($params.CertificateThumbprint)" ` - -ErrorAction SilentlyContinue + if ($params.ContainsKey("CertificateThumbprint")) + { + Write-Verbose -Message "Importing certificate from CertificateThumbprint" + $cert = Get-Item -Path "CERT:\LocalMachine\My\$($params.CertificateThumbprint)" ` + -ErrorAction SilentlyContinue + + if ($null -eq $cert) + { + throw "Certificate not found in the local Certificate Store" + } + } - if($null -eq $cert) + if ($params.ContainsKey("CertificateFilePath")) { - throw "Certificate not found in the local Certificate Store" + Write-Verbose -Message "Importing certificate from CertificateFilePath" + try + { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 + $cert.Import($CertificateFilePath) + } + catch + { + throw "An error occured: $($_.Exception.Message)" + } + + if ($null -eq $cert) + { + throw "Import of certificate failed." + } } - if($cert.HasPrivateKey) + if ($cert.HasPrivateKey) { + Write-Verbose -Message "Certificate has private key. Removing private key." $pubKeyBytes = $cert.Export("cert") $cert2 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert2.Import($pubKeyBytes) $cert = $cert2 } + Write-Verbose -Message "Creating Root Authority" New-SPTrustedRootAuthority -Name $params.Name -Certificate $cert } } @@ -157,10 +264,14 @@ function Test-TargetResource [System.String] $Name, - [Parameter(Mandatory = $true)] + [Parameter()] [System.String] $CertificateThumbprint, + [Parameter()] + [String] + $CertificateFilePath, + [Parameter()] [ValidateSet("Present","Absent")] [System.String] @@ -173,8 +284,33 @@ function Test-TargetResource Write-Verbose -Message "Testing SPTrustedRootAuthority '$Name'" + if ($PSBoundParameters.ContainsKey("CertificateThumbprint") -and ` + $PSBoundParameters.ContainsKey("CertificateFilePath")) + { + throw ("Cannot use both parameters CertificateThumbprint and CertificateFilePath " + ` + "at the same time.") + } + + if (-not ($PSBoundParameters.ContainsKey("CertificateThumbprint")) -and ` + -not($PSBoundParameters.ContainsKey("CertificateFilePath"))) + { + throw ("At least one of the following parameters must be specified: " + ` + "CertificateThumbprint, CertificateFilePath.") + } + $CurrentValues = Get-TargetResource @PSBoundParameters - if($Ensure -eq "Present") + + if ($PSBoundParameters.ContainsKey("CertificateFilePath")) + { + Write-Verbose "Retrieving thumbprint of CertificateFilePath" + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 + $cert.Import($CertificateFilePath) + + Write-Verbose "Thumbprint is $($cert.Thumbprint)" + $PSBoundParameters.CertificateThumbprint = $cert.Thumbprint + } + + if ($Ensure -eq "Present") { return Test-SPDscParameterState -CurrentValues $CurrentValues ` -DesiredValues $PSBoundParameters ` diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof b/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof index 8fcfc08df..480745511 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof @@ -3,7 +3,8 @@ class MSFT_SPTrustedRootAuthority : OMI_BaseResource { [Key, Description("Specifies the name of the trusted root authority to create.")] String Name; - [Required, Description("Specifies the X.509 certificate of the trusted root authority, as a certificate thumbprint.")] String CertificateThumbprint; + [Write, Description("Specifies the X.509 certificate of the trusted root authority, as a certificate thumbprint.")] String CertificateThumbprint; + [Write, Description("Specify the file path to the certificate if it is not stored in the local certificate store already")] String CertificateFilePath; [Write, Description("Present ensures the trusted root authority exists, absent ensures it is removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, EmbeddedInstance("MSFT_Credential"), Description("POWERSHELL 4 ONLY: The account to run this resource as, use PsDscRunAsCredential if using PowerShell 5")] String InstallAccount; }; diff --git a/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/1-Example.ps1 b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/1-AddRootAuthorityCertInCertStore.ps1 similarity index 57% rename from Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/1-Example.ps1 rename to Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/1-AddRootAuthorityCertInCertStore.ps1 index 1556c7225..98ddb44e4 100644 --- a/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/1-Example.ps1 +++ b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/1-AddRootAuthorityCertInCertStore.ps1 @@ -3,7 +3,7 @@ This example deploys a SP Trusted Root Authority to the local farm. #> - Configuration Example + Configuration Example { param( [Parameter(Mandatory = $true)] @@ -15,10 +15,10 @@ node localhost { SPTrustedRootAuthority SampleRootAuthority { - Name = "Contoso" - CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" - Ensure = "Present" - PsDscRunAsCredential = $SetupAccount + Name = "Contoso" + CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + Ensure = "Present" + PsDscRunAsCredential = $SetupAccount } } } diff --git a/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-AddRootAuthorityCertInFilePath.ps1 b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-AddRootAuthorityCertInFilePath.ps1 new file mode 100644 index 000000000..98e1c7b3a --- /dev/null +++ b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-AddRootAuthorityCertInFilePath.ps1 @@ -0,0 +1,24 @@ +<# +.EXAMPLE + This example deploys a SP Trusted Root Authority to the local farm. +#> + + Configuration Example + { + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $SetupAccount + ) + Import-DscResource -ModuleName SharePointDsc + + node localhost { + SPTrustedRootAuthority SampleRootAuthority + { + Name = "Contoso" + CertificateFilePath = "C:\Certificates\RootAuthority.cer" + Ensure = "Present" + PsDscRunAsCredential = $SetupAccount + } + } + } diff --git a/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-RemoveExample.ps1 b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveExample.ps1 similarity index 57% rename from Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-RemoveExample.ps1 rename to Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveExample.ps1 index e253034a3..5ad43176f 100644 --- a/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-RemoveExample.ps1 +++ b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveExample.ps1 @@ -3,7 +3,7 @@ This example removes a SP Trusted Root Authority from the local farm. #> - Configuration Example + Configuration Example { param( [Parameter(Mandatory = $true)] @@ -15,10 +15,10 @@ node localhost { SPTrustedRootAuthority SampleRootAuthority { - Name = "Contoso" - CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" - Ensure = "Absent" - PsDscRunAsCredential = $SetupAccount + Name = "Contoso" + CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + Ensure = "Absent" + PsDscRunAsCredential = $SetupAccount } } } diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 index 845035c20..e26bc27cd 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedIdentityTokenIssuer.Tests.ps1 @@ -1,7 +1,7 @@ [CmdletBinding()] param( [Parameter()] - [string] + [string] $SharePointCmdletModule = (Join-Path -Path $PSScriptRoot ` -ChildPath "..\Stubs\SharePoint\15.0.4805.1000\Microsoft.SharePoint.PowerShell.psm1" ` -Resolve) @@ -18,7 +18,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { InModuleScope -ModuleName $Global:SPDscHelper.ModuleName -ScriptBlock { Invoke-Command -ScriptBlock $Global:SPDscHelper.InitializeScript -NoNewScope - # Mocks for all contexts + # Mocks for all contexts Mock -CommandName Get-ChildItem -MockWith { return @( @{ @@ -49,31 +49,31 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { }) } - try - { - [Microsoft.SharePoint.Administration.SPUrlZone] + try + { + [Microsoft.SharePoint.Administration.SPUrlZone] } - catch + catch { Add-Type -TypeDefinition @" namespace Microsoft.SharePoint.Administration { public enum SPUrlZone { Default, Intranet, Internet, Custom, Extranet }; -} +} "@ } - try - { - [Microsoft.SharePoint.Administration.SPTrustedAuthenticationProvider] + try + { + [Microsoft.SharePoint.Administration.SPTrustedAuthenticationProvider] } - catch + catch { Add-Type -TypeDefinition @" namespace Microsoft.SharePoint.Administration { public class SPTrustedAuthenticationProvider {} -} +} "@ - } + } # Test contexts Context -Name "The SPTrustedLoginProvider does not exist but should, using a signing certificate in the certificate store" -Fixture { @@ -185,7 +185,7 @@ namespace Microsoft.SharePoint.Administration { ClaimProviderName = "LDAPCP" ProviderSignOutUri = "https://adfs.contoso.com/adfs/ls/" Ensure = "Present" - } + } It "should fail validation of signing certificate parameters in the set method" { { Set-TargetResource @testParams } | Should Throw "Cannot use both parameters SigningCertificateThumbprint and SigningCertificateFilePath at the same time." @@ -213,7 +213,7 @@ namespace Microsoft.SharePoint.Administration { ClaimProviderName = "LDAPCP" ProviderSignOutUri = "https://adfs.contoso.com/adfs/ls/" Ensure = "Present" - } + } It "should fail validation of signing certificate parameters in the set method" { { Set-TargetResource @testParams } | Should Throw "At least one of the following parameters must be specified: SigningCertificateThumbprint, SigningCertificateFilePath." @@ -286,7 +286,7 @@ namespace Microsoft.SharePoint.Administration { { Set-TargetResource @testParams } | Should Throw "SharePoint requires that the private key of the signing certificate is not installed in the certificate store." } } - + Context -Name "The SPTrustedLoginProvider does not exist but should, with a claims provider that exists on the farm" -Fixture { $testParams = @{ Name = "Contoso" @@ -319,7 +319,7 @@ namespace Microsoft.SharePoint.Administration { $sptrust| Add-Member -Name Update -MemberType ScriptMethod -Value { } return $sptrust } - + It "Should create the SPTrustedLoginProvider with claims provider set" { Set-TargetResource @testParams $getResults = Get-TargetResource @testParams @@ -417,11 +417,11 @@ namespace Microsoft.SharePoint.Administration { $spAP | Add-Member -Name Update -MemberType ScriptMethod -Value { } $spAP | Add-Member -MemberType ScriptMethod ` -Name GetType ` - -Value { - return @{ - FullName = "Microsoft.SharePoint.Administration.SPTrustedAuthenticationProvider" - } - } -PassThru -Force + -Value { + return @{ + FullName = "Microsoft.SharePoint.Administration.SPTrustedAuthenticationProvider" + } + } -PassThru -Force return $spAP } diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedRootAuthority.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedRootAuthority.Tests.ps1 index 754fb0775..ade92d432 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedRootAuthority.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPTrustedRootAuthority.Tests.ps1 @@ -18,14 +18,15 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { InModuleScope -ModuleName $Global:SPDscHelper.ModuleName -ScriptBlock { Invoke-Command -ScriptBlock $Global:SPDscHelper.InitializeScript -NoNewScope - Mock -CommandName Remove-SPTrustedRootAuthority -MockWith { } + Mock -CommandName Remove-SPTrustedRootAuthority -MockWith { } Mock -CommandName Set-SPTrustedRootAuthority -MockWith { } Mock -CommandName New-SPTrustedRootAuthority -MockWith { } - Context -Name "When TrustedRootAuthority should exist and does exist in the farm." -Fixture { + Context -Name "When both CertificalThumbprint and CertificateFilePath are specified" -Fixture { $testParams = @{ Name = "CertIdentifier" CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + CertificateFilePath = "C:\cert.cer" Ensure = "Present" } @@ -36,6 +37,180 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } + Mock -CommandName Test-Path -MockWith { + return $true + } + + Mock -CommandName Get-SPTrustedRootAuthority -MockWith { + return @{ + Name = $testParams.Name + Certificate = @{ + Thumbprint = $testParams.CertificateThumbprint + } + } + } + + It "Should return Present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return true when the Test method is called" { + { Test-TargetResource @testParams } | Should Throw "Cannot use both parameters CertificateThumbprint and CertificateFilePath" + } + + It "Should Update the SP Trusted Root Authority in the set method" { + { Set-TargetResource @testParams } | Should Throw "Cannot use both parameters CertificateThumbprint and CertificateFilePath" + } + } + + Context -Name "When neither CertificalThumbprint and CertificateFilePath are specified" -Fixture { + $testParams = @{ + Name = "CertIdentifier" + Ensure = "Present" + } + + Mock -CommandName Get-Item -MockWith { + return @{ + Subject = "CN=CertName" + Thumbprint = $testParams.CertificateThumbprint + } + } + + Mock -CommandName Test-Path -MockWith { + return $true + } + + Mock -CommandName Get-SPTrustedRootAuthority -MockWith { + return @{ + Name = $testParams.Name + Certificate = @{ + Thumbprint = $testParams.CertificateThumbprint + } + } + } + + It "Should return Present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return true when the Test method is called" { + { Test-TargetResource @testParams } | Should Throw "At least one of the following parameters must be specified" + } + + It "Should Update the SP Trusted Root Authority in the set method" { + { Set-TargetResource @testParams } | Should Throw "At least one of the following parameters must be specified" + } + } + + Context -Name "When specified CertificateFilePath does not exist" -Fixture { + $testParams = @{ + Name = "CertIdentifier" + CertificateFilePath = "C:\cert.cer" + Ensure = "Present" + } + + Mock -CommandName Get-Item -MockWith { + return @{ + Subject = "CN=CertName" + Thumbprint = $testParams.CertificateThumbprint + } + } + + Mock -CommandName Test-Path -MockWith { + return $false + } + + Mock -CommandName Get-SPTrustedRootAuthority -MockWith { + return @{ + Name = $testParams.Name + Certificate = @{ + Thumbprint = $testParams.CertificateThumbprint + } + } + } + + It "Should return Present from the Get method" { + { Get-TargetResource @testParams } | Should Throw "Specified CertificateFilePath does not exist" + } + + It "Should return true when the Test method is called" { + { Test-TargetResource @testParams } | Should Throw "Specified CertificateFilePath does not exist" + } + + It "Should Update the SP Trusted Root Authority in the set method" { + { Set-TargetResource @testParams } | Should Throw "Specified CertificateFilePath does not exist" + } + } + +## CertFile - RA does not exist + + Context -Name "When TrustedRootAuthority should exist and does exist in the farm (Thumbprint)." -Fixture { + $testParams = @{ + Name = "CertIdentifier" + CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + Ensure = "Present" + } + + Mock -CommandName Get-Item -MockWith { + return @{ + Subject = "CN=CertName" + Thumbprint = $testParams.CertificateThumbprint + } + } + + Mock -CommandName Get-SPTrustedRootAuthority -MockWith { + return @{ + Name = $testParams.Name + Certificate = @{ + Thumbprint = $testParams.CertificateThumbprint + } + } + } + + It "Should return Present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return true when the Test method is called" { + Test-TargetResource @testParams | Should Be $true + } + + It "Should Update the SP Trusted Root Authority in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Get-SPTrustedRootAuthority -Times 1 + Assert-MockCalled Set-SPTrustedRootAuthority -Times 1 + } + } + + Context -Name "When TrustedRootAuthority should exist and does exist in the farm (FilePath)." -Fixture { + $testParams = @{ + Name = "CertIdentifier" + CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + Ensure = "Present" + } + + Mock -CommandName Test-Path -MockWith { + return $true + } + + Mock -CommandName Get-Item -MockWith { + return @{ + Subject = "CN=CertName" + Thumbprint = $testParams.CertificateThumbprint + } + } + + Mock -CommandName New-Object -MockWith { + $retVal = [pscustomobject]@{ + Subject = "CN=CertIdentifer" + Thumbprint = "770515261D1AB169057E246E0EE6431D557C3AFC" + HasPrivateKey = $false + } + Add-Member -InputObject $retVal -MemberType ScriptMethod Import { } + + return $retVal + } -ParameterFilter { $TypeName -eq "System.Security.Cryptography.X509Certificates.X509Certificate2" } + Mock -CommandName Get-SPTrustedRootAuthority -MockWith { return @{ Name = $testParams.Name @@ -60,7 +235,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } - Context -Name "When TrustedRootAuthority should exist and does exist in the farm, but has incorrect certificate." -Fixture { + Context -Name "When TrustedRootAuthority should exist and does exist in the farm, but has incorrect certificate (Thumbprint)." -Fixture { $testParams = @{ Name = "CertIdentifier" CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" @@ -91,14 +266,67 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Test-TargetResource @testParams | Should Be $false } - It "Should create a new service application in the set method" { + It "Should update the certificate in the set method" { Set-TargetResource @testParams Assert-MockCalled Get-SPTrustedRootAuthority -Times 1 Assert-MockCalled Set-SPTrustedRootAuthority -Times 1 } } - Context -Name "When TrustedRootAuthority should exist and does exist in the farm, but has incorrect certificate, but specified certificate doesn't exist;" -Fixture { + Context -Name "When TrustedRootAuthority should exist and does exist in the farm, but has incorrect certificate (FilePath)." -Fixture { + $testParams = @{ + Name = "CertIdentifier" + CertificateFilePath = "C:\cert.cer" + Ensure = "Present" + } + + Mock -CommandName Get-SPTrustedRootAuthority -MockWith { + return @{ + Name = $testParams.Name + Certificate = @{ + Thumbprint = "770515261D1AB169057E246E0EE6431D557C3AFC" + } + } + } + + Mock -CommandName Test-Path -MockWith { + return $true + } + + Mock -CommandName Get-Item -MockWith { + return @{ + Subject = "CN=CertName" + Thumbprint = $testParams.CertificateThumbprint + } + } + + Mock -CommandName New-Object -MockWith { + $retVal = [pscustomobject]@{ + Subject = "CN=CertIdentifer" + Thumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + HasPrivateKey = $false + } + Add-Member -InputObject $retVal -MemberType ScriptMethod Import { } + + return $retVal + } -ParameterFilter { $TypeName -eq "System.Security.Cryptography.X509Certificates.X509Certificate2" } + + It "Should return Present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return false when the Test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should update the certificate in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Get-SPTrustedRootAuthority -Times 1 + Assert-MockCalled Set-SPTrustedRootAuthority -Times 1 + } + } + + Context -Name "When TrustedRootAuthority should exist and does exist in the farm, but has incorrect certificate, but specified certificate doesn't exist;" -Fixture { $testParams = @{ Name = "CertIdentifier" CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" @@ -159,7 +387,7 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } - Context -Name "When TrustedRootAuthority should exist and doesn't exist in the farm." -Fixture { + Context -Name "When TrustedRootAuthority should exist and doesn't exist in the farm (Thumbprint)." -Fixture { $testParams = @{ Name = "CertIdentifier" CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" @@ -192,6 +420,53 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { } } + Context -Name "When TrustedRootAuthority should exist and doesn't exist in the farm (FilePath)." -Fixture { + $testParams = @{ + Name = "CertIdentifier" + CertificateFilePath = "c:\cert.cer" + Ensure = "Present" + } + + Mock -CommandName Test-Path -MockWith { + return $true + } + + Mock -CommandName Get-Item -MockWith { + return @{ + Subject = "CN=CertName" + Thumbprint = $testParams.CertificateThumbprint + } + } + + Mock -CommandName New-Object -MockWith { + $retVal = [pscustomobject]@{ + Subject = "CN=CertIdentifer" + Thumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + HasPrivateKey = $false + } + Add-Member -InputObject $retVal -MemberType ScriptMethod Import { } + + return $retVal + } -ParameterFilter { $TypeName -eq "System.Security.Cryptography.X509Certificates.X509Certificate2" } + + Mock -CommandName Get-SPTrustedRootAuthority -MockWith { + return $null + } + + It "Should return Absent from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + } + + It "Should return true when the Test method is called" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should create a new service application in the set method" { + Set-TargetResource @testParams + Assert-MockCalled New-SPTrustedRootAuthority -Times 1 + } + } + Context -Name "When TrustedRootAuthority should exist and doesn't exist in the farm, but specified cert contains a private key" -Fixture { $testParams = @{ Name = "CertIdentifier" @@ -258,39 +533,34 @@ Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture { Ensure = "Present" } - Mock -CommandName Get-Item ` - -MockWith { - $retVal = [pscustomobject]@{ - Subject = "CN=CertIdentifier" - Thumbprint = $testParams.CertificateThumbprint - HasPrivateKey = $true - } + Mock -CommandName Get-Item -MockWith { + $retVal = [pscustomobject]@{ + Subject = "CN=CertIdentifier" + Thumbprint = $testParams.CertificateThumbprint + HasPrivateKey = $true + } - Add-Member -InputObject $retVal -MemberType ScriptMethod Export { - $bytes = [System.Byte[]]::CreateInstance([System.Byte],512) - return $bytes - } + Add-Member -InputObject $retVal -MemberType ScriptMethod Export { + $bytes = [System.Byte[]]::CreateInstance([System.Byte],512) + return $bytes + } - return $retVal + return $retVal } - Mock -CommandName New-Object ` - -ParameterFilter { $TypeName -eq "System.Security.Cryptography.X509Certificates.X509Certificate2" } ` - -MockWith { - $retVal = [pscustomobject]@{} - Add-Member -InputObject $retVal -MemberType ScriptMethod Import { - param([System.Byte[]]$bytes) - return @{ - Subject = "CN=CertIdentifer" - Thumbprint = $testParams.CertificateThumbprint - HasPrivateKey = $false - } + Mock -CommandName New-Object -MockWith { + $retVal = [pscustomobject]@{} + Add-Member -InputObject $retVal -MemberType ScriptMethod Import { + param([System.Byte[]]$bytes) + return @{ + Subject = "CN=CertIdentifer" + Thumbprint = $testParams.CertificateThumbprint + HasPrivateKey = $false } + } - return $retVal - - - } + return $retVal + } -ParameterFilter { $TypeName -eq "System.Security.Cryptography.X509Certificates.X509Certificate2" } Mock -CommandName Get-SPTrustedRootAuthority -MockWith { return @{ From cd6bb593a94808b9716aea8516075d97df12c3bd Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Mon, 13 May 2019 11:14:54 +0200 Subject: [PATCH 51/53] Minor updates --- .../MSFT_SPTrustedRootAuthority.schema.mof | 2 +- .../{3-RemoveExample.ps1 => 3-RemoveRootAuthority.ps1} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/{3-RemoveExample.ps1 => 3-RemoveRootAuthority.ps1} (100%) diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof b/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof index 480745511..456d711da 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPTrustedRootAuthority/MSFT_SPTrustedRootAuthority.schema.mof @@ -4,7 +4,7 @@ class MSFT_SPTrustedRootAuthority : OMI_BaseResource { [Key, Description("Specifies the name of the trusted root authority to create.")] String Name; [Write, Description("Specifies the X.509 certificate of the trusted root authority, as a certificate thumbprint.")] String CertificateThumbprint; - [Write, Description("Specify the file path to the certificate if it is not stored in the local certificate store already")] String CertificateFilePath; + [Write, Description("Specify the file path to the certificate if it is not stored in the local certificate store already. Private key should not be present.")] String CertificateFilePath; [Write, Description("Present ensures the trusted root authority exists, absent ensures it is removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, EmbeddedInstance("MSFT_Credential"), Description("POWERSHELL 4 ONLY: The account to run this resource as, use PsDscRunAsCredential if using PowerShell 5")] String InstallAccount; }; diff --git a/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveExample.ps1 b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveRootAuthority.ps1 similarity index 100% rename from Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveExample.ps1 rename to Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveRootAuthority.ps1 From 5d951b6fcefa2a9da71280306240e320ed666880 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Mon, 13 May 2019 16:57:51 +0200 Subject: [PATCH 52/53] v3.4 preparations --- CHANGELOG.md | 2 +- Modules/SharePointDsc/SharePointDsc.psd1 | 76 +++++++++++------------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c86163d0d..92efdd01a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change log for SharePointDsc -## Unreleased +## v3.4 * SPDistributedCacheClientSettings * Added 15 new SharePoint 2016 parameters. diff --git a/Modules/SharePointDsc/SharePointDsc.psd1 b/Modules/SharePointDsc/SharePointDsc.psd1 index c13c80064..382e6c084 100644 --- a/Modules/SharePointDsc/SharePointDsc.psd1 +++ b/Modules/SharePointDsc/SharePointDsc.psd1 @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '3.3.0.0' +ModuleVersion = '3.4.0.0' # ID used to uniquely identify this module GUID = '6c1176a0-4fac-4134-8ca2-3fa8a21a7b90' @@ -128,53 +128,47 @@ PrivateData = @{ # ReleaseNotes of this module ReleaseNotes = " - * SharePointDsc generic - * Implemented workaround for PSSA v1.18 issue. No further impact for - the rest of the resources - * Fixed issue where powershell session was never removed and leaded to - memory leak - * Added readme.md file to Examples folder, which directs users to the - Wiki on Github - * SPAppManagementServiceApp - * Added ability to create Service App Proxy if this is not present - * SPConfigWizard - * Improved logging + * SPDistributedCacheClientSettings + * Added 15 new SharePoint 2016 parameters. * SPFarm - * Corrected issue where the resource would try to join a farm, even when - the farm was not yet created - * Fixed issue where an error was thrown when no DeveloperDashboard - parameter was specfied + * Implemented Null check in Get method to prevent errors + * Add support to provision Central Administration on HTTPS + * SPInfoPathFormsServiceConfig + * Added the AllowEventPropagation parameter. * SPInstall - * Added check to unblock setup file if it is blocked because it is coming - from a network location. This to prevent endless wait - * Added ability to install from a UNC path, by adding server - to IE Local Intranet Zone. This will prevent an endless wait - caused by security warning + * Improved logging ouput + * Updated blocked setup file check to prevent errors when BinaryDir + is a CD-ROM drive or mounted ISO * SPInstallLanguagePack - * Added check to unblock setup file if it is blocked because it is coming - from a network location. This to prevent endless wait - * Corrected issue with Norwegian language pack not being correctly - detected + * Improved logging ouput + * Updated blocked setup file check to prevent errors when BinaryDir + is a CD-ROM drive or mounted ISO + * SPInstallPrereqs + * Improved logging ouput + * Added the updated check to unblock setup file if it is blocked because + it is coming from a network location. This to prevent endless wait. * Added ability to install from a UNC path, by adding server to IE Local Intranet Zone. This will prevent an endless wait - caused by security warning + caused by security warning. + * Fixed an issue that would prevent the resource failing a test when the + prerequisites have been installed successfully on Windows Server 2019 + * SPManagedMetadataServiceApp + * Fixed issue where Get-TargetResource method throws an error when the + service app proxy does not exist and no proxy name is specified. * SPProductUpdate - * Added ability to install from a UNC path, by adding server - to IE Local Intranet Zone. This will prevent an endless wait - caused by security warning - * Major refactor of this resource to remove the dependency on the - existence of the farm. This allows the installation of product updates - before farm creation. - * SPSearchContentSource - * Corrected typo that prevented a correct check for ContinuousCrawl - * SPSearchServiceApp - * Added possibility to manage AlertsEnabled setting - * SPSelfServiceSiteCreation - * Added new SharePoint 2019 properties + * Improved logging ouput + * Updated blocked setup file check to prevent errors when SetupFile + is a CD-ROM drive or mounted ISO + * SPSearchContent Source + * Removed check that prevents configuring an incremental schedule when + using continuous crawl. * SPSitePropertyBag - * Added new resource - * SPWebAppThrottlingSettings - * Fixed issue with ChangeLogRetentionDays not being applied + * Fixed issue where properties were set on the wrong level. + * SPSubscriptionSettingsServiceApp + * Fixed issue where the service app proxy isn't created when it wasn't + created during initial deployment. + * SPTrustedRootAuthority + * Added possibility to get certificate from file. " } # End of PSData hashtable From de20c4466edfb38762f03952740b529f86e1cb90 Mon Sep 17 00:00:00 2001 From: Yorick Kuijs Date: Mon, 13 May 2019 20:04:32 +0200 Subject: [PATCH 53/53] v3.4 release --- ..._SPDistributedCacheClientSettings.help.txt | 129 ++++++++++++++++++ .../SharePointDsc/en-US/about_SPFarm.help.txt | 25 +++- ...bout_SPInfoPathFormsServiceConfig.help.txt | 4 + .../about_SPTrustedRootAuthority.help.txt | 51 +++++-- 4 files changed, 191 insertions(+), 18 deletions(-) diff --git a/Modules/SharePointDsc/en-US/about_SPDistributedCacheClientSettings.help.txt b/Modules/SharePointDsc/en-US/about_SPDistributedCacheClientSettings.help.txt index d366ef408..267a33eb0 100644 --- a/Modules/SharePointDsc/en-US/about_SPDistributedCacheClientSettings.help.txt +++ b/Modules/SharePointDsc/en-US/about_SPDistributedCacheClientSettings.help.txt @@ -139,6 +139,66 @@ Write - UInt32 Channel timeout for the Distributed Server to Application Server Cache +.PARAMETER DFLTCMaxConnectionsToServer + Write - UInt32 + Maximum number of connections to the Distributed File Lock Throttler Cache (SP2016 and above) + +.PARAMETER DFLTCRequestTimeout + Write - UInt32 + Request timeout for the Distributed File Lock Throttler Cache (SP2016 and above) + +.PARAMETER DFLTCChannelOpenTimeOut + Write - UInt32 + Channel timeout for the Distributed File Lock Throttler Cache (SP2016 and above) + +.PARAMETER DSWUCMaxConnectionsToServer + Write - UInt32 + Maximum number of connections to the Distributed Shared With User Cache (SP2016 and above) + +.PARAMETER DSWUCRequestTimeout + Write - UInt32 + Request timeout for the Distributed Shared With User Cache (SP2016 and above) + +.PARAMETER DSWUCChannelOpenTimeOut + Write - UInt32 + Channel timeout for the Distributed Shared With User Cache (SP2016 and above) + +.PARAMETER DUGCMaxConnectionsToServer + Write - UInt32 + Maximum number of connections to the Distributed Unified Groups Cache (SP2016 and above) + +.PARAMETER DUGCRequestTimeout + Write - UInt32 + Request timeout for the Distributed Unified Groups Cache (SP2016 and above) + +.PARAMETER DUGCChannelOpenTimeOut + Write - UInt32 + Channel timeout for the Distributed Unified Groups Cache (SP2016 and above) + +.PARAMETER DRTCMaxConnectionsToServer + Write - UInt32 + Maximum number of connections to the Distributed Resource Tally Cache (SP2016 and above) + +.PARAMETER DRTCRequestTimeout + Write - UInt32 + Request timeout for the Distributed Resource Tally Cache (SP2016 and above) + +.PARAMETER DRTCChannelOpenTimeOut + Write - UInt32 + Channel timeout for the Distributed Resource Tally Cache (SP2016 and above) + +.PARAMETER DHSCMaxConnectionsToServer + Write - UInt32 + Maximum number of connections to the Distributed Health Score Cache (SP2016 and above) + +.PARAMETER DHSCRequestTimeout + Write - UInt32 + Request timeout for the Distributed Health Score Cache (SP2016 and above) + +.PARAMETER DHSCChannelOpenTimeOut + Write - UInt32 + Channel timeout for the Distributed Health Score Cache (SP2016 and above) + .PARAMETER InstallAccount Write - String POWERSHELL 4 ONLY: The account to run this resource as, use PsDscRunAsCredential if using PowerShell 5 @@ -197,3 +257,72 @@ } +.EXAMPLE + This example configures the distributed cache client settings + in SharePoint 2016. + + + Configuration Example + { + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $SetupAccount + ) + Import-DscResource -ModuleName SharePointDsc + + node localhost { + SPDistributedCacheClientSettings Settings + { + IsSingleInstance = "Yes" + DLTCMaxConnectionsToServer = 3 + DLTCRequestTimeout = 1000 + DLTCChannelOpenTimeOut = 1000 + DVSCMaxConnectionsToServer = 3 + DVSCRequestTimeout = 1000 + DVSCChannelOpenTimeOut = 1000 + DACMaxConnectionsToServer = 3 + DACRequestTimeout = 1000 + DACChannelOpenTimeOut = 1000 + DAFMaxConnectionsToServer = 3 + DAFRequestTimeout = 1000 + DAFChannelOpenTimeOut = 1000 + DAFCMaxConnectionsToServer = 3 + DAFCRequestTimeout = 1000 + DAFCChannelOpenTimeOut = 1000 + DBCMaxConnectionsToServer = 3 + DBCRequestTimeout = 1000 + DBCChannelOpenTimeOut = 1000 + DDCMaxConnectionsToServer = 3 + DDCRequestTimeout = 1000 + DDCChannelOpenTimeOut = 1000 + DSCMaxConnectionsToServer = 3 + DSCRequestTimeout = 1000 + DSCChannelOpenTimeOut = 1000 + DTCMaxConnectionsToServer = 3 + DTCRequestTimeout = 1000 + DTCChannelOpenTimeOut = 1000 + DSTACMaxConnectionsToServer = 3 + DSTACRequestTimeout = 1000 + DSTACChannelOpenTimeOut = 1000 + DFLTCMaxConnectionsToServer = 3 + DFLTCRequestTimeout = 1000 + DFLTCChannelOpenTimeOut = 1000 + DSWUCMaxConnectionsToServer = 3 + DSWUCRequestTimeout = 1000 + DSWUCChannelOpenTimeOut = 1000 + DUGCMaxConnectionsToServer = 3 + DUGCRequestTimeout = 1000 + DUGCChannelOpenTimeOut = 1000 + DRTCMaxConnectionsToServer = 3 + DRTCRequestTimeout = 1000 + DRTCChannelOpenTimeOut = 1000 + DHSCMaxConnectionsToServer = 3 + DHSCRequestTimeout = 1000 + DHSCChannelOpenTimeOut = 1000 + PsDscRunAscredential = $SetupAccount + } + } + } + + diff --git a/Modules/SharePointDsc/en-US/about_SPFarm.help.txt b/Modules/SharePointDsc/en-US/about_SPFarm.help.txt index 5079a0b4e..909404e5b 100644 --- a/Modules/SharePointDsc/en-US/about_SPFarm.help.txt +++ b/Modules/SharePointDsc/en-US/about_SPFarm.help.txt @@ -25,18 +25,25 @@ passphrase. 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. 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 default behavior of SharePoint). This means you - need to use SPDistributedCacheService on at least one server in the farm to - designate it as a cache server. + 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. + 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 + default behavior of SharePoint). This means you need to use + SPDistributedCacheService on at least one server in the farm to designate it + as a cache server. CentralAdministrationAuth can be specified as "NTLM" or "KERBEROS". If not specified, it defaults to NTLM. If using Kerberos, make sure to have appropriate SPNs setup for Farm account and Central Administration URI. + To provision Central Admin as an SSL web application, specify a value for + the CentralAdministrationUrl property that begins with https:// followed + by the vanity host name or server name you wish to use to access CA. + (e.g. https://admin.sharepoint.contoso.com). + DeveloperDashboard can be specified as "On", "Off" and (only when using SharePoint 2013) to "OnDemand". @@ -79,6 +86,10 @@ Required - Boolean Should the central admin site run on this specific server? +.PARAMETER CentralAdministrationUrl + Write - String + Vanity URL for Central Administration to be used with SSL + .PARAMETER CentralAdministrationPort Write - Uint32 What port will Central Admin be provisioned to - default is 9999 diff --git a/Modules/SharePointDsc/en-US/about_SPInfoPathFormsServiceConfig.help.txt b/Modules/SharePointDsc/en-US/about_SPInfoPathFormsServiceConfig.help.txt index d4319cab8..649af4074 100644 --- a/Modules/SharePointDsc/en-US/about_SPInfoPathFormsServiceConfig.help.txt +++ b/Modules/SharePointDsc/en-US/about_SPInfoPathFormsServiceConfig.help.txt @@ -56,6 +56,10 @@ Write - Boolean True sets the InfoPath Forms Service to allow Cross-Domain connections +.PARAMETER AllowEventPropagation + Write - Boolean + True enables the original performance optimization + .PARAMETER MaxPostbacksPerSession Write - Uint16 Maximum number of postback allowed per session diff --git a/Modules/SharePointDsc/en-US/about_SPTrustedRootAuthority.help.txt b/Modules/SharePointDsc/en-US/about_SPTrustedRootAuthority.help.txt index bb21df75f..a2813d345 100644 --- a/Modules/SharePointDsc/en-US/about_SPTrustedRootAuthority.help.txt +++ b/Modules/SharePointDsc/en-US/about_SPTrustedRootAuthority.help.txt @@ -16,9 +16,13 @@ Specifies the name of the trusted root authority to create. .PARAMETER CertificateThumbprint - Required - String + Write - String Specifies the X.509 certificate of the trusted root authority, as a certificate thumbprint. +.PARAMETER CertificateFilePath + Write - String + Specify the file path to the certificate if it is not stored in the local certificate store already. Private key should not be present. + .PARAMETER Ensure Write - String Allowed values: Present, Absent @@ -33,7 +37,32 @@ This example deploys a SP Trusted Root Authority to the local farm. - Configuration Example + Configuration Example + { + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $SetupAccount + ) + Import-DscResource -ModuleName SharePointDsc + + node localhost { + SPTrustedRootAuthority SampleRootAuthority + { + Name = "Contoso" + CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + Ensure = "Present" + PsDscRunAsCredential = $SetupAccount + } + } + } + + +.EXAMPLE + This example deploys a SP Trusted Root Authority to the local farm. + + + Configuration Example { param( [Parameter(Mandatory = $true)] @@ -45,10 +74,10 @@ node localhost { SPTrustedRootAuthority SampleRootAuthority { - Name = "Contoso" - CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" - Ensure = "Present" - PsDscRunAsCredential = $SetupAccount + Name = "Contoso" + CertificateFilePath = "C:\Certificates\RootAuthority.cer" + Ensure = "Present" + PsDscRunAsCredential = $SetupAccount } } } @@ -58,7 +87,7 @@ This example removes a SP Trusted Root Authority from the local farm. - Configuration Example + Configuration Example { param( [Parameter(Mandatory = $true)] @@ -70,10 +99,10 @@ node localhost { SPTrustedRootAuthority SampleRootAuthority { - Name = "Contoso" - CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" - Ensure = "Absent" - PsDscRunAsCredential = $SetupAccount + Name = "Contoso" + CertificateThumbprint = "770515261D1AB169057E246E0EE6431D557C3AFB" + Ensure = "Absent" + PsDscRunAsCredential = $SetupAccount } } }