diff --git a/CHANGELOG.md b/CHANGELOG.md index fd8e435c6..01140bbb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,49 @@ # Change log for SharePointDsc +## v3.4 + +* SPDistributedCacheClientSettings + * Added 15 new SharePoint 2016 parameters. +* SPFarm + * Implemented Null check in Get method to prevent errors + * Add support to provision Central Administration on HTTPS +* SPInfoPathFormsServiceConfig + * 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 + * 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. + * 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 + * 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. +* SPTrustedRootAuthority + * Added possibility to get certificate from file. + ## v3.3 * SharePointDsc generic diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 index 800d7dd7f..555c28848 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPDistributedCacheClientSettings/MSFT_SPDistributedCacheClientSettings.psm1 @@ -129,6 +129,66 @@ 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 @@ -136,6 +196,34 @@ function Get-TargetResource Write-Verbose -Message "Getting the Distributed Cache Client Settings" + 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 ` -ScriptBlock { @@ -173,7 +261,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 +290,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 +328,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 @@ -246,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] @@ -282,7 +404,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DAFMaxConnectionsToServer = 1, + $DAFMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -294,7 +416,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DAFCMaxConnectionsToServer = 1, + $DAFCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -306,7 +428,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DBCMaxConnectionsToServer = 1, + $DBCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -318,7 +440,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DDCMaxConnectionsToServer = 1, + $DDCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -330,7 +452,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DSCMaxConnectionsToServer = 1, + $DSCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -342,7 +464,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DTCMaxConnectionsToServer = 1, + $DTCMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -354,7 +476,7 @@ function Set-TargetResource [Parameter()] [System.UInt32] - $DSTACMaxConnectionsToServer = 1, + $DSTACMaxConnectionsToServer = 4, [Parameter()] [System.UInt32] @@ -364,6 +486,66 @@ function Set-TargetResource [System.UInt32] $DSTACChannelOpenTimeOut = 3000, + [Parameter()] + [System.UInt32] + $DFLTCMaxConnectionsToServer = 4, + + [Parameter()] + [System.UInt32] + $DFLTCRequestTimeout = 3000, + + [Parameter()] + [System.UInt32] + $DFLTCChannelOpenTimeOut = 3000, + + [Parameter()] + [System.UInt32] + $DSWUCMaxConnectionsToServer = 4, + + [Parameter()] + [System.UInt32] + $DSWUCRequestTimeout = 3000, + + [Parameter()] + [System.UInt32] + $DSWUCChannelOpenTimeOut = 3000, + + [Parameter()] + [System.UInt32] + $DUGCMaxConnectionsToServer = 4, + + [Parameter()] + [System.UInt32] + $DUGCRequestTimeout = 500, + + [Parameter()] + [System.UInt32] + $DUGCChannelOpenTimeOut = 100, + + [Parameter()] + [System.UInt32] + $DRTCMaxConnectionsToServer = 4, + + [Parameter()] + [System.UInt32] + $DRTCRequestTimeout = 500, + + [Parameter()] + [System.UInt32] + $DRTCChannelOpenTimeOut = 20, + + [Parameter()] + [System.UInt32] + $DHSCMaxConnectionsToServer = 4, + + [Parameter()] + [System.UInt32] + $DHSCRequestTimeout = 500, + + [Parameter()] + [System.UInt32] + $DHSCChannelOpenTimeOut = 20, + [Parameter()] [System.Management.Automation.PSCredential] $InstallAccount @@ -371,6 +553,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 +746,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 +965,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 +1037,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_SPFarm/MSFT_SPFarm.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 index 7c36cc357..17f8148ef 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1 @@ -38,6 +38,10 @@ function Get-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [System.String] + $CentralAdministrationUrl, + [Parameter()] [System.UInt32] $CentralAdministrationPort, @@ -82,6 +86,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 " + ` @@ -149,7 +161,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 +185,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) { @@ -188,9 +196,9 @@ function Get-TargetResource } $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` - | Where-Object -FilterScript { - $_.IsAdministrationWebApplication -eq $true - } + | Where-Object -FilterScript { + $_.IsAdministrationWebApplication -eq $true + } $centralAdminProvisioned = $false $ca = Get-SPServiceInstance -Server $env:ComputerName @@ -208,7 +216,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" } @@ -229,6 +239,7 @@ function Get-TargetResource Passphrase = $null AdminContentDatabaseName = $centralAdminSite.ContentDatabases[0].Name RunCentralAdmin = $centralAdminProvisioned + CentralAdministrationUrl = $centralAdminSite.Url.TrimEnd('/') CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port CentralAdministrationAuth = $centralAdminAuth DeveloperDashboard = $developerDashboardStatus @@ -273,6 +284,7 @@ function Get-TargetResource Passphrase = $null AdminContentDatabaseName = $null RunCentralAdmin = $null + CentralAdministrationUrl = $null CentralAdministrationPort = $null CentralAdministrationAuth = $null Ensure = "Present" @@ -286,7 +298,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 @@ -295,6 +308,7 @@ function Get-TargetResource Passphrase = $null AdminContentDatabaseName = $null RunCentralAdmin = $null + CentralAdministrationUrl = $null CentralAdministrationPort = $null CentralAdministrationAuth = $null Ensure = "Absent" @@ -343,6 +357,10 @@ function Set-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [System.String] + $CentralAdministrationUrl, + [Parameter()] [System.UInt32] $CentralAdministrationPort, @@ -386,10 +404,26 @@ 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")) { - $PSBoundParameters.Add("CentralAdministrationPort", 9999) + # 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", (New-Object -TypeName System.Uri $CentralAdministrationUrl).Port) + } + else + { + $PSBoundParameters.Add("CentralAdministrationPort", 9999) + } } if (-not $PSBoundParameters.ContainsKey("CentralAdministrationAuth")) @@ -417,7 +451,7 @@ function Set-TargetResource { $domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain $fqdn = "$($env:COMPUTERNAME).$domain" - $serviceInstance = Get-SPServiceInstance -Server $fqdn ` + $serviceInstance = Get-SPServiceInstance -Server $fqdn } if ($null -ne $serviceInstance) @@ -461,20 +495,94 @@ function Set-TargetResource } } } - if ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) + + if ($RunCentralAdmin) { - Invoke-SPDSCCommand -Credential $InstallAccount ` - -Arguments $PSBoundParameters ` - -ScriptBlock { - $params = $args[0] + # 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') + { + Write-Verbose -Message "Updating CentralAdmin port to HTTPS" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + $reprovisionCentralAdmin = $false + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration | Where-Object -FilterScript { + $_.IsAdministrationWebApplication + } - Write-Verbose -Message "Updating Central Admin port" - Set-SPCentralAdministration -Port $params.CentralAdministrationPort + $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 $($currentUri.AbsoluteUri) does not equal $($desiredUri.AbsoluteUri)" + $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 ($desiredUri.Host -ne $secureBindings[0].HostHeader -or ` + $desiredUri.Port -ne $secureBindings[0].Port) + { + 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 + } + } + 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" + Remove-SPWebApplication -Identity $centralAdminSite.Url -Zone Default -DeleteIisSite + + Write-Verbose -Message "Re-provisioning Central Admin web application with SSL" + $webAppParams = @{ + Identity = $centralAdminSite.Url + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = $desiredUri.Host + Port = $desiredUri.Port + AuthenticationMethod = $params.CentralAdministrationAuth + SecureSocketsLayer = $true + } + New-SPWebApplicationExtension @webAppParams + } + } + } + elseif ($CurrentValues.CentralAdministrationPort -ne $CentralAdministrationPort) + { + Write-Verbose -Message "Updating CentralAdmin port to $CentralAdministrationPort" + Invoke-SPDSCCommand -Credential $InstallAccount ` + -Arguments $PSBoundParameters ` + -ScriptBlock { + $params = $args[0] + + Write-Verbose -Message "Updating Central Admin port" + Set-SPCentralAdministration -Port $params.CentralAdministrationPort + } } } if ($CurrentValues.DeveloperDashboard -ne $DeveloperDashboard) { + Write-Verbose -Message "Updating DeveloperDashboard to $DeveloperDashboard" Invoke-SPDSCCommand -Credential $InstallAccount ` -Arguments $PSBoundParameters ` -ScriptBlock { @@ -716,7 +824,6 @@ function Set-TargetResource $_.IsAdministrationWebApplication -eq $true } - $centralAdminProvisioned = $false if ((New-Object -TypeName System.Uri $centralAdminSite.Url).Port -eq $params.CentralAdministrationPort) { @@ -727,6 +834,36 @@ function Set-TargetResource { New-SPCentralAdministration -Port $params.CentralAdministrationPort ` -WindowsAuthProvider $params.CentralAdministrationAuth + + # 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" + + $centralAdminSite = Get-SPWebApplication -IncludeCentralAdministration ` + | Where-Object -FilterScript { + $_.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" + + $webAppParams = @{ + Identity = $centralAdminSite.Url + Name = "SharePoint Central Administration v4" + Zone = "Default" + HostHeader = ([System.Uri]$params.CentralAdministrationUrl).Host + Port = $params.CentralAdministrationPort + AuthenticationMethod = $params.CentralAdministrationAuth + SecureSocketsLayer = $true + } + + New-SPWebApplicationExtension @webAppParams + } } else { @@ -825,6 +962,10 @@ function Test-TargetResource [System.Boolean] $RunCentralAdmin, + [Parameter()] + [System.String] + $CentralAdministrationUrl, + [Parameter()] [System.UInt32] $CentralAdministrationPort, @@ -860,6 +1001,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 @@ -868,6 +1016,7 @@ function Test-TargetResource -DesiredValues $PSBoundParameters ` -ValuesToCheck @("Ensure", "RunCentralAdmin", + "CentralAdministrationUrl", "CentralAdministrationPort", "DeveloperDashboard") } 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; 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/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..d20524425 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 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; diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPInstall/MSFT_SPInstall.psm1 index 66db2af26..23233c058 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,11 +46,41 @@ function Get-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item $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) + { + 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\*" @@ -132,7 +162,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,12 +217,41 @@ function Set-TargetResource } Write-Verbose -Message "Checking file status of $InstallerPath" - $zone = Get-Item $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.") + 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" @@ -279,9 +338,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..f02a71a35 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,11 +42,42 @@ function Get-TargetResource throw "Setup.exe cannot be found in {$BinaryDir}" } - $zone = Get-Item $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) + { + 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 ` @@ -99,7 +130,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 +156,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 +246,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,17 +259,49 @@ function Set-TargetResource throw "Setup.exe cannot be found in {$BinaryDir}" } - $zone = Get-Item $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) + { + 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 + 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 +321,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 +369,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 8568a4d69..962469846 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", @@ -196,6 +196,50 @@ 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" + $checkBlockedFile = $true + if (Split-Path -Path $InstallerPath -IsAbsolute) + { + $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) + { + 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) $buildVersion = (Get-SPDSCBuildVersion -PathToAssembly $InstallerPath) if ($majorVersion -eq 15) @@ -560,6 +604,50 @@ 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" + $checkBlockedFile = $true + if (Split-Path -Path $InstallerPath -IsAbsolute) + { + $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) + { + 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" $majorVersion = Get-SPDSCAssemblyVersion -PathToAssembly $InstallerPath $buildVersion = Get-SPDSCBuildVersion -PathToAssembly $InstallerPath @@ -752,10 +840,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/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) { diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 index 319161e17..5763d4210 100644 --- a/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 +++ b/Modules/SharePointDsc/DSCResources/MSFT_SPProductUpdate/MSFT_SPProductUpdate.psm1 @@ -43,23 +43,54 @@ 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}" } 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.") + Write-Verbose -Message "Checking status now" + $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.") + } + Write-Verbose -Message "File not blocked, continuing." } $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,25 +271,56 @@ 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}" } 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.") + Write-Verbose -Message "Checking status now" + $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.") + } + Write-Verbose -Message "File not blocked, continuing." } $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 +340,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 diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPSearchContentSource/MSFT_SPSearchContentSource.psm1 index d467b5bd4..e3a93a14e 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 " + ` @@ -769,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 " + ` diff --git a/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 b/Modules/SharePointDsc/DSCResources/MSFT_SPSitePropertyBag/MSFT_SPSitePropertyBag.psm1 index fe907ecca..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.Properties) - { - if ($spSite.Properties.Contains($params.Key) -eq $true) - { - $localEnsure = 'Present' - $currentValue = $spSite.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.Properties" - $spSite.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.Properties" - $spSite.Properties.Remove($params.Key) - $spSite.Update() + throw "Cannot retrieve the property bag. Please check if you have the correct permissions." } } } 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/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..456d711da 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. 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/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 + } + } + } 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-RemoveRootAuthority.ps1 similarity index 57% rename from Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-RemoveExample.ps1 rename to Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveRootAuthority.ps1 index e253034a3..5ad43176f 100644 --- a/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/2-RemoveExample.ps1 +++ b/Modules/SharePointDsc/Examples/Resources/SPTrustedRootAuthority/3-RemoveRootAuthority.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/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" - } #********************************************************** diff --git a/Modules/SharePointDsc/SharePointDsc.psd1 b/Modules/SharePointDsc/SharePointDsc.psd1 index 4cab6c645..8f2b500cc 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 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 } } } 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.SPFarm.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1 index b358f82f1..704b4100d 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 { } @@ -104,6 +106,33 @@ namespace Microsoft.SharePoint.Administration { } } + Context -Name "Invalid CA URL has been passed in" -Fixture { + $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 { $testParams = @{ IsSingleInstance = "Yes" @@ -300,6 +329,7 @@ namespace Microsoft.SharePoint.Administration { FarmAccount = $mockFarmAccount Passphrase = $mockPassphrase AdminContentDatabaseName = "SP_AdminContent" + CentralAdministrationUrl = "" RunCentralAdmin = $true } @@ -432,6 +462,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 +473,7 @@ namespace Microsoft.SharePoint.Administration { Passphrase = $mockPassphrase AdminContentDatabaseName = "SP_AdminContent" RunCentralAdmin = $true + CentralAdministrationUrl = "https://admin.contoso.com" } Mock -CommandName Get-SPDSCRegistryKey -MockWith { @@ -627,6 +659,351 @@ namespace Microsoft.SharePoint.Administration { } } + 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 { + $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" + } + } + + 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 "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" + 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 { + $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 @{ + 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" 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 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 53bbe5e2e..b994a81fe 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPInstallPrereqs.Tests.ps1 @@ -477,6 +477,130 @@ 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 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" @@ -740,6 +864,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!") + } + } } } 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" 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" diff --git a/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 b/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 index df8f2bff8..cf34de32e 100644 --- a/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 +++ b/Tests/Unit/SharePointDsc/SharePointDsc.SPSitePropertyBag.Tests.ps1 @@ -20,15 +20,30 @@ 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 { - $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 } @@ -43,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." } } @@ -62,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' { 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 } 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 @{ 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: