From 9304b9789139e09e4a3e40a6597d70123107d104 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 15 Jan 2026 02:41:30 +0100 Subject: [PATCH 1/9] Add ShowRecentList --- .../Microsoft.Windows.Settings.psm1 | 49 ++++++++++++++- .../PersonalizationSettings.winget | 4 ++ .../Microsoft.Windows.Settings.Tests.ps1 | 59 +++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index 868cc3fe..d7fbb01d 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -59,6 +59,10 @@ class WindowsSettings { [DscProperty()] [string[]] $StartFolders + # Personalization - Start Layout + [DscProperty()] + [Nullable[bool]] $ShowRecentList + [DscProperty()] [Nullable[bool]] $NotifyOnUsbErrors @@ -79,6 +83,7 @@ class WindowsSettings { hidden [string] $ColorPrevalenceDWMPropertyName = 'ColorPrevalence' hidden [string] $AutoColorizationPropertyName = 'AutoColorization' hidden [string] $VisiblePlacesPropertyName = 'VisiblePlaces' + hidden [string] $ShowRecentListPropertyName = 'ShowRecentList' hidden [string] $NotifyOnUsbErrorsPropertyName = 'NotifyOnUsbErrors' hidden [string] $NotifyOnWeakChargerPropertyName = 'NotifyOnWeakCharger' @@ -121,6 +126,9 @@ class WindowsSettings { # Get Start Folders $currentState.StartFolders = $this.GetStartFolders() + # Get Start Layout settings + $currentState.ShowRecentList = $this.GetShowRecentList() + # Get USB settings $currentState.NotifyOnUsbErrors = $this.GetNotifyOnUsbErrors() $currentState.NotifyOnWeakCharger = $this.GetNotifyOnWeakCharger() @@ -130,7 +138,20 @@ class WindowsSettings { [bool] Test() { $currentState = $this.Get() - return $this.TestTaskbarAlignment($currentState) -and $this.TestAppColorMode($currentState) -and $this.TestSystemColorMode($currentState) -and $this.TestDeveloperMode($currentState) -and $this.TestSetTimeZoneAutomatically($currentState) -and $this.TestTimeZone($currentState) -and $this.TestEnableTransparency($currentState) -and $this.TestShowAccentColorOnStartAndTaskbar($currentState) -and $this.TestShowAccentColorOnTitleBarsAndWindowBorders($currentState) -and $this.TestAutoColorization($currentState) -and $this.TestStartFolders($currentState) -and $this.TestNotifyOnUsbErrors($currentState) -and $this.TestNotifyOnWeakCharger($currentState) + return $this.TestTaskbarAlignment($currentState) -and + $this.TestAppColorMode($currentState) -and + $this.TestSystemColorMode($currentState) -and + $this.TestDeveloperMode($currentState) -and + $this.TestSetTimeZoneAutomatically($currentState) -and + $this.TestTimeZone($currentState) -and + $this.TestEnableTransparency($currentState) -and + $this.TestShowAccentColorOnStartAndTaskbar($currentState) -and + $this.TestShowAccentColorOnTitleBarsAndWindowBorders($currentState) -and + $this.TestAutoColorization($currentState) -and + $this.TestStartFolders($currentState) -and + $this.TestShowRecentList($currentState) -and + $this.TestNotifyOnUsbErrors($currentState) -and + $this.TestNotifyOnWeakCharger($currentState) } [void] Set() { @@ -238,6 +259,16 @@ class WindowsSettings { $this.SetStartFolders() } + # Set Start Layout settings + if (!$this.TestShowRecentList($currentState)) { + # Ensure registry path exists + if (-not (Test-Path $global:StartRegistryPath)) { + New-Item -Path $global:StartRegistryPath -Force | Out-Null + } + $value = $this.ShowRecentList ? 1 : 0 + Set-ItemProperty -Path $global:StartRegistryPath -Name $this.ShowRecentListPropertyName -Value $value -Type DWord + } + # Set USB settings if (!$this.TestNotifyOnUsbErrors($currentState)) { # Ensure registry path exists @@ -490,6 +521,22 @@ class WindowsSettings { return $true } + # Start Layout Helper Methods + [Nullable[bool]] GetShowRecentList() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:StartRegistryPath -Name $this.ShowRecentListPropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:StartRegistryPath -Name $this.ShowRecentListPropertyName + return $value -eq 1 + } + + [bool] TestShowRecentList([WindowsSettings] $currentState) { + if ($null -eq $this.ShowRecentList) { + return $true + } + return $currentState.ShowRecentList -eq $this.ShowRecentList + } + [bool] TestNotifyOnUsbErrors([WindowsSettings] $currentState) { if ($null -eq $this.NotifyOnUsbErrors) { return $true diff --git a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget index 00512fca..d87e8fbf 100644 --- a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget +++ b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget @@ -26,4 +26,8 @@ properties: - Downloads - Settings - Explorer + + # Start Layout Settings + # ShowRecentList: Show recently installed apps in Start + ShowRecentList: true configurationVersion: 0.2.0 diff --git a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 index 2c808bae..4759349a 100644 --- a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 +++ b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 @@ -36,6 +36,7 @@ BeforeAll { $script:originalSettings.ShowAccentColorOnTitleBarsAndWindowBorders = $currentState.ShowAccentColorOnTitleBarsAndWindowBorders $script:originalSettings.AutoColorization = $currentState.AutoColorization $script:originalSettings.StartFolders = $currentState.StartFolders + $script:originalSettings.ShowRecentList = $currentState.ShowRecentList $script:originalSettings.NotifyOnUsbErrors = $currentState.NotifyOnUsbErrors $script:originalSettings.NotifyOnWeakCharger = $currentState.NotifyOnWeakCharger @@ -51,6 +52,7 @@ BeforeAll { Write-Host " ShowAccentColorOnTitleBarsAndWindowBorders: $($script:originalSettings.ShowAccentColorOnTitleBarsAndWindowBorders)" Write-Host " AutoColorization: $($script:originalSettings.AutoColorization)" Write-Host " StartFolders: $($script:originalSettings.StartFolders -join ', ')" + Write-Host " ShowRecentList: $($script:originalSettings.ShowRecentList)" Write-Host " NotifyOnUsbErrors: $($script:originalSettings.NotifyOnUsbErrors)" Write-Host " NotifyOnWeakCharger: $($script:originalSettings.NotifyOnWeakCharger)" } @@ -92,6 +94,9 @@ AfterAll { if ($null -ne $script:originalSettings.StartFolders -and $script:originalSettings.StartFolders.Count -gt 0) { $restoreSettings.StartFolders = $script:originalSettings.StartFolders } + if ($null -ne $script:originalSettings.ShowRecentList) { + $restoreSettings.ShowRecentList = $script:originalSettings.ShowRecentList + } if ($null -ne $script:originalSettings.NotifyOnUsbErrors) { $restoreSettings.NotifyOnUsbErrors = $script:originalSettings.NotifyOnUsbErrors } @@ -818,6 +823,60 @@ Describe 'WindowsSettings - Start Folders' { $settings.Test() | Should -Be $true } } + +Describe 'WindowsSettings - ShowRecentList' { + It 'Gets current ShowRecentList' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be either $true, $false, or $null + $currentState.ShowRecentList | Should -BeIn @($true, $false, $null) + } + + It 'Sets ShowRecentList to enabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.ShowRecentList = $true + + $settings.Set() + + $newState = $settings.Get() + $newState.ShowRecentList | Should -Be $true + } + + It 'Sets ShowRecentList to disabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.ShowRecentList = $false + + $settings.Set() + + $newState = $settings.Get() + $newState.ShowRecentList | Should -Be $false + } + + It 'Tests ShowRecentList when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + $settings.ShowRecentList = $currentState.ShowRecentList + + $settings.Test() | Should -Be $true + } + + It 'Tests ShowRecentList when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Set opposite value + $settings.ShowRecentList = -not $currentState.ShowRecentList + + $settings.Test() | Should -Be $false + } +} + Describe 'WindowsSettings - USB' { It 'Gets current NotifyOnUsbErrors' { $settings = [WindowsSettings]::new() From d90e6f2f47c696c754824aabf81ea020794ab3b1 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 15 Jan 2026 02:46:05 +0100 Subject: [PATCH 2/9] Add ShowRecommendedList --- .../Microsoft.Windows.Settings.psm1 | 28 +++++++++ .../PersonalizationSettings.winget | 2 + .../Microsoft.Windows.Settings.Tests.ps1 | 58 +++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index d7fbb01d..4ec60fdd 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -63,6 +63,10 @@ class WindowsSettings { [DscProperty()] [Nullable[bool]] $ShowRecentList + # Personalization - Recommended files + [DscProperty()] + [Nullable[bool]] $ShowRecommendedList + [DscProperty()] [Nullable[bool]] $NotifyOnUsbErrors @@ -84,6 +88,7 @@ class WindowsSettings { hidden [string] $AutoColorizationPropertyName = 'AutoColorization' hidden [string] $VisiblePlacesPropertyName = 'VisiblePlaces' hidden [string] $ShowRecentListPropertyName = 'ShowRecentList' + hidden [string] $StartTrackDocsPropertyName = 'Start_TrackDocs' hidden [string] $NotifyOnUsbErrorsPropertyName = 'NotifyOnUsbErrors' hidden [string] $NotifyOnWeakChargerPropertyName = 'NotifyOnWeakCharger' @@ -128,6 +133,7 @@ class WindowsSettings { # Get Start Layout settings $currentState.ShowRecentList = $this.GetShowRecentList() + $currentState.ShowRecommendedList = $this.GetShowRecommendedList() # Get USB settings $currentState.NotifyOnUsbErrors = $this.GetNotifyOnUsbErrors() @@ -150,6 +156,7 @@ class WindowsSettings { $this.TestAutoColorization($currentState) -and $this.TestStartFolders($currentState) -and $this.TestShowRecentList($currentState) -and + $this.TestShowRecommendedList($currentState) -and $this.TestNotifyOnUsbErrors($currentState) -and $this.TestNotifyOnWeakCharger($currentState) } @@ -269,6 +276,12 @@ class WindowsSettings { Set-ItemProperty -Path $global:StartRegistryPath -Name $this.ShowRecentListPropertyName -Value $value -Type DWord } + # Set ShowRecommendedList (Start_TrackDocs) + if (!$this.TestShowRecommendedList($currentState)) { + $value = $this.ShowRecommendedList ? 1 : 0 + Set-ItemProperty -Path $global:ExplorerRegistryPath -Name $this.StartTrackDocsPropertyName -Value $value -Type DWord + } + # Set USB settings if (!$this.TestNotifyOnUsbErrors($currentState)) { # Ensure registry path exists @@ -537,6 +550,21 @@ class WindowsSettings { return $currentState.ShowRecentList -eq $this.ShowRecentList } + [Nullable[bool]] GetShowRecommendedList() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:ExplorerRegistryPath -Name $this.StartTrackDocsPropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:ExplorerRegistryPath -Name $this.StartTrackDocsPropertyName + return $value -eq 1 + } + + [bool] TestShowRecommendedList([WindowsSettings] $currentState) { + if ($null -eq $this.ShowRecommendedList) { + return $true + } + return $currentState.ShowRecommendedList -eq $this.ShowRecommendedList + } + [bool] TestNotifyOnUsbErrors([WindowsSettings] $currentState) { if ($null -eq $this.NotifyOnUsbErrors) { return $true diff --git a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget index d87e8fbf..13d36055 100644 --- a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget +++ b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget @@ -30,4 +30,6 @@ properties: # Start Layout Settings # ShowRecentList: Show recently installed apps in Start ShowRecentList: true + # ShowRecommendedList: Show recommended files in Start, recent files in File Explorer, and items in Jump Lists + ShowRecommendedList: true configurationVersion: 0.2.0 diff --git a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 index 4759349a..53a8d2e0 100644 --- a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 +++ b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 @@ -37,6 +37,7 @@ BeforeAll { $script:originalSettings.AutoColorization = $currentState.AutoColorization $script:originalSettings.StartFolders = $currentState.StartFolders $script:originalSettings.ShowRecentList = $currentState.ShowRecentList + $script:originalSettings.ShowRecommendedList = $currentState.ShowRecommendedList $script:originalSettings.NotifyOnUsbErrors = $currentState.NotifyOnUsbErrors $script:originalSettings.NotifyOnWeakCharger = $currentState.NotifyOnWeakCharger @@ -53,6 +54,7 @@ BeforeAll { Write-Host " AutoColorization: $($script:originalSettings.AutoColorization)" Write-Host " StartFolders: $($script:originalSettings.StartFolders -join ', ')" Write-Host " ShowRecentList: $($script:originalSettings.ShowRecentList)" + Write-Host " ShowRecommendedList: $($script:originalSettings.ShowRecommendedList)" Write-Host " NotifyOnUsbErrors: $($script:originalSettings.NotifyOnUsbErrors)" Write-Host " NotifyOnWeakCharger: $($script:originalSettings.NotifyOnWeakCharger)" } @@ -97,6 +99,9 @@ AfterAll { if ($null -ne $script:originalSettings.ShowRecentList) { $restoreSettings.ShowRecentList = $script:originalSettings.ShowRecentList } + if ($null -ne $script:originalSettings.ShowRecommendedList) { + $restoreSettings.ShowRecommendedList = $script:originalSettings.ShowRecommendedList + } if ($null -ne $script:originalSettings.NotifyOnUsbErrors) { $restoreSettings.NotifyOnUsbErrors = $script:originalSettings.NotifyOnUsbErrors } @@ -877,6 +882,59 @@ Describe 'WindowsSettings - ShowRecentList' { } } +Describe 'WindowsSettings - ShowRecommendedList' { + It 'Gets current ShowRecommendedList' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be either $true, $false, or $null + $currentState.ShowRecommendedList | Should -BeIn @($true, $false, $null) + } + + It 'Sets ShowRecommendedList to enabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.ShowRecommendedList = $true + + $settings.Set() + + $newState = $settings.Get() + $newState.ShowRecommendedList | Should -Be $true + } + + It 'Sets ShowRecommendedList to disabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.ShowRecommendedList = $false + + $settings.Set() + + $newState = $settings.Get() + $newState.ShowRecommendedList | Should -Be $false + } + + It 'Tests ShowRecommendedList when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + $settings.ShowRecommendedList = $currentState.ShowRecommendedList + + $settings.Test() | Should -Be $true + } + + It 'Tests ShowRecommendedList when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Set opposite value + $settings.ShowRecommendedList = -not $currentState.ShowRecommendedList + + $settings.Test() | Should -Be $false + } +} + Describe 'WindowsSettings - USB' { It 'Gets current NotifyOnUsbErrors' { $settings = [WindowsSettings]::new() From d309f78efd4e11fd6dac13d9e920f09516e9b307 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 15 Jan 2026 02:54:57 +0100 Subject: [PATCH 3/9] Add TaskbarBadges --- .../Microsoft.Windows.Settings.psm1 | 68 +++++++++- .../PersonalizationSettings.winget | 6 + .../Microsoft.Windows.Settings.Tests.ps1 | 116 +++++++++++++++++- 3 files changed, 187 insertions(+), 3 deletions(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index 4ec60fdd..acab8d57 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -14,8 +14,9 @@ if ([string]::IsNullOrEmpty($env:TestRegistryPath)) { $global:DWMRegistryPath = 'HKCU:\Software\Microsoft\Windows\DWM\' $global:StartRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Start\' $global:USBRegistryPath = 'HKCU:\Software\Microsoft\Shell\USB\' + $global:TaskbarBadgesRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarBadges\' } else { - $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $env:TestRegistryPath + $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $global:TaskbarBadgesRegistryPath = $env:TestRegistryPath } [DSCResource()] @@ -67,6 +68,13 @@ class WindowsSettings { [DscProperty()] [Nullable[bool]] $ShowRecommendedList + # Taskbar - Badges + [DscProperty()] + [Nullable[bool]] $TaskbarBadges + + [DscProperty()] + [Nullable[bool]] $DesktopTaskbarBadges + [DscProperty()] [Nullable[bool]] $NotifyOnUsbErrors @@ -89,6 +97,8 @@ class WindowsSettings { hidden [string] $VisiblePlacesPropertyName = 'VisiblePlaces' hidden [string] $ShowRecentListPropertyName = 'ShowRecentList' hidden [string] $StartTrackDocsPropertyName = 'Start_TrackDocs' + hidden [string] $TaskbarBadgingPropertyName = 'SystemSettings_Taskbar_Badging' + hidden [string] $DesktopTaskbarBadgingPropertyName = 'SystemSettings_DesktopTaskbar_Badging' hidden [string] $NotifyOnUsbErrorsPropertyName = 'NotifyOnUsbErrors' hidden [string] $NotifyOnWeakChargerPropertyName = 'NotifyOnWeakCharger' @@ -135,6 +145,10 @@ class WindowsSettings { $currentState.ShowRecentList = $this.GetShowRecentList() $currentState.ShowRecommendedList = $this.GetShowRecommendedList() + # Get Taskbar settings + $currentState.TaskbarBadges = $this.GetTaskbarBadges() + $currentState.DesktopTaskbarBadges = $this.GetDesktopTaskbarBadges() + # Get USB settings $currentState.NotifyOnUsbErrors = $this.GetNotifyOnUsbErrors() $currentState.NotifyOnWeakCharger = $this.GetNotifyOnWeakCharger() @@ -157,6 +171,8 @@ class WindowsSettings { $this.TestStartFolders($currentState) -and $this.TestShowRecentList($currentState) -and $this.TestShowRecommendedList($currentState) -and + $this.TestTaskbarBadges($currentState) -and + $this.TestDesktopTaskbarBadges($currentState) -and $this.TestNotifyOnUsbErrors($currentState) -and $this.TestNotifyOnWeakCharger($currentState) } @@ -268,7 +284,6 @@ class WindowsSettings { # Set Start Layout settings if (!$this.TestShowRecentList($currentState)) { - # Ensure registry path exists if (-not (Test-Path $global:StartRegistryPath)) { New-Item -Path $global:StartRegistryPath -Force | Out-Null } @@ -282,6 +297,24 @@ class WindowsSettings { Set-ItemProperty -Path $global:ExplorerRegistryPath -Name $this.StartTrackDocsPropertyName -Value $value -Type DWord } + # Set TaskbarBadges + if (!$this.TestTaskbarBadges($currentState)) { + if (-not (Test-Path $global:TaskbarBadgesRegistryPath)) { + New-Item -Path $global:TaskbarBadgesRegistryPath -Force | Out-Null + } + $value = $this.TaskbarBadges ? '1' : '0' + Set-ItemProperty -Path $global:TaskbarBadgesRegistryPath -Name $this.TaskbarBadgingPropertyName -Value $value -Type String + } + + # Set DesktopTaskbarBadges + if (!$this.TestDesktopTaskbarBadges($currentState)) { + if (-not (Test-Path $global:TaskbarBadgesRegistryPath)) { + New-Item -Path $global:TaskbarBadgesRegistryPath -Force | Out-Null + } + $value = $this.DesktopTaskbarBadges ? '1' : '0' + Set-ItemProperty -Path $global:TaskbarBadgesRegistryPath -Name $this.DesktopTaskbarBadgingPropertyName -Value $value -Type String + } + # Set USB settings if (!$this.TestNotifyOnUsbErrors($currentState)) { # Ensure registry path exists @@ -565,6 +598,37 @@ class WindowsSettings { return $currentState.ShowRecommendedList -eq $this.ShowRecommendedList } + # Taskbar Helper Methods + [Nullable[bool]] GetTaskbarBadges() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarBadgesRegistryPath -Name $this.TaskbarBadgingPropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:TaskbarBadgesRegistryPath -Name $this.TaskbarBadgingPropertyName + return $value -eq '1' + } + + [bool] TestTaskbarBadges([WindowsSettings] $currentState) { + if ($null -eq $this.TaskbarBadges) { + return $true + } + return $currentState.TaskbarBadges -eq $this.TaskbarBadges + } + + [Nullable[bool]] GetDesktopTaskbarBadges() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarBadgesRegistryPath -Name $this.DesktopTaskbarBadgingPropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:TaskbarBadgesRegistryPath -Name $this.DesktopTaskbarBadgingPropertyName + return $value -eq '1' + } + + [bool] TestDesktopTaskbarBadges([WindowsSettings] $currentState) { + if ($null -eq $this.DesktopTaskbarBadges) { + return $true + } + return $currentState.DesktopTaskbarBadges -eq $this.DesktopTaskbarBadges + } + [bool] TestNotifyOnUsbErrors([WindowsSettings] $currentState) { if ($null -eq $this.NotifyOnUsbErrors) { return $true diff --git a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget index 13d36055..7195a483 100644 --- a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget +++ b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget @@ -32,4 +32,10 @@ properties: ShowRecentList: true # ShowRecommendedList: Show recommended files in Start, recent files in File Explorer, and items in Jump Lists ShowRecommendedList: true + + # Taskbar Settings + # TaskbarBadges: Enable badges (unread message counts, etc.) for apps on the taskbar + TaskbarBadges: true + # DesktopTaskbarBadges: Enable badges for apps on the desktop taskbar + DesktopTaskbarBadges: true configurationVersion: 0.2.0 diff --git a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 index 53a8d2e0..223264ad 100644 --- a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 +++ b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 @@ -38,6 +38,8 @@ BeforeAll { $script:originalSettings.StartFolders = $currentState.StartFolders $script:originalSettings.ShowRecentList = $currentState.ShowRecentList $script:originalSettings.ShowRecommendedList = $currentState.ShowRecommendedList + $script:originalSettings.TaskbarBadges = $currentState.TaskbarBadges + $script:originalSettings.DesktopTaskbarBadges = $currentState.DesktopTaskbarBadges $script:originalSettings.NotifyOnUsbErrors = $currentState.NotifyOnUsbErrors $script:originalSettings.NotifyOnWeakCharger = $currentState.NotifyOnWeakCharger @@ -55,6 +57,8 @@ BeforeAll { Write-Host " StartFolders: $($script:originalSettings.StartFolders -join ', ')" Write-Host " ShowRecentList: $($script:originalSettings.ShowRecentList)" Write-Host " ShowRecommendedList: $($script:originalSettings.ShowRecommendedList)" + Write-Host " TaskbarBadges: $($script:originalSettings.TaskbarBadges)" + Write-Host " DesktopTaskbarBadges: $($script:originalSettings.DesktopTaskbarBadges)" Write-Host " NotifyOnUsbErrors: $($script:originalSettings.NotifyOnUsbErrors)" Write-Host " NotifyOnWeakCharger: $($script:originalSettings.NotifyOnWeakCharger)" } @@ -102,6 +106,12 @@ AfterAll { if ($null -ne $script:originalSettings.ShowRecommendedList) { $restoreSettings.ShowRecommendedList = $script:originalSettings.ShowRecommendedList } + if ($null -ne $script:originalSettings.TaskbarBadges) { + $restoreSettings.TaskbarBadges = $script:originalSettings.TaskbarBadges + } + if ($null -ne $script:originalSettings.DesktopTaskbarBadges) { + $restoreSettings.DesktopTaskbarBadges = $script:originalSettings.DesktopTaskbarBadges + } if ($null -ne $script:originalSettings.NotifyOnUsbErrors) { $restoreSettings.NotifyOnUsbErrors = $script:originalSettings.NotifyOnUsbErrors } @@ -888,7 +898,6 @@ Describe 'WindowsSettings - ShowRecommendedList' { $settings.SID = 'TestSID' $currentState = $settings.Get() - # Should be either $true, $false, or $null $currentState.ShowRecommendedList | Should -BeIn @($true, $false, $null) } @@ -935,6 +944,111 @@ Describe 'WindowsSettings - ShowRecommendedList' { } } +Describe 'WindowsSettings - TaskbarBadges' { + It 'Gets current TaskbarBadges' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + $currentState.TaskbarBadges | Should -BeIn @($true, $false, $null) + } + + It 'Sets TaskbarBadges to enabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarBadges = $true + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarBadges | Should -Be $true + } + + It 'Sets TaskbarBadges to disabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarBadges = $false + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarBadges | Should -Be $false + } + + It 'Tests TaskbarBadges when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + $settings.TaskbarBadges = $currentState.TaskbarBadges + + $settings.Test() | Should -Be $true + } + + It 'Tests TaskbarBadges when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Set opposite value + $settings.TaskbarBadges = -not $currentState.TaskbarBadges + + $settings.Test() | Should -Be $false + } +} + +Describe 'WindowsSettings - DesktopTaskbarBadges' { + It 'Gets current DesktopTaskbarBadges' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be either $true, $false, or $null + $currentState.DesktopTaskbarBadges | Should -BeIn @($true, $false, $null) + } + + It 'Sets DesktopTaskbarBadges to enabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarBadges = $true + + $settings.Set() + + $newState = $settings.Get() + $newState.DesktopTaskbarBadges | Should -Be $true + } + + It 'Sets DesktopTaskbarBadges to disabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarBadges = $false + + $settings.Set() + + $newState = $settings.Get() + $newState.DesktopTaskbarBadges | Should -Be $false + } + + It 'Tests DesktopTaskbarBadges when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + $settings.DesktopTaskbarBadges = $currentState.DesktopTaskbarBadges + + $settings.Test() | Should -Be $true + } + + It 'Tests DesktopTaskbarBadges when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Set opposite value + $settings.DesktopTaskbarBadges = -not $currentState.DesktopTaskbarBadges + + $settings.Test() | Should -Be $false + } +} + Describe 'WindowsSettings - USB' { It 'Gets current NotifyOnUsbErrors' { $settings = [WindowsSettings]::new() From 58883c0dba435c5f74ddb7321c88a62af65c1bf1 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 15 Jan 2026 03:01:16 +0100 Subject: [PATCH 4/9] Add GroupingMode --- .../Microsoft.Windows.Settings.psm1 | 44 ++++++++++++- .../PersonalizationSettings.winget | 3 + .../Microsoft.Windows.Settings.Tests.ps1 | 66 +++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index acab8d57..86c17bf8 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -15,8 +15,9 @@ if ([string]::IsNullOrEmpty($env:TestRegistryPath)) { $global:StartRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Start\' $global:USBRegistryPath = 'HKCU:\Software\Microsoft\Shell\USB\' $global:TaskbarBadgesRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarBadges\' + $global:TaskbarGlomLevelRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\MMTaskbarGlomLevel\' } else { - $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $global:TaskbarBadgesRegistryPath = $env:TestRegistryPath + $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $global:TaskbarBadgesRegistryPath = $global:TaskbarGlomLevelRegistryPath = $env:TestRegistryPath } [DSCResource()] @@ -75,6 +76,10 @@ class WindowsSettings { [DscProperty()] [Nullable[bool]] $DesktopTaskbarBadges + # Taskbar - Grouping Mode (not making enum to allow if user does not want to set) + [DscProperty()] + [string] $TaskbarGroupingMode + [DscProperty()] [Nullable[bool]] $NotifyOnUsbErrors @@ -99,6 +104,7 @@ class WindowsSettings { hidden [string] $StartTrackDocsPropertyName = 'Start_TrackDocs' hidden [string] $TaskbarBadgingPropertyName = 'SystemSettings_Taskbar_Badging' hidden [string] $DesktopTaskbarBadgingPropertyName = 'SystemSettings_DesktopTaskbar_Badging' + hidden [string] $TaskbarGroupingModePropertyName = 'SystemSettings_DesktopTaskbar_GroupingMode' hidden [string] $NotifyOnUsbErrorsPropertyName = 'NotifyOnUsbErrors' hidden [string] $NotifyOnWeakChargerPropertyName = 'NotifyOnWeakCharger' @@ -148,6 +154,7 @@ class WindowsSettings { # Get Taskbar settings $currentState.TaskbarBadges = $this.GetTaskbarBadges() $currentState.DesktopTaskbarBadges = $this.GetDesktopTaskbarBadges() + $currentState.TaskbarGroupingMode = $this.GetTaskbarGroupingMode() # Get USB settings $currentState.NotifyOnUsbErrors = $this.GetNotifyOnUsbErrors() @@ -173,6 +180,7 @@ class WindowsSettings { $this.TestShowRecommendedList($currentState) -and $this.TestTaskbarBadges($currentState) -and $this.TestDesktopTaskbarBadges($currentState) -and + $this.TestTaskbarGroupingMode($currentState) -and $this.TestNotifyOnUsbErrors($currentState) -and $this.TestNotifyOnWeakCharger($currentState) } @@ -315,6 +323,20 @@ class WindowsSettings { Set-ItemProperty -Path $global:TaskbarBadgesRegistryPath -Name $this.DesktopTaskbarBadgingPropertyName -Value $value -Type String } + # Set TaskbarGroupingMode + if (!$this.TestTaskbarGroupingMode($currentState)) { + if (-not (Test-Path $global:TaskbarGlomLevelRegistryPath)) { + New-Item -Path $global:TaskbarGlomLevelRegistryPath -Force | Out-Null + } + $value = switch ($this.TaskbarGroupingMode) { + 'Always' { '0' } + 'WhenFull' { '1' } + 'Never' { '2' } + default { throw "Invalid TaskbarGroupingMode: $($this.TaskbarGroupingMode). Valid values are: Always, WhenFull, Never" } + } + Set-ItemProperty -Path $global:TaskbarGlomLevelRegistryPath -Name $this.TaskbarGroupingModePropertyName -Value $value -Type String + } + # Set USB settings if (!$this.TestNotifyOnUsbErrors($currentState)) { # Ensure registry path exists @@ -629,6 +651,26 @@ class WindowsSettings { return $currentState.DesktopTaskbarBadges -eq $this.DesktopTaskbarBadges } + [string] GetTaskbarGroupingMode() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarGlomLevelRegistryPath -Name $this.TaskbarGroupingModePropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:TaskbarGlomLevelRegistryPath -Name $this.TaskbarGroupingModePropertyName + return switch ($value) { + '0' { 'Always' } + '1' { 'WhenFull' } + '2' { 'Never' } + default { $null } + } + } + + [bool] TestTaskbarGroupingMode([WindowsSettings] $currentState) { + if ([string]::IsNullOrEmpty($this.TaskbarGroupingMode)) { + return $true + } + return $currentState.TaskbarGroupingMode -eq $this.TaskbarGroupingMode + } + [bool] TestNotifyOnUsbErrors([WindowsSettings] $currentState) { if ($null -eq $this.NotifyOnUsbErrors) { return $true diff --git a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget index 7195a483..0a8555db 100644 --- a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget +++ b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget @@ -38,4 +38,7 @@ properties: TaskbarBadges: true # DesktopTaskbarBadges: Enable badges for apps on the desktop taskbar DesktopTaskbarBadges: true + # TaskbarGroupingMode: Control how taskbar buttons are grouped + # Valid values: Always, WhenFull, Never + TaskbarGroupingMode: Always configurationVersion: 0.2.0 diff --git a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 index 223264ad..59a04a00 100644 --- a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 +++ b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 @@ -40,6 +40,7 @@ BeforeAll { $script:originalSettings.ShowRecommendedList = $currentState.ShowRecommendedList $script:originalSettings.TaskbarBadges = $currentState.TaskbarBadges $script:originalSettings.DesktopTaskbarBadges = $currentState.DesktopTaskbarBadges + $script:originalSettings.TaskbarGroupingMode = $currentState.TaskbarGroupingMode $script:originalSettings.NotifyOnUsbErrors = $currentState.NotifyOnUsbErrors $script:originalSettings.NotifyOnWeakCharger = $currentState.NotifyOnWeakCharger @@ -59,6 +60,7 @@ BeforeAll { Write-Host " ShowRecommendedList: $($script:originalSettings.ShowRecommendedList)" Write-Host " TaskbarBadges: $($script:originalSettings.TaskbarBadges)" Write-Host " DesktopTaskbarBadges: $($script:originalSettings.DesktopTaskbarBadges)" + Write-Host " TaskbarGroupingMode: $($script:originalSettings.TaskbarGroupingMode)" Write-Host " NotifyOnUsbErrors: $($script:originalSettings.NotifyOnUsbErrors)" Write-Host " NotifyOnWeakCharger: $($script:originalSettings.NotifyOnWeakCharger)" } @@ -112,6 +114,9 @@ AfterAll { if ($null -ne $script:originalSettings.DesktopTaskbarBadges) { $restoreSettings.DesktopTaskbarBadges = $script:originalSettings.DesktopTaskbarBadges } + if (-not [string]::IsNullOrEmpty($script:originalSettings.TaskbarGroupingMode)) { + $restoreSettings.TaskbarGroupingMode = $script:originalSettings.TaskbarGroupingMode + } if ($null -ne $script:originalSettings.NotifyOnUsbErrors) { $restoreSettings.NotifyOnUsbErrors = $script:originalSettings.NotifyOnUsbErrors } @@ -1049,6 +1054,67 @@ Describe 'WindowsSettings - DesktopTaskbarBadges' { } } +Describe 'WindowsSettings - TaskbarGroupingMode' { + It 'Gets current TaskbarGroupingMode' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be either Always, WhenFull, Never, or null + $currentState.TaskbarGroupingMode | Should -BeIn @('Always', 'WhenFull', 'Never', $null) + } + + It 'Sets TaskbarGroupingMode to Always' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarGroupingMode = 'Always' + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarGroupingMode | Should -Be 'Always' + } + + It 'Sets TaskbarGroupingMode to WhenFull' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarGroupingMode = 'WhenFull' + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarGroupingMode | Should -Be 'WhenFull' + } + + It 'Sets TaskbarGroupingMode to Never' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarGroupingMode = 'Never' + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarGroupingMode | Should -Be 'Never' + } + + It 'Tests TaskbarGroupingMode when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + $settings.TaskbarGroupingMode = $currentState.TaskbarGroupingMode + + $settings.Test() | Should -Be $true + } + + It 'Throws error for invalid TaskbarGroupingMode' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarGroupingMode = 'InvalidValue' + + { $settings.Set() } | Should -Throw '*Invalid TaskbarGroupingMode*' + } +} + Describe 'WindowsSettings - USB' { It 'Gets current NotifyOnUsbErrors' { $settings = [WindowsSettings]::new() From 6baf16094b34603314756ca8ec6c5fd668f22eab Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 15 Jan 2026 03:04:49 +0100 Subject: [PATCH 5/9] Add MultiMonitor --- .../Microsoft.Windows.Settings.psm1 | 64 +++++++++- .../PersonalizationSettings.winget | 4 + .../Microsoft.Windows.Settings.Tests.ps1 | 116 ++++++++++++++++++ 3 files changed, 183 insertions(+), 1 deletion(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index 86c17bf8..cc6dad56 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -16,8 +16,9 @@ if ([string]::IsNullOrEmpty($env:TestRegistryPath)) { $global:USBRegistryPath = 'HKCU:\Software\Microsoft\Shell\USB\' $global:TaskbarBadgesRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarBadges\' $global:TaskbarGlomLevelRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\MMTaskbarGlomLevel\' + $global:TaskbarMultiMonRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\MMTaskbarEnabled\' } else { - $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $global:TaskbarBadgesRegistryPath = $global:TaskbarGlomLevelRegistryPath = $env:TestRegistryPath + $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $global:TaskbarBadgesRegistryPath = $global:TaskbarGlomLevelRegistryPath = $global:TaskbarMultiMonRegistryPath = $env:TestRegistryPath } [DSCResource()] @@ -80,6 +81,13 @@ class WindowsSettings { [DscProperty()] [string] $TaskbarGroupingMode + # Taskbar - Multi-Monitor + [DscProperty()] + [Nullable[bool]] $TaskbarMultiMon + + [DscProperty()] + [Nullable[bool]] $DesktopTaskbarMultiMon + [DscProperty()] [Nullable[bool]] $NotifyOnUsbErrors @@ -105,6 +113,8 @@ class WindowsSettings { hidden [string] $TaskbarBadgingPropertyName = 'SystemSettings_Taskbar_Badging' hidden [string] $DesktopTaskbarBadgingPropertyName = 'SystemSettings_DesktopTaskbar_Badging' hidden [string] $TaskbarGroupingModePropertyName = 'SystemSettings_DesktopTaskbar_GroupingMode' + hidden [string] $TaskbarMultiMonPropertyName = 'SystemSettings_Taskbar_MultiMon' + hidden [string] $DesktopTaskbarMultiMonPropertyName = 'SystemSettings_DesktopTaskbar_MultiMon' hidden [string] $NotifyOnUsbErrorsPropertyName = 'NotifyOnUsbErrors' hidden [string] $NotifyOnWeakChargerPropertyName = 'NotifyOnWeakCharger' @@ -155,6 +165,8 @@ class WindowsSettings { $currentState.TaskbarBadges = $this.GetTaskbarBadges() $currentState.DesktopTaskbarBadges = $this.GetDesktopTaskbarBadges() $currentState.TaskbarGroupingMode = $this.GetTaskbarGroupingMode() + $currentState.TaskbarMultiMon = $this.GetTaskbarMultiMon() + $currentState.DesktopTaskbarMultiMon = $this.GetDesktopTaskbarMultiMon() # Get USB settings $currentState.NotifyOnUsbErrors = $this.GetNotifyOnUsbErrors() @@ -181,6 +193,8 @@ class WindowsSettings { $this.TestTaskbarBadges($currentState) -and $this.TestDesktopTaskbarBadges($currentState) -and $this.TestTaskbarGroupingMode($currentState) -and + $this.TestTaskbarMultiMon($currentState) -and + $this.TestDesktopTaskbarMultiMon($currentState) -and $this.TestNotifyOnUsbErrors($currentState) -and $this.TestNotifyOnWeakCharger($currentState) } @@ -337,6 +351,24 @@ class WindowsSettings { Set-ItemProperty -Path $global:TaskbarGlomLevelRegistryPath -Name $this.TaskbarGroupingModePropertyName -Value $value -Type String } + # Set TaskbarMultiMon + if (!$this.TestTaskbarMultiMon($currentState)) { + if (-not (Test-Path $global:TaskbarMultiMonRegistryPath)) { + New-Item -Path $global:TaskbarMultiMonRegistryPath -Force | Out-Null + } + $value = $this.TaskbarMultiMon ? '1' : '0' + Set-ItemProperty -Path $global:TaskbarMultiMonRegistryPath -Name $this.TaskbarMultiMonPropertyName -Value $value -Type String + } + + # Set DesktopTaskbarMultiMon + if (!$this.TestDesktopTaskbarMultiMon($currentState)) { + if (-not (Test-Path $global:TaskbarMultiMonRegistryPath)) { + New-Item -Path $global:TaskbarMultiMonRegistryPath -Force | Out-Null + } + $value = $this.DesktopTaskbarMultiMon ? '1' : '0' + Set-ItemProperty -Path $global:TaskbarMultiMonRegistryPath -Name $this.DesktopTaskbarMultiMonPropertyName -Value $value -Type String + } + # Set USB settings if (!$this.TestNotifyOnUsbErrors($currentState)) { # Ensure registry path exists @@ -671,6 +703,36 @@ class WindowsSettings { return $currentState.TaskbarGroupingMode -eq $this.TaskbarGroupingMode } + [Nullable[bool]] GetTaskbarMultiMon() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonRegistryPath -Name $this.TaskbarMultiMonPropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonRegistryPath -Name $this.TaskbarMultiMonPropertyName + return $value -eq '1' + } + + [bool] TestTaskbarMultiMon([WindowsSettings] $currentState) { + if ($null -eq $this.TaskbarMultiMon) { + return $true + } + return $currentState.TaskbarMultiMon -eq $this.TaskbarMultiMon + } + + [Nullable[bool]] GetDesktopTaskbarMultiMon() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonRegistryPath -Name $this.DesktopTaskbarMultiMonPropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonRegistryPath -Name $this.DesktopTaskbarMultiMonPropertyName + return $value -eq '1' + } + + [bool] TestDesktopTaskbarMultiMon([WindowsSettings] $currentState) { + if ($null -eq $this.DesktopTaskbarMultiMon) { + return $true + } + return $currentState.DesktopTaskbarMultiMon -eq $this.DesktopTaskbarMultiMon + } + [bool] TestNotifyOnUsbErrors([WindowsSettings] $currentState) { if ($null -eq $this.NotifyOnUsbErrors) { return $true diff --git a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget index 0a8555db..4a67994f 100644 --- a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget +++ b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget @@ -41,4 +41,8 @@ properties: # TaskbarGroupingMode: Control how taskbar buttons are grouped # Valid values: Always, WhenFull, Never TaskbarGroupingMode: Always + # TaskbarMultiMon: Show taskbar on multiple displays + TaskbarMultiMon: true + # DesktopTaskbarMultiMon: Show taskbar on multiple displays (desktop) + DesktopTaskbarMultiMon: true configurationVersion: 0.2.0 diff --git a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 index 59a04a00..66ca1020 100644 --- a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 +++ b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 @@ -41,6 +41,8 @@ BeforeAll { $script:originalSettings.TaskbarBadges = $currentState.TaskbarBadges $script:originalSettings.DesktopTaskbarBadges = $currentState.DesktopTaskbarBadges $script:originalSettings.TaskbarGroupingMode = $currentState.TaskbarGroupingMode + $script:originalSettings.TaskbarMultiMon = $currentState.TaskbarMultiMon + $script:originalSettings.DesktopTaskbarMultiMon = $currentState.DesktopTaskbarMultiMon $script:originalSettings.NotifyOnUsbErrors = $currentState.NotifyOnUsbErrors $script:originalSettings.NotifyOnWeakCharger = $currentState.NotifyOnWeakCharger @@ -61,6 +63,8 @@ BeforeAll { Write-Host " TaskbarBadges: $($script:originalSettings.TaskbarBadges)" Write-Host " DesktopTaskbarBadges: $($script:originalSettings.DesktopTaskbarBadges)" Write-Host " TaskbarGroupingMode: $($script:originalSettings.TaskbarGroupingMode)" + Write-Host " TaskbarMultiMon: $($script:originalSettings.TaskbarMultiMon)" + Write-Host " DesktopTaskbarMultiMon: $($script:originalSettings.DesktopTaskbarMultiMon)" Write-Host " NotifyOnUsbErrors: $($script:originalSettings.NotifyOnUsbErrors)" Write-Host " NotifyOnWeakCharger: $($script:originalSettings.NotifyOnWeakCharger)" } @@ -117,6 +121,12 @@ AfterAll { if (-not [string]::IsNullOrEmpty($script:originalSettings.TaskbarGroupingMode)) { $restoreSettings.TaskbarGroupingMode = $script:originalSettings.TaskbarGroupingMode } + if ($null -ne $script:originalSettings.TaskbarMultiMon) { + $restoreSettings.TaskbarMultiMon = $script:originalSettings.TaskbarMultiMon + } + if ($null -ne $script:originalSettings.DesktopTaskbarMultiMon) { + $restoreSettings.DesktopTaskbarMultiMon = $script:originalSettings.DesktopTaskbarMultiMon + } if ($null -ne $script:originalSettings.NotifyOnUsbErrors) { $restoreSettings.NotifyOnUsbErrors = $script:originalSettings.NotifyOnUsbErrors } @@ -1115,6 +1125,112 @@ Describe 'WindowsSettings - TaskbarGroupingMode' { } } +Describe 'WindowsSettings - TaskbarMultiMon' { + It 'Gets current TaskbarMultiMon' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be either $true, $false, or $null + $currentState.TaskbarMultiMon | Should -BeIn @($true, $false, $null) + } + + It 'Sets TaskbarMultiMon to enabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarMultiMon = $true + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarMultiMon | Should -Be $true + } + + It 'Sets TaskbarMultiMon to disabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarMultiMon = $false + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarMultiMon | Should -Be $false + } + + It 'Tests TaskbarMultiMon when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + $settings.TaskbarMultiMon = $currentState.TaskbarMultiMon + + $settings.Test() | Should -Be $true + } + + It 'Tests TaskbarMultiMon when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Set opposite value + $settings.TaskbarMultiMon = -not $currentState.TaskbarMultiMon + + $settings.Test() | Should -Be $false + } +} + +Describe 'WindowsSettings - DesktopTaskbarMultiMon' { + It 'Gets current DesktopTaskbarMultiMon' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be either $true, $false, or $null + $currentState.DesktopTaskbarMultiMon | Should -BeIn @($true, $false, $null) + } + + It 'Sets DesktopTaskbarMultiMon to enabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarMultiMon = $true + + $settings.Set() + + $newState = $settings.Get() + $newState.DesktopTaskbarMultiMon | Should -Be $true + } + + It 'Sets DesktopTaskbarMultiMon to disabled' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarMultiMon = $false + + $settings.Set() + + $newState = $settings.Get() + $newState.DesktopTaskbarMultiMon | Should -Be $false + } + + It 'Tests DesktopTaskbarMultiMon when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + $settings.DesktopTaskbarMultiMon = $currentState.DesktopTaskbarMultiMon + + $settings.Test() | Should -Be $true + } + + It 'Tests DesktopTaskbarMultiMon when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Set opposite value + $settings.DesktopTaskbarMultiMon = -not $currentState.DesktopTaskbarMultiMon + + $settings.Test() | Should -Be $false + } +} + Describe 'WindowsSettings - USB' { It 'Gets current NotifyOnUsbErrors' { $settings = [WindowsSettings]::new() From bccad559374a21bbbe56f414e12d9d69a80be1b7 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 15 Jan 2026 03:10:38 +0100 Subject: [PATCH 6/9] Add MultiMonitor taskbar --- .../Microsoft.Windows.Settings.psm1 | 84 ++++++++- .../PersonalizationSettings.winget | 8 + .../Microsoft.Windows.Settings.Tests.ps1 | 176 +++++++++++++++++- 3 files changed, 265 insertions(+), 3 deletions(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index cc6dad56..e83231b2 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -17,8 +17,9 @@ if ([string]::IsNullOrEmpty($env:TestRegistryPath)) { $global:TaskbarBadgesRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarBadges\' $global:TaskbarGlomLevelRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\MMTaskbarGlomLevel\' $global:TaskbarMultiMonRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\MMTaskbarEnabled\' + $global:TaskbarMultiMonModeRegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\MMTaskbarMode\' } else { - $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $global:TaskbarBadgesRegistryPath = $global:TaskbarGlomLevelRegistryPath = $global:TaskbarMultiMonRegistryPath = $env:TestRegistryPath + $global:ExplorerRegistryPath = $global:PersonalizeRegistryPath = $global:AppModelUnlockRegistryPath = $global:TimeZoneAutoUpdateRegistryPath = $global:TimeZoneInformationRegistryPath = $global:DesktopRegistryPath = $global:DWMRegistryPath = $global:StartRegistryPath = $global:USBRegistryPath = $global:TaskbarBadgesRegistryPath = $global:TaskbarGlomLevelRegistryPath = $global:TaskbarMultiMonRegistryPath = $global:TaskbarMultiMonModeRegistryPath = $env:TestRegistryPath } [DSCResource()] @@ -88,6 +89,13 @@ class WindowsSettings { [DscProperty()] [Nullable[bool]] $DesktopTaskbarMultiMon + # Taskbar - Multi-Monitor Mode + [DscProperty()] + [string] $TaskbarMultiMonMode + + [DscProperty()] + [string] $DesktopTaskbarMultiMonMode + [DscProperty()] [Nullable[bool]] $NotifyOnUsbErrors @@ -115,6 +123,8 @@ class WindowsSettings { hidden [string] $TaskbarGroupingModePropertyName = 'SystemSettings_DesktopTaskbar_GroupingMode' hidden [string] $TaskbarMultiMonPropertyName = 'SystemSettings_Taskbar_MultiMon' hidden [string] $DesktopTaskbarMultiMonPropertyName = 'SystemSettings_DesktopTaskbar_MultiMon' + hidden [string] $TaskbarMultiMonModePropertyName = 'SystemSettings_Taskbar_MultiMonTaskbarMode' + hidden [string] $DesktopTaskbarMultiMonModePropertyName = 'SystemSettings_DesktopTaskbar_MultiMonTaskbarMode' hidden [string] $NotifyOnUsbErrorsPropertyName = 'NotifyOnUsbErrors' hidden [string] $NotifyOnWeakChargerPropertyName = 'NotifyOnWeakCharger' @@ -167,6 +177,8 @@ class WindowsSettings { $currentState.TaskbarGroupingMode = $this.GetTaskbarGroupingMode() $currentState.TaskbarMultiMon = $this.GetTaskbarMultiMon() $currentState.DesktopTaskbarMultiMon = $this.GetDesktopTaskbarMultiMon() + $currentState.TaskbarMultiMonMode = $this.GetTaskbarMultiMonMode() + $currentState.DesktopTaskbarMultiMonMode = $this.GetDesktopTaskbarMultiMonMode() # Get USB settings $currentState.NotifyOnUsbErrors = $this.GetNotifyOnUsbErrors() @@ -195,6 +207,8 @@ class WindowsSettings { $this.TestTaskbarGroupingMode($currentState) -and $this.TestTaskbarMultiMon($currentState) -and $this.TestDesktopTaskbarMultiMon($currentState) -and + $this.TestTaskbarMultiMonMode($currentState) -and + $this.TestDesktopTaskbarMultiMonMode($currentState) -and $this.TestNotifyOnUsbErrors($currentState) -and $this.TestNotifyOnWeakCharger($currentState) } @@ -369,6 +383,34 @@ class WindowsSettings { Set-ItemProperty -Path $global:TaskbarMultiMonRegistryPath -Name $this.DesktopTaskbarMultiMonPropertyName -Value $value -Type String } + # Set TaskbarMultiMonMode + if (!$this.TestTaskbarMultiMonMode($currentState)) { + if (-not (Test-Path $global:TaskbarMultiMonModeRegistryPath)) { + New-Item -Path $global:TaskbarMultiMonModeRegistryPath -Force | Out-Null + } + $value = switch ($this.TaskbarMultiMonMode) { + 'Duplicate' { '0' } + 'PrimaryAndWindow' { '1' } + 'WindowOnly' { '2' } + default { throw "Invalid TaskbarMultiMonMode: $($this.TaskbarMultiMonMode). Valid values are: Duplicate, PrimaryAndWindow, WindowOnly" } + } + Set-ItemProperty -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.TaskbarMultiMonModePropertyName -Value $value -Type String + } + + # Set DesktopTaskbarMultiMonMode + if (!$this.TestDesktopTaskbarMultiMonMode($currentState)) { + if (-not (Test-Path $global:TaskbarMultiMonModeRegistryPath)) { + New-Item -Path $global:TaskbarMultiMonModeRegistryPath -Force | Out-Null + } + $value = switch ($this.DesktopTaskbarMultiMonMode) { + 'Duplicate' { '0' } + 'PrimaryAndWindow' { '1' } + 'WindowOnly' { '2' } + default { throw "Invalid DesktopTaskbarMultiMonMode: $($this.DesktopTaskbarMultiMonMode). Valid values are: Duplicate, PrimaryAndWindow, WindowOnly" } + } + Set-ItemProperty -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.DesktopTaskbarMultiMonModePropertyName -Value $value -Type String + } + # Set USB settings if (!$this.TestNotifyOnUsbErrors($currentState)) { # Ensure registry path exists @@ -733,6 +775,46 @@ class WindowsSettings { return $currentState.DesktopTaskbarMultiMon -eq $this.DesktopTaskbarMultiMon } + [string] GetTaskbarMultiMonMode() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.TaskbarMultiMonModePropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.TaskbarMultiMonModePropertyName + return switch ($value) { + '0' { 'Duplicate' } + '1' { 'PrimaryAndWindow' } + '2' { 'WindowOnly' } + default { $null } + } + } + + [bool] TestTaskbarMultiMonMode([WindowsSettings] $currentState) { + if ([string]::IsNullOrEmpty($this.TaskbarMultiMonMode)) { + return $true + } + return $currentState.TaskbarMultiMonMode -eq $this.TaskbarMultiMonMode + } + + [string] GetDesktopTaskbarMultiMonMode() { + if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.DesktopTaskbarMultiMonModePropertyName)) { + return $null + } + $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.DesktopTaskbarMultiMonModePropertyName + return switch ($value) { + '0' { 'Duplicate' } + '1' { 'PrimaryAndWindow' } + '2' { 'WindowOnly' } + default { $null } + } + } + + [bool] TestDesktopTaskbarMultiMonMode([WindowsSettings] $currentState) { + if ([string]::IsNullOrEmpty($this.DesktopTaskbarMultiMonMode)) { + return $true + } + return $currentState.DesktopTaskbarMultiMonMode -eq $this.DesktopTaskbarMultiMonMode + } + [bool] TestNotifyOnUsbErrors([WindowsSettings] $currentState) { if ($null -eq $this.NotifyOnUsbErrors) { return $true diff --git a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget index 4a67994f..b94250f4 100644 --- a/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget +++ b/samples/DscResources/Microsoft.Windows.Settings/PersonalizationSettings.winget @@ -45,4 +45,12 @@ properties: TaskbarMultiMon: true # DesktopTaskbarMultiMon: Show taskbar on multiple displays (desktop) DesktopTaskbarMultiMon: true + # TaskbarMultiMonMode: Control how windows are shown on taskbars across monitors + # Valid values: Duplicate, PrimaryAndWindow, WindowOnly + # - Duplicate: Show all windows on all taskbars + # - PrimaryAndWindow: Show on main taskbar and on the taskbar where the window is open + # - WindowOnly: Show only on the taskbar where the window is open + TaskbarMultiMonMode: Duplicate + # DesktopTaskbarMultiMonMode: Control how windows are shown on taskbars across monitors (desktop) + DesktopTaskbarMultiMonMode: Duplicate configurationVersion: 0.2.0 diff --git a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 index 66ca1020..e3c3bf5d 100644 --- a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 +++ b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 @@ -43,6 +43,8 @@ BeforeAll { $script:originalSettings.TaskbarGroupingMode = $currentState.TaskbarGroupingMode $script:originalSettings.TaskbarMultiMon = $currentState.TaskbarMultiMon $script:originalSettings.DesktopTaskbarMultiMon = $currentState.DesktopTaskbarMultiMon + $script:originalSettings.TaskbarMultiMonMode = $currentState.TaskbarMultiMonMode + $script:originalSettings.DesktopTaskbarMultiMonMode = $currentState.DesktopTaskbarMultiMonMode $script:originalSettings.NotifyOnUsbErrors = $currentState.NotifyOnUsbErrors $script:originalSettings.NotifyOnWeakCharger = $currentState.NotifyOnWeakCharger @@ -65,6 +67,8 @@ BeforeAll { Write-Host " TaskbarGroupingMode: $($script:originalSettings.TaskbarGroupingMode)" Write-Host " TaskbarMultiMon: $($script:originalSettings.TaskbarMultiMon)" Write-Host " DesktopTaskbarMultiMon: $($script:originalSettings.DesktopTaskbarMultiMon)" + Write-Host " TaskbarMultiMonMode: $($script:originalSettings.TaskbarMultiMonMode)" + Write-Host " DesktopTaskbarMultiMonMode: $($script:originalSettings.DesktopTaskbarMultiMonMode)" Write-Host " NotifyOnUsbErrors: $($script:originalSettings.NotifyOnUsbErrors)" Write-Host " NotifyOnWeakCharger: $($script:originalSettings.NotifyOnWeakCharger)" } @@ -127,6 +131,12 @@ AfterAll { if ($null -ne $script:originalSettings.DesktopTaskbarMultiMon) { $restoreSettings.DesktopTaskbarMultiMon = $script:originalSettings.DesktopTaskbarMultiMon } + if (-not [string]::IsNullOrEmpty($script:originalSettings.TaskbarMultiMonMode)) { + $restoreSettings.TaskbarMultiMonMode = $script:originalSettings.TaskbarMultiMonMode + } + if (-not [string]::IsNullOrEmpty($script:originalSettings.DesktopTaskbarMultiMonMode)) { + $restoreSettings.DesktopTaskbarMultiMonMode = $script:originalSettings.DesktopTaskbarMultiMonMode + } if ($null -ne $script:originalSettings.NotifyOnUsbErrors) { $restoreSettings.NotifyOnUsbErrors = $script:originalSettings.NotifyOnUsbErrors } @@ -1231,6 +1241,170 @@ Describe 'WindowsSettings - DesktopTaskbarMultiMon' { } } +Describe 'WindowsSettings - TaskbarMultiMonMode' { + It 'Gets current TaskbarMultiMonMode' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be one of the valid values or null + $currentState.TaskbarMultiMonMode | Should -BeIn @('Duplicate', 'PrimaryAndWindow', 'WindowOnly', $null) + } + + It 'Sets TaskbarMultiMonMode to Duplicate' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarMultiMonMode = 'Duplicate' + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarMultiMonMode | Should -Be 'Duplicate' + } + + It 'Sets TaskbarMultiMonMode to PrimaryAndWindow' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarMultiMonMode = 'PrimaryAndWindow' + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarMultiMonMode | Should -Be 'PrimaryAndWindow' + } + + It 'Sets TaskbarMultiMonMode to WindowOnly' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarMultiMonMode = 'WindowOnly' + + $settings.Set() + + $newState = $settings.Get() + $newState.TaskbarMultiMonMode | Should -Be 'WindowOnly' + } + + It 'Tests TaskbarMultiMonMode when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + + # First set a known value + $settings.TaskbarMultiMonMode = 'Duplicate' + $settings.Set() + + # Now test with same value + $testSettings = [WindowsSettings]::new() + $testSettings.SID = 'TestSID' + $testSettings.TaskbarMultiMonMode = 'Duplicate' + + $testSettings.Test() | Should -Be $true + } + + It 'Tests TaskbarMultiMonMode when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + + # First set a known value + $settings.TaskbarMultiMonMode = 'Duplicate' + $settings.Set() + + # Now test with different value + $testSettings = [WindowsSettings]::new() + $testSettings.SID = 'TestSID' + $testSettings.TaskbarMultiMonMode = 'WindowOnly' + + $testSettings.Test() | Should -Be $false + } + + It 'Throws error for invalid TaskbarMultiMonMode' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.TaskbarMultiMonMode = 'InvalidValue' + + { $settings.Set() } | Should -Throw '*Invalid TaskbarMultiMonMode*' + } +} + +Describe 'WindowsSettings - DesktopTaskbarMultiMonMode' { + It 'Gets current DesktopTaskbarMultiMonMode' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $currentState = $settings.Get() + + # Should be one of the valid values or null + $currentState.DesktopTaskbarMultiMonMode | Should -BeIn @('Duplicate', 'PrimaryAndWindow', 'WindowOnly', $null) + } + + It 'Sets DesktopTaskbarMultiMonMode to Duplicate' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarMultiMonMode = 'Duplicate' + + $settings.Set() + + $newState = $settings.Get() + $newState.DesktopTaskbarMultiMonMode | Should -Be 'Duplicate' + } + + It 'Sets DesktopTaskbarMultiMonMode to PrimaryAndWindow' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarMultiMonMode = 'PrimaryAndWindow' + + $settings.Set() + + $newState = $settings.Get() + $newState.DesktopTaskbarMultiMonMode | Should -Be 'PrimaryAndWindow' + } + + It 'Sets DesktopTaskbarMultiMonMode to WindowOnly' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarMultiMonMode = 'WindowOnly' + + $settings.Set() + + $newState = $settings.Get() + $newState.DesktopTaskbarMultiMonMode | Should -Be 'WindowOnly' + } + + It 'Tests DesktopTaskbarMultiMonMode when values match' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + + $settings.DesktopTaskbarMultiMonMode = 'Duplicate' + $settings.Set() + + $testSettings = [WindowsSettings]::new() + $testSettings.SID = 'TestSID' + $testSettings.DesktopTaskbarMultiMonMode = 'Duplicate' + + $testSettings.Test() | Should -Be $true + } + + It 'Tests DesktopTaskbarMultiMonMode when values differ' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + + $settings.DesktopTaskbarMultiMonMode = 'Duplicate' + $settings.Set() + + $testSettings = [WindowsSettings]::new() + $testSettings.SID = 'TestSID' + $testSettings.DesktopTaskbarMultiMonMode = 'WindowOnly' + + $testSettings.Test() | Should -Be $false + } + + It 'Throws error for invalid DesktopTaskbarMultiMonMode' { + $settings = [WindowsSettings]::new() + $settings.SID = 'TestSID' + $settings.DesktopTaskbarMultiMonMode = 'InvalidValue' + + { $settings.Set() } | Should -Throw '*Invalid DesktopTaskbarMultiMonMode*' + } +} + Describe 'WindowsSettings - USB' { It 'Gets current NotifyOnUsbErrors' { $settings = [WindowsSettings]::new() @@ -1255,7 +1429,6 @@ Describe 'WindowsSettings - USB' { $settings.SID = 'TestSID' $currentState = $settings.Get() - # Set opposite value to ensure change $settings.NotifyOnUsbErrors = -not $currentState.NotifyOnUsbErrors $settings.Test() | Should -Be $false @@ -1270,7 +1443,6 @@ Describe 'WindowsSettings - USB' { $settings.SID = 'TestSID' $currentState = $settings.Get() - # Set opposite value to ensure change $settings.NotifyOnWeakCharger = -not $currentState.NotifyOnWeakCharger $settings.Test() | Should -Be $false From 7965ada731e975ae12727c70f3c35a5e6920adff Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 22 Jan 2026 18:45:00 +0100 Subject: [PATCH 7/9] Return value does not allow switch statement --- .../Microsoft.Windows.Settings.psm1 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index e83231b2..4cba9fdd 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -730,12 +730,13 @@ class WindowsSettings { return $null } $value = Get-ItemPropertyValue -Path $global:TaskbarGlomLevelRegistryPath -Name $this.TaskbarGroupingModePropertyName - return switch ($value) { + $returnValue = switch ($value) { '0' { 'Always' } '1' { 'WhenFull' } '2' { 'Never' } default { $null } } + return $returnValue } [bool] TestTaskbarGroupingMode([WindowsSettings] $currentState) { @@ -780,12 +781,13 @@ class WindowsSettings { return $null } $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.TaskbarMultiMonModePropertyName - return switch ($value) { + $returnValue = switch ($value) { '0' { 'Duplicate' } '1' { 'PrimaryAndWindow' } '2' { 'WindowOnly' } default { $null } } + return $returnValue } [bool] TestTaskbarMultiMonMode([WindowsSettings] $currentState) { @@ -800,12 +802,13 @@ class WindowsSettings { return $null } $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.DesktopTaskbarMultiMonModePropertyName - return switch ($value) { + $returnValue = switch ($value) { '0' { 'Duplicate' } '1' { 'PrimaryAndWindow' } '2' { 'WindowOnly' } default { $null } } + return $returnValue } [bool] TestDesktopTaskbarMultiMonMode([WindowsSettings] $currentState) { From e2ded063ace59dbf06fb4768f3401c3e57fe8bac Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 22 Jan 2026 19:11:54 +0100 Subject: [PATCH 8/9] Convert to object --- .../Microsoft.Windows.Settings.psm1 | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index 4cba9fdd..6dd746f5 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -725,18 +725,17 @@ class WindowsSettings { return $currentState.DesktopTaskbarBadges -eq $this.DesktopTaskbarBadges } - [string] GetTaskbarGroupingMode() { + [object] GetTaskbarGroupingMode() { if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarGlomLevelRegistryPath -Name $this.TaskbarGroupingModePropertyName)) { return $null } $value = Get-ItemPropertyValue -Path $global:TaskbarGlomLevelRegistryPath -Name $this.TaskbarGroupingModePropertyName - $returnValue = switch ($value) { - '0' { 'Always' } - '1' { 'WhenFull' } - '2' { 'Never' } - default { $null } + switch ($value) { + '0' { return 'Always' } + '1' { return 'WhenFull' } + '2' { return 'Never' } } - return $returnValue + return $null } [bool] TestTaskbarGroupingMode([WindowsSettings] $currentState) { @@ -776,18 +775,17 @@ class WindowsSettings { return $currentState.DesktopTaskbarMultiMon -eq $this.DesktopTaskbarMultiMon } - [string] GetTaskbarMultiMonMode() { + [object] GetTaskbarMultiMonMode() { if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.TaskbarMultiMonModePropertyName)) { return $null } $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.TaskbarMultiMonModePropertyName - $returnValue = switch ($value) { - '0' { 'Duplicate' } - '1' { 'PrimaryAndWindow' } - '2' { 'WindowOnly' } - default { $null } + switch ($value) { + '0' { return 'Duplicate' } + '1' { return 'PrimaryAndWindow' } + '2' { return 'WindowOnly' } } - return $returnValue + return $null } [bool] TestTaskbarMultiMonMode([WindowsSettings] $currentState) { @@ -797,18 +795,17 @@ class WindowsSettings { return $currentState.TaskbarMultiMonMode -eq $this.TaskbarMultiMonMode } - [string] GetDesktopTaskbarMultiMonMode() { + [object] GetDesktopTaskbarMultiMonMode() { if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.DesktopTaskbarMultiMonModePropertyName)) { return $null } $value = Get-ItemPropertyValue -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.DesktopTaskbarMultiMonModePropertyName - $returnValue = switch ($value) { - '0' { 'Duplicate' } - '1' { 'PrimaryAndWindow' } - '2' { 'WindowOnly' } - default { $null } + switch ($value) { + '0' { return 'Duplicate' } + '1' { return 'PrimaryAndWindow' } + '2' { return 'WindowOnly' } } - return $returnValue + return $null } [bool] TestDesktopTaskbarMultiMonMode([WindowsSettings] $currentState) { From 10d81042b8b81a179247764e937e2abe3ab853a5 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Fri, 23 Jan 2026 04:03:57 +0100 Subject: [PATCH 9/9] Revert to string and fix up tests --- .../Microsoft.Windows.Settings.psm1 | 4 ++-- .../Microsoft.Windows.Settings.Tests.ps1 | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 index 6dd746f5..8d2c385b 100644 --- a/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 +++ b/resources/Microsoft.Windows.Settings/Microsoft.Windows.Settings.psm1 @@ -775,7 +775,7 @@ class WindowsSettings { return $currentState.DesktopTaskbarMultiMon -eq $this.DesktopTaskbarMultiMon } - [object] GetTaskbarMultiMonMode() { + [string] GetTaskbarMultiMonMode() { if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.TaskbarMultiMonModePropertyName)) { return $null } @@ -795,7 +795,7 @@ class WindowsSettings { return $currentState.TaskbarMultiMonMode -eq $this.TaskbarMultiMonMode } - [object] GetDesktopTaskbarMultiMonMode() { + [string] GetDesktopTaskbarMultiMonMode() { if (-not(DoesRegistryKeyPropertyExist -Path $global:TaskbarMultiMonModeRegistryPath -Name $this.DesktopTaskbarMultiMonModePropertyName)) { return $null } diff --git a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 index e3c3bf5d..d6b5dcb4 100644 --- a/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 +++ b/tests/Microsoft.Windows.Settings/Microsoft.Windows.Settings.Tests.ps1 @@ -1080,8 +1080,8 @@ Describe 'WindowsSettings - TaskbarGroupingMode' { $settings.SID = 'TestSID' $currentState = $settings.Get() - # Should be either Always, WhenFull, Never, or null - $currentState.TaskbarGroupingMode | Should -BeIn @('Always', 'WhenFull', 'Never', $null) + # Should be either Always, WhenFull, Never, null, or empty string + $currentState.TaskbarGroupingMode | Should -BeIn @('Always', 'WhenFull', 'Never', $null, '') } It 'Sets TaskbarGroupingMode to Always' { @@ -1247,8 +1247,8 @@ Describe 'WindowsSettings - TaskbarMultiMonMode' { $settings.SID = 'TestSID' $currentState = $settings.Get() - # Should be one of the valid values or null - $currentState.TaskbarMultiMonMode | Should -BeIn @('Duplicate', 'PrimaryAndWindow', 'WindowOnly', $null) + # Should be one of the valid values, null, or empty string + $currentState.TaskbarMultiMonMode | Should -BeIn @('Duplicate', 'PrimaryAndWindow', 'WindowOnly', $null, '') } It 'Sets TaskbarMultiMonMode to Duplicate' { @@ -1331,8 +1331,8 @@ Describe 'WindowsSettings - DesktopTaskbarMultiMonMode' { $settings.SID = 'TestSID' $currentState = $settings.Get() - # Should be one of the valid values or null - $currentState.DesktopTaskbarMultiMonMode | Should -BeIn @('Duplicate', 'PrimaryAndWindow', 'WindowOnly', $null) + # Should be one of the valid values, null, or empty string + $currentState.DesktopTaskbarMultiMonMode | Should -BeIn @('Duplicate', 'PrimaryAndWindow', 'WindowOnly', $null, '') } It 'Sets DesktopTaskbarMultiMonMode to Duplicate' {