diff --git a/CHANGELOG.md b/CHANGELOG.md index f2d72718d..2e3ed4de0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a call to Get-SPFarm without loading the snap-in first - SPInstallLanguagePack - Fixed issue with detection of Chinese language pack in SharePoint 2019 +- SPSearchTopology + - Fixed issue where an issue was thrown when the FirstPartitionDirectory didn't + exist on the local server (which isn't always required) - SPSite - Fixed issue where the default groups were checked, even though that parameter wasn't specified in the config diff --git a/SharePointDsc/DSCResources/MSFT_SPSearchTopology/MSFT_SPSearchTopology.psm1 b/SharePointDsc/DSCResources/MSFT_SPSearchTopology/MSFT_SPSearchTopology.psm1 index a999ebf7d..6a085f1f7 100644 --- a/SharePointDsc/DSCResources/MSFT_SPSearchTopology/MSFT_SPSearchTopology.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPSearchTopology/MSFT_SPSearchTopology.psm1 @@ -312,13 +312,19 @@ function Set-TargetResource { $networkPath = "\\$IndexPartitionServer\" + ` $params.FirstPartitionDirectory.Replace(":\", "$\") - New-Item $networkPath -ItemType Directory -Force - } - - # Create the directory on the local server as it will not apply the topology without it - if ((Test-Path -Path $params.FirstPartitionDirectory) -eq $false) - { - New-Item $params.FirstPartitionDirectory -ItemType Directory -Force + try + { + $null = New-Item -Path $networkPath ` + -ItemType Directory ` + -Force ` + -ErrorAction Stop + } + catch + { + Write-Verbose -Message ("Unable to create folder {$($params.FirstPartitionDirectory)} " + ` + "on {$IndexPartitionServer}.") + Write-Verbose -Message " Error: $($_.Exception.Message)" + } } # Get all service service instances to assign topology components to @@ -403,41 +409,61 @@ function Set-TargetResource { "AdminComponent" { - New-SPEnterpriseSearchAdminComponent @NewComponentParams + Write-Verbose -Message "Adding $ComponentToAdd to run an AdminComponent" + $null = New-SPEnterpriseSearchAdminComponent @NewComponentParams } "CrawlComponent" { - New-SPEnterpriseSearchCrawlComponent @NewComponentParams + Write-Verbose -Message "Adding $ComponentToAdd to run a CrawlComponent" + $null = New-SPEnterpriseSearchCrawlComponent @NewComponentParams } "ContentProcessingComponent" { - New-SPEnterpriseSearchContentProcessingComponent @NewComponentParams + Write-Verbose -Message "Adding $ComponentToAdd to run a ContentProcessingComponent" + $null = New-SPEnterpriseSearchContentProcessingComponent @NewComponentParams } "AnalyticsProcessingComponent" { - New-SPEnterpriseSearchAnalyticsProcessingComponent @NewComponentParams + Write-Verbose -Message "Adding $ComponentToAdd to run an AnalyticsProcessingComponent" + $null = New-SPEnterpriseSearchAnalyticsProcessingComponent @NewComponentParams } "QueryProcessingComponent" { - New-SPEnterpriseSearchQueryProcessingComponent @NewComponentParams + Write-Verbose -Message "Adding $ComponentToAdd to run a QueryComponent" + $null = New-SPEnterpriseSearchQueryProcessingComponent @NewComponentParams } "IndexComponent" { - $NewComponentParams.Add("IndexPartition", 0) - if ($params.ContainsKey("FirstPartitionDirectory") -eq $true) + Write-Verbose -Message "Adding $ComponentToAdd to run an IndexComponent" + $installedVersion = Get-SPDscInstalledProductVersion + if ($installedVersion.FileMajorPart -eq 15) { - if ([string]::IsNullOrEmpty($params.FirstPartitionDirectory) -eq $false) + Write-Verbose -Message "Using SharePoint 2013" + $indexServer = (Get-SPServer $ComponentToAdd).Name + $indexComponent = (New-Object Microsoft.Office.Server.Search.Administration.Topology.IndexComponent $indexServer, 0); + $indexComponent.RootDirectory = $params.FirstPartitionDirectory + $newTopology.AddComponent($indexComponent) + } + else + { + Write-Verbose -Message "Using SharePoint 2016 or later" + $NewComponentParams.Add("IndexPartition", 0) + if ($params.ContainsKey("FirstPartitionDirectory") -eq $true) { - $dir = $params.FirstPartitionDirectory - $NewComponentParams.Add("RootDirectory", $dir) + if ([string]::IsNullOrEmpty($params.FirstPartitionDirectory) -eq $false) + { + $dir = $params.FirstPartitionDirectory + $NewComponentParams.Add("RootDirectory", $dir) + } } + $null = New-SPEnterpriseSearchIndexComponent @NewComponentParams } - New-SPEnterpriseSearchIndexComponent @NewComponentParams } } } foreach ($ComponentToRemove in $ComponentsToRemove) { + Write-Verbose -Message "Removing $($componentTypes.$CurrentSearchProperty) from $ComponentToRemove" if ($componentTypes.$CurrentSearchProperty -eq "IndexComponent") { $component = Get-SPEnterpriseSearchComponent -SearchTopology $newTopology | ` @@ -455,10 +481,11 @@ function Set-TargetResource -and ($_.ServerName -eq $ComponentToRemove) } } + if ($null -ne $component) { $component | Remove-SPEnterpriseSearchComponent -SearchTopology $newTopology ` - -confirm:$false + -Confirm:$false } } } @@ -475,10 +502,11 @@ function Set-TargetResource $_.ComponentId -eq $id } | ` Remove-SPEnterpriseSearchComponent -SearchTopology $newTopology ` - -confirm:$false + -Confirm:$false } # Apply the new topology to the farm + Write-Verbose -Message "Applying new Search topology" Set-SPEnterpriseSearchTopology -Identity $newTopology } } diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Mocks.cs b/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Mocks.cs index 2e4e9f00c..3782126f2 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Mocks.cs +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Mocks.cs @@ -11,35 +11,38 @@ public class CrawlComponent { public string ServerName { get; set; } public System.Guid ComponentId { get; set; } - public System.Guid ServerId {get; set;} + public System.Guid ServerId { get; set; } } public class ContentProcessingComponent { public string ServerName { get; set; } public System.Guid ComponentId { get; set; } - public System.Guid ServerId {get; set;} + public System.Guid ServerId { get; set; } } public class AnalyticsProcessingComponent { public string ServerName { get; set; } public System.Guid ComponentId { get; set; } - public System.Guid ServerId {get; set;} + public System.Guid ServerId { get; set; } } public class QueryProcessingComponent { public string ServerName { get; set; } public System.Guid ComponentId { get; set; } - public System.Guid ServerId {get; set;} + public System.Guid ServerId { get; set; } } public class IndexComponent { + public IndexComponent() { } + public IndexComponent(string server, uint IndexPartitionOrdinal) { } public string ServerName { get; set; } public System.Guid ComponentId { get; set; } public System.Int32 IndexPartitionOrdinal { get; set; } public System.Guid ServerId { get; set; } + public System.String RootDirectory { get; set; } } } diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Tests.ps1 index 3bf8c0037..2441671e1 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPSearchTopology.Tests.ps1 @@ -115,7 +115,13 @@ try return $null } Mock -CommandName New-SPEnterpriseSearchTopology -MockWith { - return @{ } + $returnval = @{ } + $returnval = $returnval | Add-Member -MemberType ScriptMethod ` + -Name AddComponent ` + -Value { } ` + -PassThru ` + -Force + return $returnval } Mock -CommandName New-SPEnterpriseSearchAdminComponent -MockWith { return @{ }