Copia de seguridad de la configuración del terminal de Windows con PowerShell
He sido un gran admirador de Windows Terminal desde el principio. De hecho, lo he estado usando durante tanto tiempo que he ido avanzando en configuraciones de perfil que cambiaron hace mucho tiempo. No me molesté en actualizar mi configuración. Parte del desafío es que la aplicación se actualizará en segundo plano y no me doy cuenta. Lo que significa que nunca miro las notas de la versión para ver qué ha cambiado. La versión actual 0.11.1120 realizó algunos cambios importantes, que ahora he solucionado y mi archivo de configuración está actualizado y donde lo necesito. Ahora necesito mantener buenas copias de seguridad porque siempre estoy jugueteando con ellas. Eso significa respaldo. Y como hago todo en PowerShell, eso significa un script.
Antes de pasar al guión, permítanme mencionar una cosa que estoy haciendo de manera diferente. La ubicación predeterminada para el archivo de configuración está en su carpeta AppData.
$ENV:Userprofile\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json
Aquí es donde busca la aplicación. Pero quiero asegurarme de que se haga una copia de seguridad de ese archivo Y me gustaría usarlo en varios sistemas. Así que creé un vínculo físico a este archivo que apunta a una copia en mi carpeta OneDrive. Puedes crear un enlace simbólico pero no funcionará como deseas.
Lo más probable es que crear un vínculo físico a un archivo en una ubicación diferente no sea una configuración compatible con Windows Terminal y no hay garantía de que funcione con versiones futuras. Pero estoy dispuesto a aceptar el riesgo.
Si tiene curiosidad, aquí tiene un fragmento de PowerShell que puede utilizar (bajo su propia responsabilidad).
$params = @{
Path = "$ENV:Userprofile\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
ItemType = "HardLink"
Value = "C:\users\jeff\OneDrive\windowsterminal\settings.json"
}
Move-Item -Path $params.path -Destination $params.value
New-Item @params
Mi secuencia de comandos de respaldo utilizará la nueva ubicación pero también funcionará con el archivo original. Deberá editar el script para adaptarlo a su situación. La idea detrás del script es crear copias de seguridad numeradas del archivo settings.json como settings.bak1.json. El script tiene un parámetro que puede usar para limitar la cantidad de archivos de respaldo. Estoy usando un valor predeterminado de 7. El otro parámetro es la carpeta de destino de los archivos de respaldo. Estoy usando la misma carpeta de OneDrive.
#Backup-WTSettings.ps1
[CmdletBinding(SupportsShouldProcess)]
Param(
#how many backup copies should be saved
[int]$Limit = 7,
#backup folder
[parameter(HelpMessage = "Specify the backup location")]
[ValidateScript({Test-Path $_})]
[string]$Destination = "C:\users\jeff\OneDrive\windowsTerminal"
)
#Actual path to settings.json file - you will want to uncomment this line
#$json = $ENV:Userprofile\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json
#comment out or update to reflect the location of the settings.json file to backup.
$json = "C:\users\jeff\OneDrive\windowsterminal\settings.json"
Write-Verbose "Backing up $json to $Destination"
Write-Verbose "Get existing backups and save as an array sorted by name"
[array]$bak = Get-ChildItem -path $Destination -Name settings.bak*.json | Sort-Object -Property name
if ($bak.count -eq 0) {
Write-Verbose "Creating first backup copy."
[int]$new = 1
}
else {
#get the numeric value
[int]$counter = ([regex]"\d+").match($bak[-1]).value
Write-Verbose "Last backup is #$counter"
[int]$new = $counter + 1
Write-Verbose "Creating backup copy $new"
}
$backup = Join-Path -path $Destination -ChildPath "settings.bak$new.json"
Write-Verbose "Creating backup $backup"
Copy-Item -Path $json -Destination $backup
#update the list of backups sorted by age and delete extras
Write-Verbose "Removing any extra backup files over the limit of $Limit"
Get-ChildItem -path $Destination\settings.bak*.json |
Sort-Object -Property LastWriteTime -Descending |
Select-Object -Skip $Limit | Remove-Item
#renumber backup files
Write-Verbose "Renumbering backup files"
<#
You can't rename a file if it will conflict with an existing file so files will be copied
to a temp folder with a new name, the old file deleted and then the copy restored
#>
Get-ChildItem -path $Destination\settings.bak*.json |
Sort-Object -Property LastWriteTime |
ForEach-Object -Begin {$n = 0} -process {
#rename each file with a new number
$n++
$temp = Join-Path -path $env:TEMP -ChildPath "settings.bak$n.json"
Write-Verbose "Copying temp file to $temp"
$_ | Copy-Item -Destination $temp
Write-Verbose "Removing $($_.name)"
$_ | Remove-Item
} -end {
Write-Verbose "Restoring temp files to $Destination"
Get-ChildItem -Path "$env:TEMP\settings.bak*.json" | Move-Item -Destination $Destination
}
#show current backup files
Get-ChildItem -path $Destination\settings.bak*.json | Sort-Object -Property LastWriteTime -Descending
Creo que el guión está lo suficientemente documentado como para que puedas descubrir qué está haciendo.
En una versión anterior me di cuenta de que la numeración iba a aumentar aunque estuviera eliminando carpetas más antiguas. Decidí que lo que realmente quería era no tener más de 7 archivos, desde settings.bak1.json hasta settings.bak7.json, donde 1 representaba la copia de seguridad más antigua. Esto significó que tuve que cambiar el nombre de los archivos de respaldo. La parte complicada fue que había cambiado el nombre usando un nombre de archivo que ya existía. La solución más sencilla fue copiar la versión numerada a una carpeta temporal, eliminar el archivo y luego copiar los archivos temporales nuevamente a mi directorio de destino.
El script también admite -WhatIf y tiene salida detallada. Si tiene alguna pregunta sobre lo que estoy haciendo o por qué, no dude en publicar un comentario. ¡Disfruta y sigue aprendiendo!