# Check PowerShell version for use in path if ($PSVersionTable.PSVersion.Major -ge 3) { # Use new variable syntax in PowerShell 3 and above $currentDir = $PSScriptRoot } else { # Use old variable syntax in Windows PowerShell 3 and below $currentDir = (Get-Item .).FullName } # Import script-helper.ps1 . "$currentDir\..\..\scripts\script-helper.ps1" # Get system information $systemInfo = Get-SystemInfo $windowsInfo = Get-WindowsVersionDetails # Create a systemRestore point before making any changes to the system, # this way we can be sure that the user can easily revert back to a working state if anything goes wrong. Checkpoint-Computer -Description "Pre-UpdatePackages-oxmc Changes" -RestorePointType "MODIFY_SETTINGS" # Create a backupfolder for the registry, # this way we can be sure that we can easily revert back to a working state if anything goes wrong with the registry changes. $backupFolder = "$windowsDrive\Windows\OEM\RegistryBackups" $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" # Ensure backup folder exists if (-not (Test-Path $backupFolder)) { New-Item -Path $backupFolder -ItemType Directory | Out-Null } # Save the registry backup with a timestamp, and the build number of windows as the filename, # this way we can easily identify the backup and restore it if anything goes wrong. $backupPath = "$backupFolder\RegistryBackup_Build-$($systemInfo.BuildNumber)_$($timestamp)" # Define hives to backup $hives = @("HKLM", "HKCU", "HKCR", "HKU", "HKCC") foreach ($hive in $hives) { try { $backupFile = "$backupPath`_$hive.reg" reg export $hive $backupFile /y | Out-Null Write-Output "Backup succeeded for $hive -> $backupFile" } catch { Write-Warning "Failed to backup $hive. Error: $_" } } # ========================================= # Cleanup old registry backups (keep 20) # ========================================= # This ensures we don't accumulate unlimited backups over time, # while still retaining a reasonable rollback history. $maxBackups = 20 $files = Get-ChildItem -Path $backupFolder -Filter "RegistryBackup_Build-*.reg" -File $groups = $files | ForEach-Object { if ($_.BaseName -match "^(RegistryBackup_Build-\d+_\d{8}_\d{6})_") { [PSCustomObject]@{ BaseName = $matches[1] File = $_ } } } | Group-Object BaseName $sortedGroups = $groups | Sort-Object { if ($_.Name -match "_(\d{8}_\d{6})$") { [datetime]::ParseExact($matches[1], "yyyyMMdd_HHmmss", $null) } } -Descending $groupsToDelete = $sortedGroups | Select-Object -Skip $maxBackups foreach ($group in $groupsToDelete) { foreach ($item in $group.Group) { try { Remove-Item $item.File.FullName -Force -ErrorAction Stop Write-Output "Removed old backup file: $($item.File.Name)" } catch { Write-Warning "Failed to remove $($item.File.Name): $_" } } } # On certain windows versions we have to run specific commands and or apply registry updates, # As this update script is made to fix/migrate settings for new windows updates and features, # we will use the build number as a reference to run those commands, # this way we can be sure that the script will work on older and newer windows versions without breaking anything. # Windows 11 22H2 and above (All editions) #Invoke-CommandsForBuildVersion -targetBuildNumber 22000 -commands { # # Add any commands or registry updates that are specific to Windows 11 22H2 and above here #}