Tìm kiếm trang web

Sao lưu cài đặt thiết bị đầu cuối Windows bằng PowerShell


Tôi đã là một fan hâm mộ lớn của Windows Terminal ngay từ đầu. Trên thực tế, tôi đã sử dụng nó quá lâu nên tôi đã chuyển sang các cài đặt cấu hình đã thay đổi từ lâu. Tôi không buồn cập nhật cài đặt của mình. Một phần của thách thức là ứng dụng sẽ cập nhật ở chế độ nền và tôi không nhận ra điều đó. Điều đó có nghĩa là tôi không bao giờ xem ghi chú phát hành để xem điều gì đã thay đổi. Bản phát hành hiện tại 0.11.1120 đã thực hiện một số thay đổi đáng chú ý mà tôi hiện đã sắp xếp và tệp cài đặt của tôi đã được cập nhật cũng như nơi tôi cần. Bây giờ, tôi cần phải sao lưu tốt vì tôi luôn mày mò nó. Điều đó có nghĩa là sao lưu. Và vì tôi làm mọi thứ trong PowerShell nên điều đó có nghĩa là có một tập lệnh.

Trước khi bắt đầu viết kịch bản, hãy để tôi đề cập đến một điều mà tôi đang làm khác đi. Vị trí mặc định cho tệp cài đặt nằm trong thư mục AppData của bạn.

$ENV:Userprofile\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json

Đây là nơi ứng dụng đang tìm kiếm. Nhưng tôi muốn đảm bảo rằng tệp đó đã được sao lưu VÀ tôi muốn sử dụng nó trên nhiều hệ thống. Vì vậy, tôi đã tạo một liên kết cứng tới tệp này trỏ đến một bản sao trong thư mục OneDrive của tôi. Bạn có thể tạo một liên kết tượng trưng nhưng nó sẽ không hoạt động theo cách bạn muốn.

Việc tạo liên kết cứng tới tệp ở một vị trí khác rất có thể không phải là cấu hình được hỗ trợ cho Windows Terminal và không có gì đảm bảo rằng nó sẽ hoạt động với các phiên bản trong tương lai. Nhưng tôi sẵn sàng chấp nhận rủi ro.

Nếu bạn tò mò thì đây là đoạn mã PowerShell mà bạn có thể sử dụng (bạn phải tự chịu rủi ro).

$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

Tập lệnh sao lưu của tôi sẽ sử dụng vị trí mới nhưng nó cũng sẽ hoạt động với tệp gốc. Bạn sẽ cần phải chỉnh sửa tập lệnh để đáp ứng tình huống của mình. Ý tưởng đằng sau tập lệnh là tạo bản sao lưu được đánh số của tệp settings.json như settings.bak1.json. Tập lệnh có một tham số mà bạn có thể sử dụng để giới hạn số lượng tệp sao lưu. Tôi đang sử dụng giá trị mặc định là 7. Tham số khác là thư mục đích cho các tệp sao lưu. Tôi đang sử dụng cùng một thư mục 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

Tôi nghĩ kịch bản đã được ghi lại đầy đủ để bạn có thể hiểu nó đang làm gì.

Trong phiên bản cũ hơn, tôi nhận ra rằng việc đánh số sẽ tăng lên mặc dù tôi đã xóa các thư mục cũ hơn. Tôi quyết định rằng điều tôi thực sự muốn là không có quá 7 tệp, settings.bak1.json đến settings.bak7.json, với 1 tệp đại diện cho bản sao lưu cũ nhất. Điều này có nghĩa là tôi phải đổi tên các tập tin sao lưu. Phần khó khăn là tôi đã đổi tên bằng tên tệp đã tồn tại. Giải pháp đơn giản nhất là sao chép phiên bản được đánh số vào thư mục tạm thời, xóa tệp rồi sao chép tệp tạm thời trở lại thư mục đích của tôi.

Tập lệnh cũng hỗ trợ -WhatIf và có đầu ra Verbose. Nếu bạn có bất kỳ câu hỏi nào về những gì tôi đang làm hoặc tại sao, xin vui lòng gửi bình luận. Hãy tận hưởng và tiếp tục học hỏi!

Bài viết liên quan