diff --git a/functions/private/Set-WinUtilService.ps1 b/functions/private/Set-WinUtilService.ps1 index 8be5525efd..46d9232abd 100644 --- a/functions/private/Set-WinUtilService.ps1 +++ b/functions/private/Set-WinUtilService.ps1 @@ -33,7 +33,10 @@ Function Set-WinUtilService { # Service exists, proceed with changing properties -- while handling auto delayed start for PWSH 5 if (($PSVersionTable.PSVersion.Major -lt 7) -and ($StartupType -eq "AutomaticDelayedStart")) { - sc.exe config $Name start=delayed-auto + sc.exe config $Name start= delayed-auto + if ($LASTEXITCODE -ne 0) { + throw "sc.exe config failed with exit code $LASTEXITCODE" + } } else { $service | Set-Service -StartupType $StartupType -ErrorAction Stop } diff --git a/functions/public/Invoke-WPFFixesUpdate.ps1 b/functions/public/Invoke-WPFFixesUpdate.ps1 index 4d7cfcefa4..7fc04550c2 100644 --- a/functions/public/Invoke-WPFFixesUpdate.ps1 +++ b/functions/public/Invoke-WPFFixesUpdate.ps1 @@ -114,9 +114,9 @@ function Invoke-WPFFixesUpdate { if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate") { Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing WSUS client settings..." -PercentComplete 60 Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -PercentComplete 0 - Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "AccountDomainSid", "/f" -RedirectStandardError "NUL" - Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "PingID", "/f" -RedirectStandardError "NUL" - Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "SusClientId", "/f" -RedirectStandardError "NUL" + Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" -Name "AccountDomainSid" -ErrorAction SilentlyContinue + Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" -Name "PingID" -ErrorAction SilentlyContinue + Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" -Name "SusClientId" -ErrorAction SilentlyContinue Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -Status "Completed" -PercentComplete 100 } diff --git a/functions/public/Invoke-WPFImpex.ps1 b/functions/public/Invoke-WPFImpex.ps1 index b3c0ae16dd..5748811a02 100644 --- a/functions/public/Invoke-WPFImpex.ps1 +++ b/functions/public/Invoke-WPFImpex.ps1 @@ -73,9 +73,17 @@ function Invoke-WPFImpex { Write-Error "Failed to load the JSON file from the specified path or URL: $_" return } - # TODO how to handle old style? detected json type then flatten it in a func? - # $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value }) - $flattenedJson = $jsonFile + if ($null -ne $jsonFile -and $jsonFile.PSObject.Properties['Install']) { + Write-WinUtilLog -Component "Impex" -Message "Detected legacy WinUtil config structure; flattening import object." + $flattenedJson = @() + foreach ($prop in $jsonFile.PSObject.Properties) { + if ($prop.Name -ne "Install" -and $null -ne $prop.Value) { + $flattenedJson += @($prop.Value) + } + } + } else { + $flattenedJson = $jsonFile + } if (-not $flattenedJson) { [System.Windows.MessageBox]::Show( diff --git a/pester/ui-state.Tests.ps1 b/pester/ui-state.Tests.ps1 index 1f2809f002..b7a0e77cfd 100644 --- a/pester/ui-state.Tests.ps1 +++ b/pester/ui-state.Tests.ps1 @@ -271,6 +271,30 @@ Describe "Invoke-WPFImpex import selection state" { Should -Invoke -CommandName Write-Error -Times 0 -Exactly } + It "imports legacy selection groups without treating Install metadata as a selection" { + $legacyConfigPath = Join-Path $TestDrive "legacy-config.json" + [ordered]@{ + Install = @( + [pscustomobject]@{ + winget = "Git.Git" + choco = "git" + } + ) + WPFInstall = @("WPFInstallGit") + WPFTweaks = @("WPFTweaksTelemetry") + WPFToggle = @("WPFToggleDarkMode") + WPFFeature = @("WPFFeatureSandbox") + } | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $legacyConfigPath + + Invoke-WPFImpex -type "import" -Config $legacyConfigPath + + @($script:sync.selectedApps) | Should -Be @("WPFInstallGit") + @($script:sync.selectedTweaks) | Should -Be @("WPFTweaksTelemetry") + @($script:sync.selectedToggles) | Should -Be @("WPFToggleDarkMode") + @($script:sync.selectedFeatures) | Should -Be @("WPFFeatureSandbox") + Should -Invoke -CommandName Write-Error -Times 0 -Exactly + } + It "preserves selections and does not reset the UI after an invalid import" { $script:sync.selectedApps.Add("WPFInstallExisting") $script:sync.selectedTweaks.Add("WPFTweaksExisting")