Public/Backup-Path.ps1
|
function Backup-Path { <# .SYNOPSIS Creates a backup of the current PATH environment variable. .DESCRIPTION Saves the current PATH to a timestamped JSON file in the backup directory. .PARAMETER Target Which PATH to backup: User, Machine, or Both. Default is Both. .EXAMPLE Backup-Path .EXAMPLE Backup-Path -Target Machine #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [ValidateSet('User', 'Machine', 'Both')] [string]$Target = 'Both' ) $timestamp = Get-Date -Format 'yyyy-MM-dd_HH-mm-ss' $backupFile = Join-Path $script:BackupPath "path-backup_$timestamp.json" $backup = @{ Timestamp = (Get-Date).ToString('o') Target = $Target Hostname = $env:COMPUTERNAME Username = $env:USERNAME Paths = @{} } if ($Target -eq 'User' -or $Target -eq 'Both') { $backup.Paths.User = [Environment]::GetEnvironmentVariable('PATH', 'User') } if ($Target -eq 'Machine' -or $Target -eq 'Both') { $backup.Paths.Machine = [Environment]::GetEnvironmentVariable('PATH', 'Machine') } $backup | ConvertTo-Json -Depth 10 | Out-File -FilePath $backupFile -Encoding UTF8 Write-Verbose "Backup created: $backupFile" return [PSCustomObject]@{ BackupFile = $backupFile Timestamp = $backup.Timestamp Target = $Target } } function Restore-Path { <# .SYNOPSIS Restores PATH from a backup file. .DESCRIPTION Reads a backup JSON file and restores the PATH environment variable. .PARAMETER BackupFile Path to the backup file to restore from. .PARAMETER Target Which PATH to restore: User, Machine, or Both. Default is Both. .PARAMETER Force Skips confirmation prompt. .EXAMPLE Restore-Path -BackupFile "C:\Users\user\.config\winpath-clean\backups\path-backup_2024-01-01.json" .EXAMPLE Get-ChildItem ~/.config/winpath-clean/backups | Select-Object -First 1 | Restore-Path #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('FullName')] [string]$BackupFile, [ValidateSet('User', 'Machine', 'Both')] [string]$Target = 'Both', [switch]$Force ) process { if (-not (Test-Path $BackupFile)) { Write-Error "Backup file not found: $BackupFile" return } $backup = Get-Content $BackupFile | ConvertFrom-Json Write-Host Write-Host " Restore PATH from Backup" -ForegroundColor Cyan Write-Host " ════════════════════════════════════" -ForegroundColor DarkGray Write-Host " Backup file: $BackupFile" -ForegroundColor White Write-Host " Created: $($backup.Timestamp)" -ForegroundColor White Write-Host " Computer: $($backup.Hostname)" -ForegroundColor White Write-Host if (-not $Force) { $confirm = Read-Host " Restore this backup? (Y/N)" if ($confirm -ne 'Y' -and $confirm -ne 'y') { Write-Host " Restore cancelled." -ForegroundColor Gray return } } # Create a backup of current state before restoring $preRestoreBackup = Backup-Path -Target $Target Write-Host " Pre-restore backup created: $($preRestoreBackup.BackupFile)" -ForegroundColor DarkGray try { if (($Target -eq 'User' -or $Target -eq 'Both') -and $backup.Paths.User) { [Environment]::SetEnvironmentVariable('PATH', $backup.Paths.User, 'User') Write-Host " ✓ User PATH restored" -ForegroundColor Green } if (($Target -eq 'Machine' -or $Target -eq 'Both') -and $backup.Paths.Machine) { $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Warning "Administrator privileges required to restore Machine PATH. Skipping." } else { [Environment]::SetEnvironmentVariable('PATH', $backup.Paths.Machine, 'Machine') Write-Host " ✓ Machine PATH restored" -ForegroundColor Green } } Write-Host Write-Host " PATH restored successfully!" -ForegroundColor Green return [PSCustomObject]@{ Success = $true RestoredFrom = $BackupFile PreRestoreBackup = $preRestoreBackup.BackupFile } } catch { Write-Error "Failed to restore PATH: $_" return [PSCustomObject]@{ Success = $false Error = $_.Exception.Message } } } } function Get-PathBackups { <# .SYNOPSIS Lists all available PATH backups. .EXAMPLE Get-PathBackups #> [CmdletBinding()] [OutputType([PSCustomObject[]])] param() $backups = Get-ChildItem -Path $script:BackupPath -Filter '*.json' -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | ForEach-Object { $content = Get-Content $_.FullName | ConvertFrom-Json [PSCustomObject]@{ FileName = $_.Name FullName = $_.FullName Created = $content.Timestamp Target = $content.Target Computer = $content.Hostname } } return $backups } |