Skip to content

Commit

Permalink
Merge pull request #1147 from jensotto/set-application-credential-key
Browse files Browse the repository at this point in the history
SPFarm: Added ApplicationCredentialKey
  • Loading branch information
ykuijs authored Jan 24, 2020
2 parents 1756202 + a1bdc17 commit 5cca8dd
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- SharePointDsc
- Added automatic release with a new CI pipeline
- Updated PULL_REQUEST_TEMPLATE.md to match DSC standard
- SPFarm
- Added possibility to set application credential key.

### Changed

Expand Down
39 changes: 39 additions & 0 deletions SharePointDsc/DSCResources/MSFT_SPFarm/MSFT_SPFarm.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ function Get-TargetResource
[System.String]
$DeveloperDashboard,

[Parameter()]
[System.Management.Automation.PSCredential]
$ApplicationCredentialKey,

[Parameter()]
[System.Management.Automation.PSCredential]
$InstallAccount
Expand All @@ -90,6 +94,7 @@ function Get-TargetResource
throw "SharePointDsc does not support removing a server from a farm, please set the ensure property to 'present'"
}

$supportsSettingApplicationCredentialKey = $false
$installedVersion = Get-SPDscInstalledProductVersion
switch ($installedVersion.FileMajorPart)
{
Expand Down Expand Up @@ -119,6 +124,7 @@ function Get-TargetResource
else
{
Write-Verbose -Message "Detected installation of SharePoint 2019"
$supportsSettingApplicationCredentialKey = $true
}
}
default
Expand All @@ -128,6 +134,13 @@ function Get-TargetResource
}
}

if ($PSBoundParameters.ContainsKey("ApplicationCredentialKey") -and
-not $supportsSettingApplicationCredentialKey)
{
throw [Exception] ("Specifying ApplicationCredentialKey is only supported " +
"on SharePoint 2019")
}

if (($PSBoundParameters.ContainsKey("ServerRole") -eq $true) -and
$installedVersion.FileMajorPart -ne 16)
{
Expand Down Expand Up @@ -236,6 +249,7 @@ function Get-TargetResource
CentralAdministrationPort = (New-Object -TypeName System.Uri $centralAdminSite.Url).Port
CentralAdministrationAuth = $centralAdminAuth
DeveloperDashboard = $developerDashboardStatus
ApplicationCredentialKey = $null
}
$installedVersion = Get-SPDscInstalledProductVersion
if ($installedVersion.FileMajorPart -eq 16)
Expand Down Expand Up @@ -280,6 +294,7 @@ function Get-TargetResource
CentralAdministrationUrl = $null
CentralAdministrationPort = $null
CentralAdministrationAuth = $null
ApplicationCredentialKey = $null
Ensure = "Present"
}
}
Expand All @@ -304,6 +319,7 @@ function Get-TargetResource
CentralAdministrationUrl = $null
CentralAdministrationPort = $null
CentralAdministrationAuth = $null
ApplicationCredentialKey = $null
Ensure = "Absent"
}
}
Expand Down Expand Up @@ -381,6 +397,9 @@ function Set-TargetResource
[System.String]
$DeveloperDashboard,

[Parameter()]
[System.Management.Automation.PSCredential]
$ApplicationCredentialKey,

[Parameter()]
[System.Management.Automation.PSCredential]
Expand Down Expand Up @@ -688,6 +707,7 @@ function Set-TargetResource
SkipRegisterAsDistributedCacheHost = $true
}

$supportsSettingApplicationCredentialKey = $false
$installedVersion = Get-SPDscInstalledProductVersion
switch ($installedVersion.FileMajorPart)
{
Expand All @@ -708,6 +728,7 @@ function Set-TargetResource
{
Write-Verbose -Message ("Detected Version: SharePoint 2019 - " +
"configuring server as $($params.ServerRole)")
$supportsSettingApplicationCredentialKey = $true
}
$executeArgs.Add("LocalServerRole", $params.ServerRole)
}
Expand All @@ -724,6 +745,7 @@ function Set-TargetResource
Write-Verbose -Message ("Detected Version: SharePoint 2019 - no server " +
"role provided, configuring server without a " +
"specific role")
$supportsSettingApplicationCredentialKey = $true
}
$executeArgs.Add("ServerRoleOptional", $true)
}
Expand All @@ -736,6 +758,13 @@ function Set-TargetResource
}
}

if ($params.ContainsKey("ApplicationCredentialKey") -and
-not $supportsSettingApplicationCredentialKey)
{
throw [Exception] ("Specifying ApplicationCredentialKey is only supported " +
"on SharePoint 2019")
}

if ($dbStatus.DatabaseExists -eq $true)
{
Write-Verbose -Message ("The SharePoint config database " +
Expand Down Expand Up @@ -862,6 +891,12 @@ function Set-TargetResource
Write-Verbose -Message "Starting Install-SPFeature"
Install-SPFeature -AllExistingFeatures -Force | Out-Null

if ($params.ContainsKey("ApplicationCredentialKey"))
{
Write-Verbose -Message "Setting application credential key"
Set-SPApplicationCredentialKey -Password $params.ApplicationCredentialKey.Password
}

# Provision central administration
if ($params.RunCentralAdmin -eq $true)
{
Expand Down Expand Up @@ -1060,6 +1095,10 @@ function Test-TargetResource
[System.String]
$DeveloperDashboard,

[Parameter()]
[System.Management.Automation.PSCredential]
$ApplicationCredentialKey,

[Parameter()]
[System.Management.Automation.PSCredential]
$InstallAccount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ class MSFT_SPFarm : OMI_BaseResource
[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","SingleServerFarm","WebFrontEnd","WebFrontEndWithDistributedCache"}, Values{"Application","ApplicationWithSearch","Custom","DistributedCache","Search","SingleServerFarm","WebFrontEnd","WebFrontEndWithDistributedCache"}] String ServerRole;
[Write, Description("Specifies the state of the Developer Dashboard ('OnDemand' is SP2013 only)"), ValueMap{"Off","On","OnDemand"}, Values{"Off","On","OnDemand"}] String DeveloperDashboard;
[Write, Description("Specifies the application credential key on the local server. Only supported for SP2019."), EmbeddedInstance("MSFT_Credential")] String ApplicationCredentialKey;
[Write, Description("POWERSHELL 4 ONLY: The account to run this resource as, use PsDscRunAsCredential if using PowerShell 5"), EmbeddedInstance("MSFT_Credential")] String InstallAccount;
};
6 changes: 6 additions & 0 deletions SharePointDsc/DSCResources/MSFT_SPFarm/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ begins with HTTPS, and will default to port 443.
DeveloperDashboard can be specified as "On", "Off" and (only when using
SharePoint 2013) to "OnDemand".

ApplicationCredentialKey is used to set the application credential key on the
local server, which is used by certain features to encrypt and decrypt passwords.
The application credential key will only be set during initial farm creation and
when joining the farm. The ApplicationCredentialKey needs to be the same on each
server in the farm. ApplicationCredentialKey is only supported for SharePoint 2019.

NOTE:
When using SharePoint 2016 and later and enabling the Developer Dashboard,
please make sure you also provision the Usage and Health service application
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

<#PSScriptInfo
.VERSION 1.0.0
.GUID 80d306fa-8bd4-4a8d-9f7a-bf40df95e661
.AUTHOR DSC Community
.COMPANYNAME DSC Community
.COPYRIGHT DSC Community contributors. All rights reserved.
.TAGS
.LICENSEURI https://github.com/dsccommunity/SharePointDsc/blob/master/LICENSE
.PROJECTURI https://github.com/dsccommunity/SharePointDsc
.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
Updated author, copyright notice, and URLs.
.PRIVATEDATA
#>

<#
.DESCRIPTION
This example shows how a basic SharePoint farm can be created. The database server and names
are specified, and the accounts to run the setup as, the farm account and the passphrase are
all passed in to the configuration to be applied. The application credential key is also
specified. This configuration is only supported with SharePoint 2019. By default the central
admin site in this example is provisioned to port 9999 using NTLM authentication.
#>

Configuration Example
{
param(
[Parameter(Mandatory = $true)]
[PSCredential]
$FarmAccount,

[Parameter(Mandatory = $true)]
[PSCredential]
$SetupAccount,

[Parameter(Mandatory = $true)]
[PSCredential]
$Passphrase,

[Parameter(Mandatory = $true)]
[PSCredential]
$ApplicationCredentialKey
)
Import-DscResource -ModuleName SharePointDsc

node localhost {
SPFarm SharePointFarm
{
IsSingleInstance = "Yes"
DatabaseServer = "SQL.contoso.local\SQLINSTANCE"
FarmConfigDatabaseName = "SP_Config"
AdminContentDatabaseName = "SP_AdminContent"
Passphrase = $Passphrase
FarmAccount = $FarmAccount
ApplicationCredentialKey = $ApplicationCredentialKey
RunCentralAdmin = $true
PsDscRunAsCredential = $SetupAccount
}
}
}

<#
.EXAMPLE
#>

97 changes: 97 additions & 0 deletions tests/Unit/SharePointDsc/SharePointDsc.SPFarm.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,103 @@ namespace Microsoft.SharePoint.Administration {
}
}

if ($Global:SPDscHelper.CurrentStubBuildNumber.Major -eq 16 -and
$Global:SPDscHelper.CurrentStubBuildNumber.Build.ToString().Length -ne 4)
{
Context -Name "ApplicationCredentialKey is specified on SP2019 installation" -Fixture {
$testParams = @{
IsSingleInstance = "Yes"
Ensure = "Present"
FarmConfigDatabaseName = "SP_Config"
DatabaseServer = "sql.contoso.com"
FarmAccount = $mockFarmAccount
Passphrase = $mockPassphrase
AdminContentDatabaseName = "SP_AdminContent"
RunCentralAdmin = $false
}

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
Url = "http://localhost:9999"
}
}
Mock -CommandName "Get-CimInstance" -MockWith {
return @{
Domain = "test.lab"
}
}
Mock -CommandName "Get-SPServiceInstance" -MockWith {
if ($global:SPDscCentralAdminCheckDone -eq $true)
{
return @(
$null | Add-Member -MemberType ScriptMethod `
-Name GetType `
-Value {
return @{
Name = "SPWebServiceInstance"
}
} -PassThru -Force | Add-Member -Name Name `
-MemberType ScriptProperty `
-PassThru `
{
# get
""
}`
{
# set
param ( $arg )
}
)
}
else
{
$global:SPDscCentralAdminCheckDone = $true
return $null
}
}

Mock -CommandName "Get-SPWebApplication" -MockWith {
return @{
IsAdministrationWebApplication = $true
ContentDatabases = @(@{
Name = $testParams.AdminContentDatabaseName
})
Url = "http://localhost:9999"
}
}

Mock -CommandName Set-SPApplicationCredentialKey -MockWith { return $null }

It "Should not throw an exception in the get method" {
{ Get-TargetResource @testParams } | Should Not Throw "Specifying ApplicationCredentialKey is only supported on SharePoint 2019"
}

It "Should set application credential key" {
Set-TargetResource @testParams
Assert-MockCalled -CommandName "Set-SPApplicationCredentialKey"
}

It "Should not throw an exception in the test method" {
{ Test-TargetResource @testParams } | Should not Throw "Specifying ApplicationCredentialKey is only supported on SharePoint 2019"
}
}
}

Context -Name "no serverrole is specified but get-targetresource needs to identify and return it" -Fixture {
$testParams = @{
IsSingleInstance = "Yes"
Expand Down

0 comments on commit 5cca8dd

Please sign in to comment.