装配:Get-BakNRetCatalogField → 菜单选字段 → Read-BakNRetLine → Set-BakNRetCatalogField → Save-BakNRetConfigFile(校验通过才原子替换 + 时间戳备份)。 菜单里**只列可编辑的字段**(单行的 Encrypt / Description):把只读的 Path / Exclude 也列出来再拒绝,会让每个只读项浪费用户一次回车。 校验用模块自己的 Import-BaknretDataFile:这份名录有 $( ) 动态表达式与跨行拼接,普通数据文件读取器读不了 —— 而正是它保证"改完整份文件还能被程序读回来"(值能读回来才算改成功)。定位用 (软件名, Slot, 字段名) 三元组,因为同一软件可以有多个 Slot。 Edit-Config 的三个界面(清单 / 设置 / 名录)至此全部完成。 判据 9 条:改一个值后只动一行、注释行数不变、改完能读回新值、留下时间戳备份且备份里是原文;取消时不写盘也不产生备份。 验收:test.ps1 9/9 全绿(5.1 与 7);真实清单只读冒烟 4/4。
275 lines
11 KiB
PowerShell
275 lines
11 KiB
PowerShell
<#
|
||
.SYNOPSIS
|
||
BakNRet —— 备份 / 恢复脚本的公共功能模块。
|
||
|
||
.DESCRIPTION
|
||
提供日志(控制台 + 落盘)、外部命令调用(可取得真实退出码)、
|
||
BackupList.txt 语法解析、归档命名与逆向解析、目录摘要、manifest 读写、
|
||
磁盘剩余空间查询等公共能力。
|
||
|
||
兼容 Windows PowerShell 5.1 与 PowerShell 7.x:
|
||
* 不使用 ?? / 三元运算符 / Join-String / -AsHashtable 等 6.0+ 语法;
|
||
* 不使用 ProcessStartInfo.ArgumentList(5.1 上不存在),改为自行构造命令行。
|
||
|
||
模块内出现的备份清单语法(BackupList.txt 每一行):
|
||
|
||
[+|-] <软件名 或 绝对路径> [修饰符...] [# 说明]
|
||
[:: <Absolute\Path>] [:- <模式>[,...]] [:+ <包含项>[,...]]
|
||
[:encrypt | :!encrypt] [@ <Key>='<Value>']
|
||
|
||
标记(必须是独立的空白分隔记号,前后都要有空格):
|
||
+ 仅备份,不恢复(Restore.ps1 跳过)
|
||
- 仅恢复,不备份(Backup.ps1 跳过)
|
||
:: 覆盖 Path,等价于 `@ Path='...'`
|
||
:- 排除模式,等价于 `@ Exclude='...'`
|
||
:+ 追加包含项(<归档内相对路径>:<宿主机绝对路径>),等价于 `@ Include='...'`
|
||
:encrypt 该条目加密(`@ Encrypt='$true'`)
|
||
:!encrypt 该条目不加密(`@ Encrypt='$false'`)
|
||
@ Key='值' 覆盖 SoftwareCatalog.psd1 里的同名默认字段
|
||
|
||
兼容的历史写法:`@encrypt` / `@!encrypt` / `@pathname` / `@root=<名>`,
|
||
以及用双引号包住路径或模式值。
|
||
|
||
归档内布局(SoftwareCatalog.psd1 的 Slot 是包内的一层目录):
|
||
软件名条目 -> <Slot>\<该 Path 的内容>(Path 是文件时就是名为 <Slot> 的文件)
|
||
手写路径 -> <路径末级名>\...(历史布局,不变)
|
||
#>
|
||
|
||
|
||
# ----------------------------------------------------------------------------
|
||
# 加载器:下面这份点源顺序是**唯一**一份顺序声明。
|
||
#
|
||
# 每个函数一个文件,文件名 = 函数名;要合回单个 .psm1(发布形态,或做代码签名时需要),
|
||
# 跑 tools\Build-BakNRetModule.ps1 —— 它从本文件里读出顺序,所以顺序不需要维护两遍。
|
||
# ----------------------------------------------------------------------------
|
||
|
||
. (Join-Path $PSScriptRoot 'Private\State.ps1')
|
||
|
||
# ---- 日志 ----
|
||
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetDebug.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Start-BakNRetLog.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Stop-BakNRetLog.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetLogPath.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetLog.ps1')
|
||
|
||
# ---- 运行锁 ----
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetRunLockPath.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Enter-BakNRetRunLock.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Exit-BakNRetRunLock.ps1')
|
||
|
||
# ---- 环境 ----
|
||
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetAdministrator.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetFreeSpaceGB.ps1')
|
||
|
||
# ---- 外部命令 ----
|
||
. (Join-Path $PSScriptRoot 'Public\ConvertTo-BakNRetNativeArgumentString.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Invoke-ExternalCommand.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetCompressionTool.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-Optimized7zArgument.ps1')
|
||
|
||
# ---- BackupList.txt 解析 ----
|
||
. (Join-Path $PSScriptRoot 'Public\Split-BakNRetToken.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Remove-BakNRetQuote.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetMarker.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\ConvertFrom-BakNRetPatternList.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\ConvertFrom-BackupListLine.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetLiteralPath.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetRegexExclude.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetExcludeArgument.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Split-BakNRetPatternScope.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Merge-BakNRetExcludeArgument.ps1')
|
||
|
||
# ---- 软件名录(SoftwareCatalog.psd1) ----
|
||
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetCatalogPath.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Format-BakNRetCatalogName.ps1')
|
||
. (Join-Path $PSScriptRoot 'Private\Test-BakNRetMapKey.ps1')
|
||
. (Join-Path $PSScriptRoot 'Private\Get-BakNRetMapValue.ps1')
|
||
. (Join-Path $PSScriptRoot 'Private\Get-BakNRetMapKeys.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Expand-CatalogPathText.ps1')
|
||
. (Join-Path $PSScriptRoot 'Private\Import-BakNRetDataFile.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSoftwareCatalog.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetArchiveTopLevelNames.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Find-BakNRetChildDirectoryByName.ps1')
|
||
|
||
# ---- 归档命名与路径还原 ----
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetItemArchiveName.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetArchiveTopName.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\New-BakNRetArchiveItem.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\New-BakNRetJunction.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Remove-BakNRetJunction.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\New-BakNRetArchiveStaging.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Remove-BakNRetArchiveStaging.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetBackupEntry.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetBackupEntryPlan.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetBackupBaseName.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Convert-BakNRetBackupFileNameToPath.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetFolderSummary.ps1')
|
||
|
||
# ---- manifest.json ----
|
||
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetManifest.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Sync-BakNRetManifestArchive.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetManifest.ps1')
|
||
|
||
# ---- 归档原子替换 ----
|
||
. (Join-Path $PSScriptRoot 'Public\Move-BakNRetArchiveIntoPlace.ps1')
|
||
|
||
# ---- 安全描述符(NTFS 属主 / ACL) ----
|
||
. (Join-Path $PSScriptRoot 'Public\Enable-BakNRetPrivilege.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\ConvertTo-BakNRetWildcardPattern.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetPathExcluded.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetAceSignatureList.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSecuritySddlWithStale.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSecurityRecord.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetSecurityRecordNeeded.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSecurityRecords.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetAtomicText.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Save-BakNRetSecuritySidecar.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetSecuritySidecar.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Convert-BakNRetSidMap.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetObjectSecurity.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Restore-BakNRetSecurity.ps1')
|
||
|
||
# ---- 配置 ----
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetConfig.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetPassword.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetRootedPath.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetItemSelected.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Find-BakNRet7zExecutable.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\New-BakNRetItemRecord.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Save-BakNRetItemRecord.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetRunSummary.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetCellWidth.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetKeyName.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\New-BakNRetInputDriver.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetKey.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Format-BakNRetPaddedText.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetAt.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Update-BakNRetMenuState.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetMenu.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetBackupListRow.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetBackupListRow.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Save-BakNRetConfigFile.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetBackupListDirection.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetBackupListEditor.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetEntryScript.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetConfigSetting.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetConfigSetting.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetLine.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetConfigEditor.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetCatalogField.ps1')
|
||
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetCatalogField.ps1')
|
||
|
||
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetCatalogEditor.ps1')
|
||
|
||
Export-ModuleMember -Function @(
|
||
'Invoke-BakNRetCatalogEditor',
|
||
'Get-BakNRetCatalogField',
|
||
'Set-BakNRetCatalogField',
|
||
'Invoke-BakNRetConfigEditor',
|
||
'Read-BakNRetLine',
|
||
'Get-BakNRetConfigSetting',
|
||
'Set-BakNRetConfigSetting',
|
||
'Invoke-BakNRetEntryScript',
|
||
'Invoke-BakNRetBackupListEditor',
|
||
'Set-BakNRetBackupListDirection',
|
||
'Save-BakNRetConfigFile',
|
||
'Get-BakNRetBackupListRow',
|
||
'Set-BakNRetBackupListRow',
|
||
'Invoke-BakNRetMenu',
|
||
'Update-BakNRetMenuState',
|
||
'Format-BakNRetPaddedText',
|
||
'Write-BakNRetAt',
|
||
'Get-BakNRetKeyName',
|
||
'New-BakNRetInputDriver',
|
||
'Read-BakNRetKey',
|
||
'Get-BakNRetCellWidth',
|
||
'Write-BakNRetRunSummary',
|
||
'Save-BakNRetItemRecord',
|
||
'New-BakNRetItemRecord',
|
||
'Find-BakNRet7zExecutable',
|
||
'Resolve-BakNRetRootedPath',
|
||
'Test-BakNRetItemSelected',
|
||
'Enter-BakNRetRunLock',
|
||
'Exit-BakNRetRunLock',
|
||
'Get-BakNRetRunLockPath',
|
||
'Set-BakNRetDebug',
|
||
'Start-BakNRetLog',
|
||
'Stop-BakNRetLog',
|
||
'Get-BakNRetLogPath',
|
||
'Write-BakNRetLog',
|
||
'Test-BakNRetAdministrator',
|
||
'Get-BakNRetFreeSpaceGB',
|
||
'ConvertTo-BakNRetNativeArgumentString',
|
||
'Invoke-ExternalCommand',
|
||
'Resolve-BakNRetCompressionTool',
|
||
'Get-Optimized7zArgument',
|
||
'Split-BakNRetToken',
|
||
'Remove-BakNRetQuote',
|
||
'Test-BakNRetMarker',
|
||
'ConvertFrom-BakNRetPatternList',
|
||
'ConvertFrom-BackupListLine',
|
||
'Test-BakNRetLiteralPath',
|
||
'Get-BakNRetRegexExclude',
|
||
'Get-BakNRetExcludeArgument',
|
||
'Split-BakNRetPatternScope',
|
||
'Merge-BakNRetExcludeArgument',
|
||
'Resolve-BakNRetCatalogPath',
|
||
'Get-BakNRetSoftwareCatalog',
|
||
'Find-BakNRetChildDirectoryByName',
|
||
'Format-BakNRetCatalogName',
|
||
'Expand-CatalogPathText',
|
||
'Get-BakNRetArchiveTopLevelNames',
|
||
'Get-BakNRetArchiveTopName',
|
||
'New-BakNRetArchiveItem',
|
||
'New-BakNRetJunction',
|
||
'Remove-BakNRetJunction',
|
||
'New-BakNRetArchiveStaging',
|
||
'Remove-BakNRetArchiveStaging',
|
||
'Get-BakNRetItemArchiveName',
|
||
'Resolve-BakNRetBackupEntry',
|
||
'Write-BakNRetBackupEntryPlan',
|
||
'Get-BakNRetBackupBaseName',
|
||
'Convert-BakNRetBackupFileNameToPath',
|
||
'Get-BakNRetFolderSummary',
|
||
'Read-BakNRetManifest',
|
||
'Write-BakNRetManifest',
|
||
'Sync-BakNRetManifestArchive',
|
||
'Move-BakNRetArchiveIntoPlace',
|
||
'Enable-BakNRetPrivilege',
|
||
'ConvertTo-BakNRetWildcardPattern',
|
||
'Test-BakNRetPathExcluded',
|
||
'Get-BakNRetAceSignatureList',
|
||
'Get-BakNRetSecuritySddlWithStale',
|
||
'Get-BakNRetSecurityRecord',
|
||
'Test-BakNRetSecurityRecordNeeded',
|
||
'Get-BakNRetSecurityRecords',
|
||
'Write-BakNRetAtomicText',
|
||
'Save-BakNRetSecuritySidecar',
|
||
'Read-BakNRetSecuritySidecar',
|
||
'Convert-BakNRetSidMap',
|
||
'Set-BakNRetObjectSecurity',
|
||
'Restore-BakNRetSecurity',
|
||
'Get-BakNRetConfig',
|
||
'Get-BakNRetPassword'
|
||
)
|
||
|