Skip to content

Commit

Permalink
Merge pull request #1396 from ChristophHannappel/Adds/MSFT_SPWebAppPP…
Browse files Browse the repository at this point in the history
…SearchDomainCustomFilter

SPWebAppPeoplePickerSettings: Adds support for parameter CustomFilter and ShortDomainName
  • Loading branch information
ykuijs committed Apr 1, 2022
2 parents 139e5f7 + 290d64d commit df57d18
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 26 deletions.
17 changes: 6 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- SPFarmPropertyBag
- Added support for boolean and int32 data types
- SPInstall
- Added additional ExitCode for incorrect license key
- SPShellAdmin
- Added additional logging to improve troubleshooting
- SPWebAppPeoplePickerSettings
- Added the CustomFilter parameter to the resource
- Added the ShortDomainName parameter to the resource

### Fixed

- SPSearchServiceApp
- Fixed issue where the database permissions were not corrected for new
search service applications.
- SPWebApplication
- Fixed an issue where the Set method tried to use the Parameter SecureSocketsLayer with
Set-SPWebApplication on SharePoint Server older than Subscription Edition.
- Fixed an issue where the Set method tried to use the Parameter SecureSocketsLayer with Set-SPWebApplication on SharePoint Server older than Subscription Edition.
- SPWebAppPeoplePickerSettings
- Fixed an issue where the Set method would not update a non mandatory parameter on an existing SPWebAppPPSearchDomain

## [5.1.0] - 2022-02-24

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ function Get-TargetResource
$searchADDomain.FQDN = $searchDomain.DomainName
$searchADDomain.IsForest = $searchDomain.IsForest
$searchADDomain.AccessAccount = $searchDomain.LoginName
$searchADDomain.CustomFilter = $searchDomain.CustomFilter
$searchADDomain.ShortDomainName = $searchDomain.ShortDomainName
$searchADDomains += $searchADDomain
}

Expand Down Expand Up @@ -211,9 +213,42 @@ function Set-TargetResource
$adsearchobj.SetPassword($accessAccountPassword)
}
}
if ($null -ne ($searchADDomain.CimInstanceProperties | Where-Object -FilterScript { $_.Name -eq 'CustomFilter' }))
{
$adsearchobj.CustomFilter = $searchADDomain.CustomFilter
}
if ($null -ne ($searchADDomain.CimInstanceProperties | Where-Object -FilterScript { $_.Name -eq 'ShortDomainName' }))
{
$adsearchobj.ShortDomainName = $searchADDomain.ShortDomainName
}

$wa.PeoplePickerSettings.SearchActiveDirectoryDomains.Add($adsearchobj)
}
else
{
if ($null -ne ($searchADDomain.CimInstanceProperties | Where-Object -FilterScript { $_.Name -eq 'AccessAccount' }))
{
$configuredDomain.LoginName = $searchADDomain.AccessAccount.UserName

if ([string]::IsNullOrEmpty($searchADDomain.AccessAccount.Password))
{
$configuredDomain.SetPassword($null)
}
else
{
$accessAccountPassword = ConvertTo-SecureString $searchADDomain.AccessAccount.Password -AsPlainText -Force
$configuredDomain.SetPassword($accessAccountPassword)
}
}
if ($null -ne ($searchADDomain.CimInstanceProperties | Where-Object -FilterScript { $_.Name -eq 'CustomFilter' }))
{
$configuredDomain.CustomFilter = $searchADDomain.CustomFilter
}
if ($null -ne ($searchADDomain.CimInstanceProperties | Where-Object -FilterScript { $_.Name -eq 'ShortDomainName' }))
{
$configuredDomain.ShortDomainName = $searchADDomain.ShortDomainName
}
}
}

# Reverse Check: Configured domains do not exist in config
Expand Down Expand Up @@ -319,15 +354,45 @@ function Test-TargetResource
Write-Verbose -Message "Test-TargetResource returned false"
return $false
}
else
{
if ($searchADDomain.ContainsKey('AccessAccount') -and $searchADDomain.AccessAccount.UserName -ne $specifiedDomain.LoginName)
{
$message = "Current LoginName Property of SearchActiveDirectoryDomain $searchADDomain does not match the desired state."
Write-Verbose -Message $message
Add-SPDscEvent -Message $message -EntryType 'Error' -EventID 1 -Source $MyInvocation.MyCommand.Source

Write-Verbose -Message "Test-TargetResource returned false"
return $false
}
if ($searchADDomain.ContainsKey('CustomFilter') -and $searchADDomain.CustomFilter -ne $specifiedDomain.CustomFilter)
{
$message = "Current CustomFilter Property of SearchActiveDirectoryDomain $searchADDomain does not match the desired state."
Write-Verbose -Message $message
Add-SPDscEvent -Message $message -EntryType 'Error' -EventID 1 -Source $MyInvocation.MyCommand.Source

Write-Verbose -Message "Test-TargetResource returned false"
return $false
}
if ($searchADDomain.ContainsKey('ShortDomainName') -and $searchADDomain.ShortDomainName -ne $specifiedDomain.ShortDomainName)
{
$message = "Current ShortDomainName Property of SearchActiveDirectoryDomain $searchADDomain does not match the desired state."
Write-Verbose -Message $message
Add-SPDscEvent -Message $message -EntryType 'Error' -EventID 1 -Source $MyInvocation.MyCommand.Source

Write-Verbose -Message "Test-TargetResource returned false"
return $false
}
}
}

$result = Test-SPDscParameterState -CurrentValues $CurrentValues `
-Source $($MyInvocation.MyCommand.Source) `
-DesiredValues $PSBoundParameters `
-ValuesToCheck @("ActiveDirectoryCustomFilter", `
"ActiveDirectoryCustomQuery", `
"ActiveDirectorySearchTimeout", `
"OnlySearchWithinSiteCollection",
-ValuesToCheck @("ActiveDirectoryCustomFilter",
"ActiveDirectoryCustomQuery",
"ActiveDirectorySearchTimeout",
"OnlySearchWithinSiteCollection",
"PeopleEditorOnlyResolveWithinSiteCollection")

Write-Verbose -Message "Test-TargetResource returned $result"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Class MSFT_SPWebAppPPSearchDomain
[Required, Description("FQDN of the domain or forest")] String FQDN;
[Required, Description("Is the FQDN a forest?")] Boolean IsForest;
[Write, Description("Specifies the credentials to use to connect to the specified domain or forest"), EmbeddedInstance("MSFT_Credential")] String AccessAccount;
[Write, Description("Sets a customized query filter to send to Active Directory")] String CustomFilter;
[Write, Description("NetBIOS name of the domain or forest")] String ShortDomainName;
};
[ClassVersion("1.0.0.0"), FriendlyName("SPWebAppPeoplePickerSettings")]
class MSFT_SPWebAppPeoplePickerSettings : OMI_BaseResource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ queried before you can configure the SearchActiveDirectoryDomains.
The encryption key must be set on every front-end web server in the farm
on which SharePoint is installed:
https://technet.microsoft.com/en-us/library/gg602075(v=office.15).aspx#section3

Due to a SharePoint API limitation a password missmatch cannot be detected.
To update the password after the initial add to the SearchActiveDirectoryDomains
the `SPPeoplePickerSearchActiveDirectoryDomain` has to be removed from the SearchActiveDirectoryDomains or
the the password needs to be updated with the `SetPassword(SecureString)` Method directly.
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,13 @@ Configuration Example
ActiveDirectorySearchTimeout = 30
OnlySearchWithinSiteCollection = $false
SearchActiveDirectoryDomains = @(
MSFT_SPWebAppPPSearchDomain {
FQDN = "contoso.com"
IsForest = $false
AccessAccount = $AccessAccount
MSFT_SPWebAppPPSearchDomain
{
FQDN = "contoso.com"
IsForest = $false
AccessAccount = $AccessAccount
CustomFilter = '(company=Contoso)'
ShortDomainName = 'CONTOSO'
}
)
PsDscRunAsCredential = $SetupAccount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function Invoke-TestSetup

$script:testEnvironment = Initialize-TestEnvironment `
-DSCModuleName $script:DSCModuleName `
-DSCResourceName $script:DSCResourceFullName `
-DscResourceName $script:DSCResourceFullName `
-ResourceType 'Mof' `
-TestType 'Unit'
}
Expand All @@ -49,7 +49,7 @@ try
InModuleScope -ModuleName $script:DSCResourceFullName -ScriptBlock {
Describe -Name $Global:SPDscHelper.DescribeHeader -Fixture {
BeforeAll {
Invoke-Command -Scriptblock $Global:SPDscHelper.InitializeScript -NoNewScope
Invoke-Command -ScriptBlock $Global:SPDscHelper.InitializeScript -NoNewScope

# Initialize tests
$mockPassword = ConvertTo-SecureString -String "password" -AsPlainText -Force
Expand Down Expand Up @@ -130,7 +130,7 @@ try
}
}

Context -Name "Search domain settings do not match actual values" -Fixture {
Context -Name "Search domain settings do not match actual values (Domain does not exist)" -Fixture {
BeforeAll {
$testParams = @{
WebAppUrl = "http://sharepoint.contoso.com"
Expand Down Expand Up @@ -198,6 +198,119 @@ try
}
}

Context -Name "Search domain settings do not match actual values (Domain exists)" -Fixture {
BeforeAll {
$testParams = @{
WebAppUrl = "http://sharepoint.contoso.com"
SearchActiveDirectoryDomains = @(
(New-CimInstance -ClassName MSFT_SPWebAppPPSearchDomain -Property @{
FQDN = "contoso.intra"
IsForest = $false
AccessAccount = (New-CimInstance -ClassName MSFT_Credential `
-Property @{
Username = [string]$mockAccount.UserName;
Password = [string]$mockAccount.Password;
} `
-Namespace root/microsoft/windows/desiredstateconfiguration `
-ClientOnly)
CustomFilter = "(company=Contoso)"
ShortDomainName = "CONTOSO"
} -ClientOnly)
(New-CimInstance -ClassName MSFT_SPWebAppPPSearchDomain -Property @{
FQDN = "fabrikam.intra"
IsForest = $false
AccessAccount = (New-CimInstance -ClassName MSFT_Credential `
-Property @{
Username = [string]$mockAccount.UserName;
Password = [string]$null;
} `
-Namespace root/microsoft/windows/desiredstateconfiguration `
-ClientOnly)
CustomFilter = "(company=FABRIKAM)"
ShortDomainName = "FABRIKAM"
} -ClientOnly)
)
}

Mock -CommandName Get-SPWebApplication -MockWith {
$searchADdom = New-Object -TypeName "System.Collections.Generic.List[System.Object]"
# Create a SPPeoplePickerSearchActiveDirectoryDomain
$searchDom1 = New-Object -TypeName "Object"
Add-Member -InputObject $searchDom1 -MemberType 'NoteProperty' -Name DomainName -Value "contoso.intra"
Add-Member -InputObject $searchDom1 -MemberType 'NoteProperty' -Name IsForest -Value $false
Add-Member -InputObject $searchDom1 -MemberType 'NoteProperty' -Name LoginName -Value "wrongUsername"
Add-Member -InputObject $searchDom1 -MemberType 'NoteProperty' -Name CustomFilter -Value "(company=Fabrikam)"
Add-Member -InputObject $searchDom1 -MemberType 'NoteProperty' -Name ShortDomainName -Value "FABRIKAM"
$addMemberSetPassword = @{
InputObject = $searchDom1
MemberType = 'ScriptMethod'
Name = 'SetPassword'
Value = {
param(
[securestring]
$Password
)
}
}
Add-Member @addMemberSetPassword
$searchADdom.Add($searchDom1)

# Create a SPPeoplePickerSearchActiveDirectoryDomain
$searchDom2 = New-Object -TypeName "Object"
Add-Member -InputObject $searchDom2 -MemberType 'NoteProperty' -Name DomainName -Value "fabrikam.intra"
Add-Member -InputObject $searchDom2 -MemberType 'NoteProperty' -Name IsForest -Value $false
Add-Member -InputObject $searchDom2 -MemberType 'NoteProperty' -Name LoginName -Value "wrongUsername"
Add-Member -InputObject $searchDom2 -MemberType 'NoteProperty' -Name CustomFilter -Value "(company=Fabrikam)"
Add-Member -InputObject $searchDom2 -MemberType 'NoteProperty' -Name ShortDomainName -Value "FABRIKAM"
$addMemberSetPassword = @{
InputObject = $searchDom2
MemberType = 'ScriptMethod'
Name = 'SetPassword'
Value = {
param(
[securestring]
$Password
)
}
}
Add-Member @addMemberSetPassword
$searchADdom.Add($searchDom2)

$returnval = @{
PeoplePickerSettings = @{
ActiveDirectoryCustomFilter = "()"
ActiveDirectoryCustomQuery = "()"
ActiveDirectorySearchTimeout = @{
TotalSeconds = 10
}
OnlySearchWithinSiteCollection = $true
PeopleEditorOnlyResolveWithinSiteCollection = $true
SearchActiveDirectoryDomains = $searchADdom
}
}
$returnval = $returnval | Add-Member -MemberType ScriptMethod -Name Update -Value {
$Global:SPDscWebApplicationUpdateCalled = $true
} -PassThru

return $returnval
}
}

It "Should return SearchTimeOut=10 from the get method" {
(Get-TargetResource @testParams).ActiveDirectorySearchTimeout | Should -Be 10
}

It "Should return false from the test method" {
Test-TargetResource @testParams | Should -Be $false
}

It "Should update the people picker settings" {
$Global:SPDscWebApplicationUpdateCalled = $false
Set-TargetResource @testParams
$Global:SPDscWebApplicationUpdateCalled | Should -Be $true
}
}

Context -Name "Settings do not match actual values" -Fixture {
BeforeAll {
$testParams = @{
Expand Down Expand Up @@ -264,15 +377,17 @@ try
WebAppUrl = "http://sharepoint.contoso.com"
SearchActiveDirectoryDomains = @(
(New-CimInstance -ClassName MSFT_SPWebAppPPSearchDomain -Property @{
FQDN = "contoso.intra"
IsForest = $false
AccessAccount = (New-CimInstance -ClassName MSFT_Credential `
FQDN = "contoso.intra"
IsForest = $false
AccessAccount = (New-CimInstance -ClassName MSFT_Credential `
-Property @{
Username = [string]$mockAccount.UserName;
Password = [string]$mockAccount.Password;
} `
-Namespace root/microsoft/windows/desiredstateconfiguration `
-ClientOnly)
CustomFilter = "(company=Contoso)"
ShortDomainName = "CONTOSO"
} -ClientOnly)
)
}
Expand All @@ -288,7 +403,13 @@ try
-Value ( $false ) -PassThru | `
Add-Member -MemberType NoteProperty `
-Name LoginName `
-Value ( $mockAccount.UserName ) -PassThru
-Value ( $mockAccount.UserName ) -PassThru | `
Add-Member -MemberType NoteProperty `
-Name CustomFilter `
-Value ( "(company=Contoso)" ) -PassThru | `
Add-Member -MemberType NoteProperty `
-Name ShortDomainName `
-Value ( "CONTOSO" ) -PassThru
$searchADdom.Add($searchDom1)

$returnval = @{
Expand Down

0 comments on commit df57d18

Please sign in to comment.