From 5a2539c1610b177a9840a0af7a0aa35dbfad85fb Mon Sep 17 00:00:00 2001 From: LuigiLink Date: Mon, 29 Jun 2026 13:38:27 +0200 Subject: [PATCH] fix(dc): iterate SPDistributedCacheServiceInstance instead of ClusterHealth.Hosts v2.3.4 iterated (Get-SPCacheClusterHealth).Hosts, which is a collection of HostInfo objects whose ToString() starts with 'Microsoft.SharePoint.Internal.Caching...'. Split('.')[0] then yielded 'Microsoft' as a fake short name, and the real DC host fell into the 'Not a cache host' list. Go back to iterating SPDistributedCacheServiceInstance (Server.Address is the correct short name) and keep Get-SPCacheClusterInfo.Size for the cluster Size; the graceful defaults from 2.3.4 are preserved. Fixes #51 --- CHANGELOG.md | 13 +++++++ RELEASE-NOTES.md | 14 ++++---- .../Public/Get-AppFabricStatus.ps1 | 35 ++++++++----------- .../SPSWeather.Common/SPSWeather.Common.psd1 | 2 +- tests/SPSWeather.Common.Tests.ps1 | 2 +- 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77e6a44..c02d430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.3.5] - 2026-06-29 + +### Fixed + +- `Get-AppFabricStatus` (SE branch) no longer reports a phantom 'Microsoft' + cache host: v2.3.4 iterated `(Get-SPCacheClusterHealth).Hosts`, which is a + collection of HostInfo objects whose `ToString()` starts with + `Microsoft.SharePoint.Internal.Caching...`, yielding 'Microsoft' as a fake + short name and pushing the real DC host into the 'Not a cache host' list. + Iteration is back on `SPDistributedCacheServiceInstance` (Server.Address is + the correct short name); `Get-SPCacheClusterInfo.Size` is still used for + the cluster Size (#51). + ## [2.3.4] - 2026-06-29 ### Fixed diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index b1d01d8..9305a10 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,14 +1,14 @@ # SPSWeather - Release Notes -## [2.3.4] - 2026-06-29 +## [2.3.5] - 2026-06-29 ### Fixed -- Distributed Cache report on SharePoint Subscription Edition now populates - Port / Size / ServiceName / CacheStatus from the SE-native cluster cmdlets - (`Get-SPCacheClusterHealth` + `Get-SPCacheClusterInfo`), with a graceful - degradation to the SP DC defaults (22233, AppFabricCachingService) when - `Get-SPCacheHostConfig` cannot resolve the host. Removes the AppFabric - fallback from 2.3.3 (those cmdlets do not exist on SE). +- Distributed Cache report on SharePoint Subscription Edition no longer shows + a phantom 'Microsoft' row (a 2.3.4 regression caused by iterating cluster + health HostInfo objects whose ToString starts with + 'Microsoft.SharePoint.Internal.Caching...'). The function iterates the + SPDistributedCacheServiceInstance set again; cluster Size still comes from + Get-SPCacheClusterInfo. A full list of changes can be found in the [change log](CHANGELOG.md). diff --git a/src/Modules/SPSWeather.Common/Public/Get-AppFabricStatus.ps1 b/src/Modules/SPSWeather.Common/Public/Get-AppFabricStatus.ps1 index 4679281..7a7b4cf 100644 --- a/src/Modules/SPSWeather.Common/Public/Get-AppFabricStatus.ps1 +++ b/src/Modules/SPSWeather.Common/Public/Get-AppFabricStatus.ps1 @@ -42,32 +42,27 @@ $productVersion = (Get-Command $fullPath).FileVersionInfo } if ($productVersion.FileMajorPart -eq 16 -and $productVersion.FileBuildPart -gt 13000) { - Write-Verbose -Message 'Subscription Edition: using Get-SPCacheClusterHealth/Info as the source of truth' + Write-Verbose -Message 'Subscription Edition: iterating SPDistributedCacheServiceInstance + Get-SPCacheClusterInfo for Size' $allSPServers = (Get-SPServer | Where-Object -FilterScript { $_.Role -ne 'Invalid' }).Name $dcInstances = @(Get-SPServiceInstance | Where-Object -FilterScript { $_.GetType().Name -eq 'SPDistributedCacheServiceInstance' }) - # Canonical host list (FQDNs) and cluster Size come from the SE-native cmdlets. - $clusterHealth = Get-SPCacheClusterHealth -ErrorAction SilentlyContinue - $clusterInfo = Get-SPCacheClusterInfo -ErrorAction SilentlyContinue - $clusterSize = if ($null -ne $clusterInfo) { "$($clusterInfo.Size)" } else { '' } - $clusterHosts = @() - if ($null -ne $clusterHealth -and $null -ne $clusterHealth.Hosts) { - $clusterHosts = @($clusterHealth.Hosts | ForEach-Object { "$_" }) - } + # Cluster Size comes from the SE-native cmdlet (string like 'Small'/'Medium'/...). + $clusterInfo = Get-SPCacheClusterInfo -ErrorAction SilentlyContinue + $clusterSize = if ($null -ne $clusterInfo) { "$($clusterInfo.Size)" } else { '' } $reportedServers = New-Object -TypeName System.Collections.ArrayList - foreach ($clusterFqdn in $clusterHosts) { - $cacheserver = $clusterFqdn.Split('.')[0] - # Match the SP service instance for this host (Server.Address is short) - $dcInst = $dcInstances | Where-Object -FilterScript { - "$($_.Server.Address)" -eq $cacheserver -or - "$($_.Server.Address)" -eq $clusterFqdn - } | Select-Object -First 1 - $SPInstanceStatus = if ($null -ne $dcInst) { "$($dcInst.Status)" } else { 'Unknown' } - # Try Get-SPCacheHostConfig with the FQDN; degrade gracefully if it - # returns null (some SE builds cannot resolve the host name). - $cacheHostConfig = Get-SPCacheHostConfig -HostName $clusterFqdn -ErrorAction SilentlyContinue + foreach ($dcInst in $dcInstances) { + $cacheserver = "$($dcInst.Server.Address)".Split('.')[0] + $SPInstanceStatus = "$($dcInst.Status)" + # Try Get-SPCacheHostConfig with the FQDN then short name; some SE + # builds return null for both - degrade gracefully to SP DC defaults. + $cacheHostConfig = $null $cacheHost = $null + foreach ($tryHost in @("$($dcInst.Server.Address)", $cacheserver)) { + if ([string]::IsNullOrEmpty($tryHost)) { continue } + $cacheHostConfig = Get-SPCacheHostConfig -HostName $tryHost -ErrorAction SilentlyContinue + if ($null -ne $cacheHostConfig) { break } + } if ($null -ne $cacheHostConfig) { $cacheHost = Get-SPCacheHost -HostName $cacheHostConfig.HostName -CachePort $cacheHostConfig.CachePort -ErrorAction SilentlyContinue } diff --git a/src/Modules/SPSWeather.Common/SPSWeather.Common.psd1 b/src/Modules/SPSWeather.Common/SPSWeather.Common.psd1 index c54dc2f..18a5db4 100644 --- a/src/Modules/SPSWeather.Common/SPSWeather.Common.psd1 +++ b/src/Modules/SPSWeather.Common/SPSWeather.Common.psd1 @@ -1,6 +1,6 @@ @{ RootModule = 'SPSWeather.Common.psm1' - ModuleVersion = '2.3.4' + ModuleVersion = '2.3.5' GUID = 'c39bd612-8520-4e65-9037-80060894d654' Author = 'Jean-Cyril DROUHIN' CompanyName = 'luigilink' diff --git a/tests/SPSWeather.Common.Tests.ps1 b/tests/SPSWeather.Common.Tests.ps1 index 4dd7b05..e14893c 100644 --- a/tests/SPSWeather.Common.Tests.ps1 +++ b/tests/SPSWeather.Common.Tests.ps1 @@ -36,7 +36,7 @@ Describe 'SPSWeather.Common module' { } It 'manifest version is 2.0.0 or higher' { - (Test-ModuleManifest -Path $modulePath).Version | Should -BeGreaterOrEqual ([version]'2.3.4') + (Test-ModuleManifest -Path $modulePath).Version | Should -BeGreaterOrEqual ([version]'2.3.5') } It 'exports exactly the expected public functions' {