Restic 备份工具使用指南(Windows Server 2019 适配版)
Restic 同样是 Windows 上可用的单二进制、客户端加密、全局去重快照备份工具。在 Windows Server 2019 中,最关键的差异有三点:通过任务计划程序实现无人值守、用 VSS 快照处理被锁定文件、用 NTFS ACL 严格控制密码文件权限。
一、安装(单二进制,推荐 winget 或手动放置)
方式 A:winget(推荐,便于后续升级)
以管理员身份打开 PowerShell:
winget install restic.restic安装后确认版本:
restic version方式 B:手动下载 .exe
从 restic releases 下载restic_*_windows_amd64.zip,解压后将restic.exe放入C:\Program Files\Restic\,并将该目录加入系统PATH。不要直接丢进System32,便于后续版本管理与审计。
方式 C:我共享的百度网盘地址下载
链接: https://pan.baidu.com/s/1_-lRGoG_VOMa_SQwRqnyLg?pwd=hpdy 提取码: hpdy
目录结构
C:\Program Files\Restic\ ├── logs\ # 存放每日备份、清理和校验的日志 ├── exclude.txt # 备份排除列表(如临时文件、缓存目录等) ├── init.log # 首次执行 restic init 时的输出日志 ├── restic.exe # Restic 主程序 ├── restic_backup_passwd.txt # Restic 仓库密码文件(需严格控制 NTFS ACL 权限) └── restic-backup.ps1 # 自动化备份与发信通知的主 PowerShell 脚本二、环境变量与密码文件(Windows 下务必用密码文件,不用明文环境变量)
Restic 在 Windows 上同样支持环境变量,但生产环境优先使用密码文件。PowerShell 中设置当前会话的临时环境变量可用于测试:
$env:RESTIC_REPOSITORY = "D:\Backup\restic-repo" $env:RESTIC_PASSWORD_FILE = "C:\ProgramData\Restic\password.txt"如果要持久化到系统级(不推荐用于密码),可用:
[Environment]::SetEnvironmentVariable("RESTIC_REPOSITORY", "D:\Backup\restic-repo", "Machine")密码文件权限(关键):Windows 没有chmod 600,必须用 NTFS ACL 限制为仅运行备份的身份可读。假设任务以SYSTEM运行,则只允许SYSTEM和Administrators读取:
$acl = Get-Acl "C:\ProgramData\Restic\password.txt" $acl.SetAccessRuleProtection($true, $false) # 禁用继承 $acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) } $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM","Read","Allow") $acl.AddAccessRule($rule) $rule2 = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators","Read","Allow") $acl.AddAccessRule($rule2) Set-Acl "C:\ProgramData\Restic\password.txt" $acl这样可避免普通用户或误操作进程读取密码。
仓库后端示例(Windows 路径写法):
# 本地目录 D:\Backup\restic-repo # SFTP sftp://user@192.168.1.100//backup/repo # S3 兼容(MinIO / 阿里云 OSS / 华为 OBS) s3:http://192.168.1.200:9000/restic-repo s3:oss-cn-beijing.aliyuncs.com/bucket-name/repoS3 场景还需额外设置凭证(建议同样用受限文件或仅在任务专用账户中设置):
$env:AWS_ACCESS_KEY_ID = "xxx" $env:AWS_SECRET_ACCESS_KEY = "xxx"三、初始化仓库(只执行一次)
# 初始化 restic 仓库到 D:\backup\repo restic init --repo "D:\backup\repo" --password-file "C:\ProgramData\Restic\password.txt" # 示例1 restic init --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt"输出created restic repository ...即成功。仓库密码一旦丢失,所有备份永久无法恢复,建议用restic key add添加备用密钥并存放在安全位置。
四、核心备份:backup(Windows Server 2019 必须加--use-fs-snapshot)
Linux 下可直接备份运行中的文件;Windows 上大量文件会被进程锁定(如数据库、IIS 日志、系统文件),不加 VSS 快照会遇到Access is denied或文件被跳过。Restic 在 Windows 上支持--use-fs-snapshot,通过卷影复制服务读取一致状态的文件。
基础备份命令(管理员 PowerShell):
restic backup C:\Data D:\AppData ` --use-fs-snapshot ` --repo "D:\jg_cpz\minio_backup" ` --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" ` --exclude-file "C:\ProgramData\Restic\exclude.txt" ` --compression better ` --tag server-data常用参数(Windows 等价):
--use-fs-snapshot # Windows 必加,处理锁定文件 --exclude C:\Data\tmp # 排除目录 --exclude-file exclude.txt # 批量排除,一行一个 Windows 路径 --compression better # auto|off|fastest|better|max --dry-run # 试运行,不写仓库 --host WS2019-DB01 # 手动指定主机名示例:SQL Server 热备(不落地文件)
如果服务器上运行 SQL Server,可以用sqlcmd输出流直接管道给 restic,避免生成巨大的.bak临时文件:
sqlcmd -S localhost -E -Q "BACKUP DATABASE [YourDB] TO DISK = 'NUL' WITH COPY_ONLY" | restic backup --stdin --tag mssql注意:TO DISK = 'NUL'不会产生真实文件,数据流直接进入 restic。需确保sqlcmd可用且执行账户有备份权限。
五、快照管理:snapshots / forget / prune
查看快照
restic snapshots restic snapshots --tag server-data restic snapshots --host WS2019-DB01 restic snapshots latest # 示例 restic snapshots --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" # 输出结果: D:\jg_cpz> restic snapshots --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" repository 2086c998 opened (version 2, compression level auto) ID Time Host Tags Paths Size -------------------------------------------------------------------------------------- 4d9d5fbb 2026-10-24 08:52:24 ecs-240e-0002 server-data D:\minio 1.218 GiB 5e8acd11 2026-10-24 09:00:32 ecs-240e-0002 server-data D:\jg_cpz\gdal 222.012 MiB -------------------------------------------------------------------------------------- Timestamps shown in local time 2 snapshots restic snapshots --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" latest # 输出结果: D:\jg_cpz> restic snapshots --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" latest repository 2086c998 opened (version 2, compression level auto) ID Time Host Tags Paths Size -------------------------------------------------------------------------------------- 5e8acd11 2026-10-24 09:00:32 ecs-240e-0002 server-data D:\jg_cpz\gdal 222.012 MiB -------------------------------------------------------------------------------------- Timestamps shown in local time 1 snapshots自动清理旧快照forget只打删除标记,prune才真正回收数据块。生产环境建议分两步执行,确认forget结果无误后再prune:
# forget 命令的作用是删除快照记录。注意,它不会立刻释放硬盘空间,它只是把备份的“目录”删了。 #--keep-daily 7:保留最近 7 天,每天的最后一个快照。 #--keep-weekly 4:保留最近 4 周,每周的最后一个快照。 #--keep-monthly 6:保留最近 6 个月,每个月的最后一个快照。 restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 restic prune删掉指定快照
删除指定的 restic 快照,核心命令是restic forget <快照ID>。这个操作分两步走:forget负责删除快照的“记录”,而prune负责真正释放被占用的磁盘空间。
🔍 第一步:找到要删除的快照 ID
首先,你需要列出所有快照,找到目标快照的 ID。
restic -r "D:\jg_cpz\minio_backup" snapshots # 示例: D:\tmp> restic --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" snapshots # 输出: repository 2086c998 opened (version 2, compression level auto) ID Time Host Tags Paths Size -------------------------------------------------------------------------------------- 4d9d5fbb 2026-10-24 08:52:24 ecs-240e-0002 server-data D:\minio 1.218 GiB 5e8acd11 2026-10-24 09:00:32 ecs-240e-0002 server-data D:\jg_cpz\gdal 222.012 MiB fe28025e 2026-10-24 12:00:58 ecs-240e-0002 mysqbackup D:\backup 62.101 GiB de371bec 2026-10-24 14:02:34 ecs-240e-0002 server-data D:\backup 63.536 GiB D:\jg_cpz\gdal D:\minio -------------------------------------------------------------------------------------- Timestamps shown in local time 4 snapshots # 示例: D:\tmp> restic -r "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" snapshots # 输出: repository 2086c998 opened (version 2, compression level auto) ID Time Host Tags Paths Size -------------------------------------------------------------------------------------- 4d9d5fbb 2026-10-24 08:52:24 ecs-240e-0002 server-data D:\minio 1.218 GiB 5e8acd11 2026-10-24 09:00:32 ecs-240e-0002 server-data D:\jg_cpz\gdal 222.012 MiB fe28025e 2026-10-24 12:00:58 ecs-240e-0002 mysqbackup D:\backup 62.101 GiB de371bec 2026-10-24 14:02:34 ecs-240e-0002 server-data D:\backup 63.536 GiB D:\jg_cpz\gdal D:\minio -------------------------------------------------------------------------------------- Timestamps shown in local time 4 snapshots执行后,你会看到一个列表,ID列就是快照的唯一标识(通常是8位短ID)。
🗑️ 第二步:执行删除
这里有两种方式,你可以任选其一:
方式一:分两步执行(更安全,便于确认)
仅删除快照记录:
forget命令只移除快照的引用,不立即释放空间。restic -r "D:\jg_cpz\minio_backup" forget <快照ID> # 示例: restic -r "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" forget 4d9d5fbb释放磁盘空间:接着运行
prune,它会扫描仓库,删除那些不再被任何快照引用的“孤儿”数据块。restic -r "D:\jg_cpz\minio_backup" prune # 示例: restic -r "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" prune
方式二:一步到位(推荐)
直接在forget命令后加上--prune参数,restic 会在删除快照后自动执行清理。
restic -r "D:\jg_cpz\minio_backup" forget <快照ID> --prune # 示例: restic -r "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" forget fe28025e --prune注意:prune会重打包仓库,不能与其他备份任务同时运行,否则会锁库报错。应安排在业务低峰期,且与
备份任务错开。
注意删除逻辑:如下两种情况
情况一:这个文件在其他保留的快照里也有(最常见)
结论:文件还在,可以恢复。
- 原理:假设你每天备份同一个文件
app.log。第一天快照A存了它,第二天快照B也存了它。restic 在底层只会存一份数据块,快照A和快照B都只是通过“指针”指向这份数据块。 - 操作:如果你用
forget删除了快照A,并执行了prune。restic 在清理时会发现:“虽然快照A没了,但快照B还在使用这份数据块”,于是它会保留这份数据。 - 结果:当你去恢复快照B时,这个文件完整无缺。
情况二:这个文件是“只属于”被删快照的(独有数据)
结论:一旦你执行了prune,文件就被彻底物理删除了,无法恢复。
- 原理:假设你在快照A里存了一个文件
only_in_A.txt,后来你把这个文件从源目录删了,后续的快照B、C里都没有它。当你对快照A执行forget并加上prune后,restic 扫描发现没有任何快照还在引用这份数据,于是就会从硬盘上彻底抹掉它。 - 结果:以后恢复快照B或C时,里面不会有这个文件;快照A的记录也已经没了。这份数据就“灰飞烟灭”了。
六、恢复:restore(最重要的功能)
恢复到目标目录
restic restore <快照ID> --target D:\Restore restic restore 4d9d5fbb --target D:\tmp --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt"只恢复单个目录或文件
restic restore <快照ID> --target D:\Restore --include "/D/minio/data" # 例如: # 注意 --include "/D/minio/data" 的路径不能是:"\D\minio\data" restic restore 4d9d5fbb --target D:\tmp --include "/D/minio/data" --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt"直接导出单个文件
restic dump <快照ID> "/D/minio/config/minio.env" > D:\test.txt # 示例: restic dump 4d9d5fbb --repo "D:\jg_cpz\minio_backup1" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" "/D/minio/config/minio.env"> D:\tmp\minio.env列出快照内文件
restic ls <快照ID> # 示例: # 用 restic ls 命令看一眼快照 4d9d5fbb 的目录结构,确认 data 文件夹到底是以什么路径存储的。 restic ls 4d9d5fbb --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" restic ls <快照ID> "/D/minio/config" # 示例: restic ls 4d9d5fbb --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" "/D/minio/config" # 输出: repository 2086c998 opened (version 2, compression level auto) [0:00] 100.00% 4 / 4 index files loaded snapshot 4d9d5fbb of [D:\minio] at 2026-10-24 08:52:24.1702605 +0800 CST by ECS-240E-0002\Administrator@ecs-240e-0002 filtered by [/D/minio/config]: /D/minio/config /D/minio/config/minio.env全仓库搜索文件名
restic find "filename.txt" <快照ID> # 示例: restic find "minio.env" 4d9d5fbb --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" # 输出: repository 2086c998 opened (version 2, compression level auto) [0:00] 100.00% 4 / 4 index files loaded Found matching entries in snapshot de371bec from 2026-10-24 14:02:34 /D/minio/config/minio.env Found matching entries in snapshot 4d9d5fbb from 2026-10-24 08:52:24 /D/minio/config/minio.env⚠️Windows 恢复的重要限制:Restic 在 Windows 上对文件ACL 和所有者的备份/恢复能力有限,部分版本虽已改进 SecurityDescriptor 支持,但仍需Backup Operators组成员或相应特权。如果恢复后出现权限异常,可能需要手动修正。
七、仓库校验(防静默损坏,运维必做)
磁盘静默损坏和 bit rot 无法肉眼发现,必须定期check:
restic check # 示例: restic check --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" # 输出: using temporary cache in C:\Users\ADMINI~1\AppData\Local\Temp\1\restic-check-cache-2435865498 create exclusive lock for repository repository 2086c998 opened (version 2, compression level auto) created new cache in C:\Users\ADMINI~1\AppData\Local\Temp\1\restic-check-cache-2435865498 load indexes [0:00] 100.00% 4 / 4 index files loaded check all packs check snapshots, trees and blobs [0:00] 100.00% 4 / 4 snapshots no errors were found更严格的完整数据校验(较慢):
restic check --read-data # 示例: restic check --read-data --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" # 输出: using temporary cache in C:\Users\ADMINI~1\AppData\Local\Temp\1\restic-check-cache-1059252936 create exclusive lock for repository repository 2086c998 opened (version 2, compression level auto) created new cache in C:\Users\ADMINI~1\AppData\Local\Temp\1\restic-check-cache-1059252936 load indexes [0:00] 100.00% 4 / 4 index files loaded check all packs check snapshots, trees and blobs [0:00] 100.00% 4 / 4 snapshots read all data [0:40] 100.00% 120 / 120 packs no errors were found折中方案(随机抽样):
restic check --read-data-subset 10% # 示例: restic check --read-data-subset 10% --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" # 输出: using temporary cache in C:\Users\ADMINI~1\AppData\Local\Temp\1\restic-check-cache-2999965827 create exclusive lock for repository repository 2086c998 opened (version 2, compression level auto) created new cache in C:\Users\ADMINI~1\AppData\Local\Temp\1\restic-check-cache-2999965827 load indexes [0:00] 100.00% 4 / 4 index files loaded check all packs check snapshots, trees and blobs [0:00] 100.00% 4 / 4 snapshots read 10.0% of packfiles [0:04] 100.00% 12 / 12 packs no errors were found最佳实践:每周跑一次check,失败触发告警。若备份中途中断导致repository locked:
restic unlock # 示例: restic unlock --repo "D:\jg_cpz\minio_backup" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt" # 输出: repository 2086c998 opened (version 2, compression level auto)八、跨仓库复制快照:copy(异地灾备 3-2-1)
将本地仓库快照同步到异地 OSS 或另一台服务器:
restic copy --repo D:\Backup\restic-repo ` --repo2 s3:http://192.168.1.200:9000/restic-repo ` <快照ID> # 示例: restic copy --repo "D:\jg_cpz\minio_backup" ` --repo2 s3:http://192.168.1.200:9000/restic-repo ` 5e8acd11 ` --password-file "C:\Program Files\Restic\restic_backup_passwd.txt"注意:在运行 restic copy 命令之前,先在同一个 PowerShell 窗口里执行以下命令设置环境变量。这些变量只在当前窗口有效,关闭后即失效。
使用repo2 之前需要初始化:
$env:AWS_ACCESS_KEY_ID = "你的AccessKey" $env:AWS_SECRET_ACCESS_KEY = "你的SecretKey" $env:AWS_DEFAULT_REGION = "us-east-1" # MinIO 通常需要,可任意指定,但必须存在 # 使用前需要初始化 restic init --repo "s3:http://192.168.1.200:9000/restic-repo" --password-file "C:\Program Files\Restic\restic_backup_passwd.txt"复制全部快照时省略<快照ID>。copy利用全局去重,只传输目标仓库缺失的数据块,不会重复上传相同内容。
九、自动化脚本 + 任务计划程序
Windows Server 2019 使用任务计划程序实现开机自启和定时备份,并且状态邮件通知。
脚本的核心逻辑是:每次运行先检测仓库是否已初始化,未初始化则执行restic init;随后执行备份,并根据最终状态发送邮件。
# C:\Program Files\Restic\restic-backup.ps1(管理员/SYSTEM 权限运行) $ErrorActionPreference = "Stop" # ========== 1. 基础配置 ========== # ========== 性能参数 ========== $env:RESTIC_PACK_SIZE = "128" # 本地仓库建议 64~128 $env:RESTIC_REPOSITORY = "D:\jg_backup" $env:RESTIC_PASSWORD_FILE = "C:\Program Files\Restic\restic_backup_passwd.txt" $env:EXCLUDE_FILE = "C:\Program Files\Restic\exclude.txt" $backupPaths = @("D:\jg_cpz","D:\minio") $RepoConfigFile = "D:\jg_backup\config" # restic 仓库的标志性文件 $MailParams = @{ SmtpServer = "smtp.qq.com" Port = 587 From = "610152753@qq.com" To = "qiaoshunlong@163.com" UseSsl = $true Credential = New-Object System.Management.Automation.PSCredential( "610152753@qq.com", (ConvertTo-SecureString "你的16位QQ邮箱授权码" -AsPlainText -Force) ) } # 引入 Mailozaurr Import-Module Mailozaurr -ErrorAction Stop # ========== 2. 辅助函数:发送邮件 ========== function Send-BackupMail { param([string]$Subject, [string]$Body, [string]$Priority = "Normal") $mail = @{ From = $MailParams.From To = $MailParams.To Subject = $Subject Body = $Body Priority = $Priority SmtpServer = $MailParams.SmtpServer Port = $MailParams.Port UseSsl = $MailParams.UseSsl Credential = $MailParams.Credential } try { Send-EmailMessage @mail -ErrorAction Stop } catch { # 邮件失败时写入本地日志,避免因邮件问题中断备份 "邮件通知失败:$($_.Exception.Message)" | Out-File "C:\Program Files\Restic\mail-failure.log" -Append } } # ========== 3. 仅首次运行:初始化仓库 ========== if (-not (Test-Path $RepoConfigFile)) { try { restic init --repo $env:RESTIC_REPOSITORY --password-file $env:RESTIC_PASSWORD_FILE 2>&1 | Out-File "C:\Program Files\Restic\init.log" -Append if ($LASTEXITCODE -eq 0) { Send-BackupMail -Subject "[Restic] 仓库初始化成功 $(hostname)" ` -Body "仓库 $($env:RESTIC_REPOSITORY) 已初始化完成。`n时间:$(Get-Date)" } else { Send-BackupMail -Subject "[CRIT] [Restic] 仓库初始化失败 $(hostname)" ` -Body "restic init 退出码 $LASTEXITCODE,请检查 init.log。" -Priority High exit 1 # 初始化失败则不继续备份 } } catch { Send-BackupMail -Subject "[CRIT] [Restic] 仓库初始化异常 $(hostname)" ` -Body $_.Exception.Message -Priority High exit 1 } } # 初始化成功后,继续执行备份 # ========== 4. 执行备份 ========== $ErrorActionPreference = "Continue" # Restic 在备份前会并发统计文件数量和总大小,用于估算进度,这个扫描阶段在文件多时会产生大量额外 I/O,拖慢整体速度。加上 --no-scan 可以跳过这一阶段 $LogFile = "C:\Program Files\Restic\logs\backup-$(Get-Date -Format 'yyyyMMdd-HHmm').log" restic backup $backupPaths ` --use-fs-snapshot ` --no-scan ` -o vss.provider=MS ` --repo $env:RESTIC_REPOSITORY ` --password-file $env:RESTIC_PASSWORD_FILE ` --exclude-file $env:EXCLUDE_FILE ` --compression better ` --tag server-data *>> $LogFile $ret = $LASTEXITCODE # ========== 5. 根据备份状态发送通知 ========== # ========== 构造带日志的邮件正文 ========== function Get-LogTail { param([string]$Path, [int]$Lines = 80) if (-not (Test-Path $Path)) { return "(日志文件不存在)" } $content = Get-Content -Path $Path -Tail $Lines -ErrorAction SilentlyContinue if (-not $content) { return "(日志为空)" } return ($content -join "`r`n") } # 清理旧快照(分两步,确认后再 prune) restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 *>> $LogFile restic prune *>> $LogFile restic check *>> $LogFile $logTail = Get-LogTail -Path $LogFile -Lines 80 if ($ret -eq 0) { $subject = "[OK] [Restic] 备份成功 $(hostname)" $body = "备份完成。`n日志文件:$LogFile`n`n===== 末尾日志 =====`n$logTail" Send-BackupMail -Subject $subject -Body $body } elseif ($ret -eq 3) { $subject = "[WARN] [Restic] 备份部分文件失败 $(hostname)" $body = "退出码 3,快照已生成但部分文件被跳过。`n日志文件:$LogFile`n`n===== 末尾日志 =====`n$logTail" Send-BackupMail -Subject $subject -Body $body -Priority High } else { $subject = "[CRIT] [Restic] 备份失败 $(hostname)" $body = "退出码 $ret。`n日志文件:$LogFile`n`n===== 末尾日志 =====`n$logTail" Send-BackupMail -Subject $subject -Body $body -Priority High exit $ret }关键设计说明
① 初始化的幂等判断Test-Path $RepoConfigFile检查仓库根目录下是否存在config文件。restic init成功后会生成该文件,因此这个判断比直接反复执行restic init更安全——后者在仓库已存在时会报错并退出。只有config不存在时才走初始化分支,满足“仅第一次运行”的要求。
② 初始化失败即终止
初始化失败后直接exit 1,不再继续备份。因为仓库不可用时备份必然失败,继续执行只会产生无意义的错误日志。
③ 邮件通知的时机
脚本在三个关键节点发送邮件:初始化成功 / 失败、备份成功 / 部分失败 / 完全失败。邮件发送本身用try/catch包裹,即使 SMTP 服务器临时不可达,也不会中断备份流程,而是降级写入本地日志。
④ 优先级区分
备份成功用Normal,警告和致命错误用High,便于邮件客户端或后续告警规则做差异化处理。
创建任务计划程序任务(管理员 PowerShell)
Restic 在 Windows 上要完整利用 VSS 快照,任务身份需要具备“作为服务登录”和备份特权。最省事的做法是以SYSTEM运行,并勾选“使用最高权限运行”。
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" ` -Argument "-NoProfile -ExecutionPolicy Bypass -File `"C:\Program Files\Restic\restic-backup.ps1`"" $trigger = New-ScheduledTaskTrigger -Daily -At "23:00PM" $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest Register-ScheduledTask -TaskName "Restic Backup" -Action $action -Trigger $trigger -Principal $principal也可在 GUI 的任务计划程序中创建任务,触发器选“每天”,操作指向 PowerShell 脚本,勾选“使用最高权限运行”,并在“常规”中选择“不管用户是否登录都要运行”。
部署提醒
- Mailozaurr 安装:在以
SYSTEM运行的任务计划中,模块需要安装在系统级路径,建议提前在管理员 PowerShell 中执行Install-Module Mailozaurr -Scope AllUsers -Force。 - 凭据安全:示例中密码是明文,生产环境建议改用Windows 凭据管理器或加密的 CLIXML 文件读取 SMTP 密码,避免脚本泄露。
- 初始化日志:
init.log和备份日志分开存放,便于故障时快速区分是仓库创建问题还是备份执行问题。