mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-07-03 07:08:27 +00:00
Update start menu backup/restore with timestamped filenames (#672)
This commit is contained in:
@@ -113,11 +113,15 @@ function ReplaceStartMenu {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$backupBinFile = $startMenuBinFile + ".bak"
|
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
|
||||||
|
$backupFileName = "Win11Debloat-StartBackup-$timestamp.bak"
|
||||||
|
$startMenuDir = Split-Path $startMenuBinFile -Parent
|
||||||
|
$backupBinFile = Join-Path $startMenuDir $backupFileName
|
||||||
|
|
||||||
if (Test-Path $startMenuBinFile) {
|
if (Test-Path $startMenuBinFile) {
|
||||||
# Backup current start menu file
|
# Backup current start menu file
|
||||||
Move-Item -Path $startMenuBinFile -Destination $backupBinFile -Force
|
Copy-Item -Path $startMenuBinFile -Destination $backupBinFile -Force
|
||||||
|
Write-Verbose "Start menu backup for user $userName saved to $backupFileName"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Host "Unable to find original start2.bin file for user $userName, no backup was created for this user" -ForegroundColor Yellow
|
Write-Host "Unable to find original start2.bin file for user $userName, no backup was created for this user" -ForegroundColor Yellow
|
||||||
@@ -189,6 +193,55 @@ function GetStartMenuUserNameFromPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Returns the path to the latest start menu backup file for the given scope.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Resolves the LocalState folder for the specified scope and returns the
|
||||||
|
full path to the most recent Win11Debloat-StartBackup-*.bak file, or
|
||||||
|
$null if no backup exists.
|
||||||
|
|
||||||
|
For CurrentUser, uses $env:LOCALAPPDATA directly. For AllUsers, scans
|
||||||
|
every user profile.
|
||||||
|
|
||||||
|
.PARAMETER Scope
|
||||||
|
The scope to check: CurrentUser or AllUsers.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
$backupPath = Get-StartMenuBackupPath -Scope 'CurrentUser'
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
$backupPath = Get-StartMenuBackupPath -Scope 'AllUsers'
|
||||||
|
#>
|
||||||
|
function Get-StartMenuBackupPath {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[ValidateSet('CurrentUser', 'AllUsers')]
|
||||||
|
[string]$Scope
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($Scope -eq 'CurrentUser') {
|
||||||
|
$localStateDir = "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState"
|
||||||
|
$latestBackup = Get-ChildItem -Path (Join-Path $localStateDir 'Win11Debloat-StartBackup-*.bak') -ErrorAction SilentlyContinue |
|
||||||
|
Sort-Object Name -Descending |
|
||||||
|
Select-Object -First 1
|
||||||
|
if ($latestBackup) { return $latestBackup.FullName }
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$userPathString = GetUserDirectory -userName "*" -fileName "AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState"
|
||||||
|
$usersStartMenuPaths = Get-ChildItem -Path $userPathString -ErrorAction SilentlyContinue
|
||||||
|
foreach ($startMenuPath in $usersStartMenuPaths) {
|
||||||
|
$latestBackup = Get-ChildItem -Path (Join-Path $startMenuPath.FullName 'Win11Debloat-StartBackup-*.bak') -ErrorAction SilentlyContinue |
|
||||||
|
Sort-Object Name -Descending |
|
||||||
|
Select-Object -First 1
|
||||||
|
if ($latestBackup) { return $latestBackup.FullName }
|
||||||
|
}
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
@@ -204,14 +257,14 @@ function GetStartMenuUserNameFromPath {
|
|||||||
The full path to the user's start2.bin file to restore.
|
The full path to the user's start2.bin file to restore.
|
||||||
|
|
||||||
.PARAMETER BackupFilePath
|
.PARAMETER BackupFilePath
|
||||||
Path to the backup file to restore from. If omitted, defaults to
|
Path to the backup file to restore from. If omitted, automatically
|
||||||
StartMenuBinFile with a .bak extension.
|
finds the latest Win11Debloat-StartBackup-*.bak file.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
RestoreStartMenuFromBackup -StartMenuBinFile "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start2.bin"
|
RestoreStartMenuFromBackup -StartMenuBinFile "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start2.bin"
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
RestoreStartMenuFromBackup -StartMenuBinFile "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start2.bin" -BackupFilePath "C:\Backups\start2.bin"
|
RestoreStartMenuFromBackup -StartMenuBinFile "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start2.bin" -BackupFilePath "C:\Backups\Win11Debloat-StartBackup-20260101_120000.bak"
|
||||||
#>
|
#>
|
||||||
function RestoreStartMenuFromBackup {
|
function RestoreStartMenuFromBackup {
|
||||||
param(
|
param(
|
||||||
@@ -222,12 +275,28 @@ function RestoreStartMenuFromBackup {
|
|||||||
|
|
||||||
$userName = GetStartMenuUserNameFromPath -StartMenuBinFile $StartMenuBinFile
|
$userName = GetStartMenuUserNameFromPath -StartMenuBinFile $StartMenuBinFile
|
||||||
$backupBinFile = if ([string]::IsNullOrWhiteSpace($BackupFilePath)) {
|
$backupBinFile = if ([string]::IsNullOrWhiteSpace($BackupFilePath)) {
|
||||||
$StartMenuBinFile + '.bak'
|
# Auto-detect latest backup in the same folder as the start2.bin
|
||||||
|
$startMenuDir = Split-Path $StartMenuBinFile -Parent
|
||||||
|
$latestBackup = Get-ChildItem -Path (Join-Path $startMenuDir 'Win11Debloat-StartBackup-*.bak') -ErrorAction SilentlyContinue |
|
||||||
|
Sort-Object Name -Descending |
|
||||||
|
Select-Object -First 1
|
||||||
|
|
||||||
|
if ($latestBackup) { $latestBackup.FullName } else { $null }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$BackupFilePath
|
$BackupFilePath
|
||||||
}
|
}
|
||||||
$currentBinBackup = $StartMenuBinFile + '.restore.bak'
|
$restoreTimestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
|
||||||
|
$restoreBackupFileName = "Win11Debloat-StartRestore-$restoreTimestamp.bak"
|
||||||
|
$currentBinBackup = Join-Path (Split-Path $StartMenuBinFile -Parent) $restoreBackupFileName
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($backupBinFile)) {
|
||||||
|
return [PSCustomObject]@{
|
||||||
|
UserName = $userName
|
||||||
|
Result = $false
|
||||||
|
Message = "No start menu backup file found for user $userName."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($script:Params.ContainsKey("WhatIf")) {
|
if ($script:Params.ContainsKey("WhatIf")) {
|
||||||
Write-Host "[WhatIf] Restore start menu for user $userName from backup $backupBinFile" -ForegroundColor Cyan
|
Write-Host "[WhatIf] Restore start menu for user $userName from backup $backupBinFile" -ForegroundColor Cyan
|
||||||
@@ -272,37 +341,26 @@ function RestoreStartMenuFromBackup {
|
|||||||
Restores the start menu for the current target user from a backup.
|
Restores the start menu for the current target user from a backup.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Resolves the start2.bin path for the current user (or the user specified
|
Resolves the start2.bin path for the currently logged-in user, then
|
||||||
via the -User parameter), then delegates to RestoreStartMenuFromBackup.
|
delegates to RestoreStartMenuFromBackup.
|
||||||
Returns early with a warning if the user's start menu path cannot
|
|
||||||
be resolved.
|
|
||||||
|
|
||||||
.PARAMETER BackupFilePath
|
.PARAMETER BackupFilePath
|
||||||
Path to the backup file to restore from. If omitted, defaults to
|
Path to the backup file to restore from. If omitted, automatically
|
||||||
the .bak file alongside the current start2.bin.
|
finds the latest Win11Debloat-StartBackup-*.bak file.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
RestoreStartMenu
|
RestoreStartMenu
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
RestoreStartMenu -BackupFilePath "C:\Backups\start2.bin"
|
RestoreStartMenu -BackupFilePath "C:\Backups\Win11Debloat-StartBackup-20260101_120000.bak"
|
||||||
#>
|
#>
|
||||||
function RestoreStartMenu {
|
function RestoreStartMenu {
|
||||||
param(
|
param(
|
||||||
[string]$BackupFilePath
|
[string]$BackupFilePath
|
||||||
)
|
)
|
||||||
|
|
||||||
$targetUserName = GetUserName
|
$targetUserName = $env:USERNAME
|
||||||
$startMenuBinFile = GetStartMenuBinPathForUser -UserName $targetUserName
|
$startMenuBinFile = "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start2.bin"
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($startMenuBinFile)) {
|
|
||||||
Write-Host "Unable to resolve start menu path for user $targetUserName, nothing to restore" -ForegroundColor Yellow
|
|
||||||
return [PSCustomObject]@{
|
|
||||||
UserName = $targetUserName
|
|
||||||
Result = $false
|
|
||||||
Message = "Could not resolve start menu path for user $targetUserName."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Restoring start menu for user $targetUserName from backup..."
|
Write-Host "Restoring start menu for user $targetUserName from backup..."
|
||||||
|
|
||||||
@@ -315,19 +373,21 @@ function RestoreStartMenu {
|
|||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Iterates over every existing user profile and restores each user's
|
Iterates over every existing user profile and restores each user's
|
||||||
start2.bin from its .bak backup. For the Default user profile, removes
|
start2.bin from the latest backup in their LocalState folder. For the
|
||||||
the start2.bin file (which was previously copied from a template) so
|
Default user profile, removes the start2.bin file (which was previously
|
||||||
that new profiles revert to the system default start menu.
|
copied from a template) so that new profiles revert to the system
|
||||||
|
default start menu.
|
||||||
|
|
||||||
.PARAMETER BackupFilePath
|
.PARAMETER BackupFilePath
|
||||||
Path to the backup file to restore from. If omitted, defaults to
|
Path to the backup file to restore from. If omitted, automatically
|
||||||
the .bak file alongside each user's current start2.bin.
|
finds the latest Win11Debloat-StartBackup-*.bak in each user's
|
||||||
|
LocalState folder.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
RestoreStartMenuForAllUsers
|
RestoreStartMenuForAllUsers
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
RestoreStartMenuForAllUsers -BackupFilePath "C:\Backups\start2.bin"
|
RestoreStartMenuForAllUsers -BackupFilePath "C:\Backups\Win11Debloat-StartBackup-20260101_120000.bak"
|
||||||
#>
|
#>
|
||||||
function RestoreStartMenuForAllUsers {
|
function RestoreStartMenuForAllUsers {
|
||||||
param(
|
param(
|
||||||
|
|||||||
@@ -196,6 +196,10 @@ function Show-RestoreBackupDialog {
|
|||||||
$primaryActionBtn.Visibility = 'Visible'
|
$primaryActionBtn.Visibility = 'Visible'
|
||||||
$primaryActionBtn.IsDefault = $true
|
$primaryActionBtn.IsDefault = $true
|
||||||
$chooseRegistryBtn.IsDefault = $false
|
$chooseRegistryBtn.IsDefault = $false
|
||||||
|
|
||||||
|
# Show intro panel so user can configure scope & auto-detect
|
||||||
|
$startMenuAutoBackupCheck.IsChecked = $true
|
||||||
|
$state.SelectedStartMenuBackupFilePath = $null
|
||||||
& $refreshStartMenuUi
|
& $refreshStartMenuUi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,27 +327,14 @@ function Show-RestoreBackupDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (-not $useManualBackupFile) {
|
if (-not $useManualBackupFile) {
|
||||||
$autoBackupExists = $false
|
$scopeInfo = & $getStartMenuScopeInfo
|
||||||
if ($scope -eq 'AllUsers') {
|
$autoBackupPath = Get-StartMenuBackupPath -Scope $scopeInfo.Scope
|
||||||
$userPathString = GetUserDirectory -userName "*" -fileName "AppData\Local\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState"
|
if ($null -eq $autoBackupPath) {
|
||||||
$usersStartMenuPaths = Get-ChildItem -Path $userPathString -ErrorAction SilentlyContinue
|
$scopeText = $scopeInfo.SummaryText
|
||||||
foreach ($startMenuPath in $usersStartMenuPaths) {
|
Show-MessageBox -Owner $window -Title 'No Backup Found' -Message "No Start Menu backup file was found for $scopeText. Uncheck 'Automatically find Start Menu backup' to select a backup file manually." -Button 'OK' -Icon 'Warning' | Out-Null
|
||||||
if (Test-Path -LiteralPath (Join-Path $startMenuPath.FullName 'start2.bin.bak')) {
|
|
||||||
$autoBackupExists = $true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$autoBackupPath = "$env:LOCALAPPDATA\Packages\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\LocalState\start2.bin.bak"
|
|
||||||
$autoBackupExists = Test-Path -LiteralPath $autoBackupPath
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not $autoBackupExists) {
|
|
||||||
$scopeText = (& $getStartMenuScopeInfo).SummaryText
|
|
||||||
Show-MessageBox -Owner $window -Title 'No Backup Found' -Message "No Start Menu backup file was found. You can uncheck the 'Automatically find Start Menu backup' option to select a backup file manually." -Button 'OK' -Icon 'Warning' | Out-Null
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
$state.SelectedStartMenuBackupFilePath = if ($scopeInfo.Scope -eq 'CurrentUser') { $autoBackupPath } else { $null }
|
||||||
}
|
}
|
||||||
|
|
||||||
$window.Tag = @{
|
$window.Tag = @{
|
||||||
@@ -377,6 +368,7 @@ function Show-RestoreBackupDialog {
|
|||||||
})
|
})
|
||||||
|
|
||||||
$startMenuScopeCombo.Add_SelectionChanged({
|
$startMenuScopeCombo.Add_SelectionChanged({
|
||||||
|
$state.SelectedStartMenuBackupFilePath = $null
|
||||||
& $refreshStartMenuUi
|
& $refreshStartMenuUi
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user