chore: 记录改造前基线

改造开始前的完整状态,作为可回退的基点。此提交之后:Pester 175 项、零依赖套件 101 项全绿;PowerShell 5.1 尚不可用(源文件无 BOM)。

包含此前未提交的在制品:安全描述符套件、Hyper-V 实验环境(tools/lab)、agent 约定(AGENTS.md 与 docs/agents)。

.gitignore 增加 *.key / *.pfx:BackupConfig.psd1 的 PasswordFile 此前默认指向仓库内的 baknret.key,一次 git add -A 就会把口令提交进版本库。默认值在后续提交中改为空。
This commit is contained in:
Shuery committed 2026-09-26 21:46:55 +08:00
1 parent 7173e8ae10
commit 2937eb6652
32 files changed
+8775 -1691

No files matched your search

@@ -0,0 +1,25 @@
<#
隔离沙盒配置:归档、日志、快照全部落在 C:\BakNRet-Lab 与 C:\BakNRet\ 下(都在 VM 内),
绝不碰宿主机仓库的 Backups\ 与 logs\。
取值偏「跑得快」而非「压得小」:CompressionLevel = 1,让一次全链路几秒钟跑完;
要压真实比例时用 -CompressionLevel 9 单独跑。
#>
@{
BackupDir = 'C:\BakNRet-Lab\Backups'
LogDir = 'C:\BakNRet-Lab\logs\backup'
SnapshotDir = 'C:\BakNRet-Lab\Backups\snapshots'
# 注意:SoftwareCatalog 的相对路径是按**仓库根**(Backup.ps1 所在目录)解析的,
# 不是按本配置文件所在目录;而且路径不存在时会**静默回退**到仓库真实的
# SoftwareCatalog.psd1。沙盒必须写成仓库根相对路径,否则软件名条目会悄悄用错名录。
SoftwareCatalog = 'tools\lab\payload\sandbox\SoftwareCatalog.psd1'
CatalogMaxDepth = 5
MinFreeSpaceGB = 0
VerifyArchive = $true
ComputeHash = $true
CompressionLevel = 1
ToolOutput = 'quiet'
Snapshot = @{ Enabled = $false; KeepCount = 3; KeepDays = 30 }
Encryption = @{ Enabled = $false; PasswordFile = 'C:\BakNRet-Lab\state\baknret.key'; EncryptHeaders = $true }
DefaultExcludes = @('!Thumbs.db','!desktop.ini')
}
+26
View File
@@ -0,0 +1,26 @@
###########
# BakNRet 隔离沙盒清单(只在 VM 内使用;所有路径都指向 C:\BakNRet-Lab\sources)
###########
#
# 形态覆盖:多 Slot 软件名、单文件 Slot、中文+空格路径、真 NTFS 连接点、手写路径、
# :- 排除、:+ 追加、:: 覆盖 Path、行首方向标记 + / -、源缺失条目。
# 约束提醒:归档名 = 软件名(或路径推导名),每行必须产生唯一归档名。
# ---- 软件名条目(查同目录的 SoftwareCatalog.psd1)----
AppMultiSlot :- CacheSlot\cache-01.tmp,!*.log # Slot 前缀排除 + 任意层级通配
AppFileSlot :+ Modules:C:\BakNRet-Lab\sources\AppMultiSlot\Config # 追加映射:把 Config 放到包内 Modules\
软件目录甲 # 中文 + 空格 + 点的路径
JunctionToData # 真 NTFS 连接点
MissingApp # 源不存在:记 missing-source,退出码仍 0
OverrideTarget :: C:\BakNRet-Lab\sources\AppMultiSlot\Config # :: 覆盖名录里故意写错的 Path
# ---- 手写路径条目 ----
C:\BakNRet-Lab\sources\AppBig
C:\BakNRet-Lab\sources\AppLocked # 被占用文件:验证「有文件没打进归档」的告警
# ---- 行首方向标记 ----
+ C:\BakNRet-Lab\sources\AppDeep # 仅备份,不恢复
- C:\BakNRet-Lab\sources\AppRestoreOnly # 仅恢复,不备份(备份端跳过)
@@ -0,0 +1,34 @@
<#
BakNRet 隔离沙盒名录:软件名 -> Slot 组,全部指向 C:\BakNRet-Lab\sources 下的假数据。
只在 VM 内使用,宿主机仓库里的 SoftwareCatalog.psd1 不受影响。
带连字符的键必须加引号(PSD1 会把它当减法);这里用中文键名,也统一加引号。
#>
@{
AppMultiSlot = @{
DefaultData = @{ Path = 'C:\BakNRet-Lab\sources\AppMultiSlot\Data'; Description = '主数据(含 node_modules、session.log、空目录)' }
DefaultConfig = @{ Path = 'C:\BakNRet-Lab\sources\AppMultiSlot\Config'; Description = '配置(含 .bak)' }
CacheSlot = @{ Path = 'C:\BakNRet-Lab\sources\AppMultiSlot\Cache'; Description = '缓存(清单里再排除一条 cache-01.tmp)' }
}
AppFileSlot = @{
Profile = @{ Path = 'C:\BakNRet-Lab\sources\AppFileSlot\profile.json'; Description = '单文件 Slot:归档内是名为 Profile 的文件' }
Readme = @{ Path = 'C:\BakNRet-Lab\sources\AppFileSlot\readme.txt'; Description = '另一个单文件 Slot' }
}
'软件目录甲' = @{
DefaultData = @{ Path = 'C:\BakNRet-Lab\sources\软件 目录.甲'; Description = '中文 + 空格 + 点的路径' }
}
JunctionToData = @{
DefaultData = @{ Path = 'C:\BakNRet-Lab\sources\JunctionToData'; Description = '真 NTFS 连接点(指向 AppMultiSlot\Data)' }
}
MissingApp = @{
DefaultData = @{ Path = 'C:\BakNRet-Lab\sources\MissingApp'; Description = '源不存在:备份跳过并记 missing-source,恢复仍知道目标位置' }
}
OverrideTarget = @{
DefaultData = @{ Path = 'C:\BakNRet-Lab\sources\OverrideTarget-故意不存在'; Description = '故意写错,由清单里的 :: 覆盖成存在的目录' }
}
}