tl;dr:有没有办法通过无人值守命令行/某些脚本配置 Windows 8 文件历史记录?
长话短说:我正在配置许多独立(非域)PC,我认为备份总比没有备份好。在 Windows 7 上,我甚至配置了它的标准备份,尽管它很慢——默认情况下,它会在每个星期一显著降低计算机速度,除非由于某种不为人知的原因,用户在周末之前没有关闭 PC,它会填满备份介质并停止备份。
我决定尝试自动化配置,但至少我可以以管理员身份设置一次,并且它对所有用户(包括新用户)都有效。而且我调度(调度是自动化)自定义脚本当备份媒体空间不足时删除旧备份,因此之后不需要维护(设置一次即可忘记)。
从 Windows 8 开始,就有了文件历史记录,它对用户的干扰小了很多(它对性能的影响几乎察觉不到),而且它可以自行清理(根据时间或可用空间自动进行历史记录管理)。这是真正的备份解决方案,现在真的如此 :) 但它也需要每个用户手动配置。这是不可接受的,因为用户将要忘记配置它。
我的计划是使用一些 runonce 登录脚本为每个用户配置它。我已经通过 runonce-logon 脚本做了一些事情,所以安装这样的脚本不是问题。但我不知道如何通过脚本配置文件历史记录。
我尝试了一些研究,但唯一官方的(有一些非官方的发现,见下面的截图)我发现的相关工具是系统管理工具,它会删除旧文件版本。我需要先通过 GUI 进行设置。在链接上,有完整的 API,似乎可以通过该 API 配置文件历史记录。但我认为这是 .NET 应用程序的 API,因此不能通过命令行使用它。或者可以吗?
尝试过注册表搜索,但在任何地方都找不到文件历史记录位置 :(
具体来说,假设我想设置文件历史记录\\localhost\FileHistory$
并保留文件版本,直到需要可用空间(默认情况下它会永久保留)。它应该是这样的:
供参考:备份到本地共享是使文件历史记录在单个硬盘上运行的解决方法,否则它声称不安全。
这是我通过评论发现的:配置存储在 中的 xml 文件中%LocalAppData%\Microsoft\Windows\FileHistory\Configuration
。它在注册表项中引用HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\fhsvc\Parameters\Configs
,其值名称 = 配置文件夹路径(如上所述),值数据 = REG_DWORD:1
。
但只需添加这些文件和注册表值并启动服务(有脚本) 不会启动备份,控制面板中的配置也不会更新。但是,如果已配置了文件历史记录,则 xml 文件的更新会反映在控制面板中。
答案1
不幸的是,API 的使用并不十分简单——大多数相关调用都是COM 对象未实现IDispatch
。因此,从 PowerShell 调用这些函数将极其困难和混乱。以下是我们需要进行的调用:
CoCreateInstance
获取FhConfigMgr
对象IFhConfigMgr::CreateDefaultConfiguration
创建配置或替换旧配置IFhConfigMgr::ProvisionAndSetNewTarget
设置备份目标文件夹IFhConfigMgr::SetLocalPolicy
将策略设置为仅在需要空间时删除IFhConfigMgr::SetBackupStatus
打开文件历史记录IFhConfigMgr::SaveConfiguration
提交更改FhServiceOpenPipe
获取文件历史记录服务的句柄FhServiceReloadConfiguration
告诉服务重新加载其设置FhServiceClosePipe
关闭服务句柄
要调用所有这些函数,我们可以使用我的开源应用程序打印动态链接库。我为你写了这个脚本,并用仿 C++ 的等价代码注释了每个部分:
// CoCreateInstance(CLSID_FhConfigMgr, NULL, CLSCTX_INPROC_SERVER, IID_IFhConfigMgr, &fh)
newslot native fhPtr
call ole32.dll!CoCreateInstance /return uint (blockptr(guid {ED43BB3C-09E9-498a-9DF6-2177244C6DB4}), nullptr, int 1, blockptr(guid {6A5FEA5B-BF8F-4EE5-B8C3-44D8A0D7331C}), slotptr fhPtr)
newslot native fh
copyslot fh = fhPtr dereferenced
newslot block vtbl = nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
copyslot vtbl = fh dereferenced
// fh->CreateDefaultConfiguration(TRUE)
newslot native createDefaultConfiguration
copyslot createDefaultConfiguration = vtbl field 4
call funcat createDefaultConfiguration /call thiscall /return uint (slotdata fhPtr, int 1)
// fh->ProvisionAndSetNewTarget("\\localhost\FileHistory$\", "Local Disk")
newslot native provisionAndSetNewTarget
copyslot provisionAndSetNewTarget = vtbl field 14
call funcat provisionAndSetNewTarget /call thiscall /return uint (slotdata fhPtr, bstr "\\\\localhost\\FileHistory$\\", bstr "Local Disk")
// fh->SetLocalPolicy(FH_RETENTION_TYPE, FH_RETENTION_UNLIMITED)
newslot native setLocalPolicy
copyslot setLocalPolicy = vtbl field 9
call funcat setLocalPolicy /call thiscall /return uint (slotdata fhPtr, int 1, int 1)
// fh->SetBackupStatus(FH_STATUS_ENABLED)
newslot native setBackupStatus
copyslot setBackupStatus = vtbl field 11
call funcat setBackupStatus /call thiscall /return uint (slotdata fhPtr, int 2)
// fh->SaveConfiguration()
newslot native saveConfiguration
copyslot saveConfiguration = vtbl field 5
call funcat saveConfiguration /call thiscall /return uint (slotdata fhPtr)
// FhServiceOpenPipe(TRUE, &fhPipe)
newslot native fhPipe
call fhsvcctl.dll!FhServiceOpenPipe /return int (int 1, slotptr fhPipe)
// FhServiceReloadConfiguration(fhPipe)
call fhsvcctl.dll!FhServiceReloadConfiguration /return int (slotdata fhPipe)
// FhServiceClosePipe(fhPipe)
call fhsvcctl.dll!FhServiceClosePipe /return int (slotdata fhPipe)
我从函数的位置获取了 VTable 字段 IDC 风格的 COM 接口用于文件历史记录管理器 COM 对象。如果脚本成功,它将说每个函数都返回零。
要使用脚本,请将其保存到文件中,例如filehistory.sprint
。然后您可以从批处理文件中运行它,如下所示:
sprintdll run filehistory.sprint
如果通过网络部署,您可能需要首先包含一个将实用程序和脚本复制到本地机器的命令。