Настройка истории файлов Windows 8/8.1/10 через командную строку

tl;dr: есть ли способ настроить историю файлов Windows 8 через автоматическую командную строку / какой-нибудь скрипт?

Длинная история: я настраиваю множество автономных (не доменных) ПК и думаю, что резервное копирование лучше, чем отсутствие резервного копирования. В Windows 7 я даже настраиваю его стандартное резервное копирование, несмотря на то, что оно запаздывает - по умолчанию он значительно замедляет работу компьютера каждый понедельник, если только по какой-то непонятной причине пользователь не выключил свой компьютер до выходных, а также заполнил носитель резервного копирования и прекратил резервное копирование.

И я ушел в отставку, чтобы попытаться автоматизировать его настройку, но по крайней мере там я могу настроить его один раз как администратор, и он эффективен для всех, включая новых пользователей. И я планирую (планирование автоматизировано) пользовательский сценарий для удаления старых резервных копий, когда на носителе резервных копий мало места, поэтому впоследствии он не требует обслуживания (установите один раз и забудьте).

Начиная с Windows 8, существует такая штука, которая называется "История файлов", которая гораздо менее навязчива для пользователей (ее влияние на производительность едва заметно) и может сама себя очистить (автоматическое управление историей на основе возраста или свободного места). Это реальное решение для резервного копирования, по настоящему сейчас:) Но оно также требует ручной настройки для каждого пользователя. Что неприемлемо, так как пользователи забудут его настроить.

Мой план состоит в том, чтобы настроить его для каждого пользователя, используя некоторый скрипт входа в систему runonce. Я уже делаю некоторые вещи с помощью скриптов runonce-logon, поэтому установка такого скрипта не является проблемой. Но я не знаю, как настроить историю файлов через скрипт.

Я попробовал некоторые исследования, но единственный официальный (есть неофициальные результаты, см. Ниже скриншоты) связанный инструмент, который я нашел, это FhManagew.exe, который удаляет старые версии файлов. И мне нужно сначала настроить его через графический интерфейс. По ссылке есть полный API, и, похоже, история файлов может быть настроена через этот API. Но я предполагаю, что это API для приложений.NET, поэтому его нельзя использовать через командную строку. Или это может?

Пробовал поиск в реестре, но местоположение истории файлов нигде не найдено:(

Для подробностей, скажем, я хочу настроить историю файлов \\localhost\FileHistory$ и сохранять версию файла до тех пор, пока не потребуется свободное место (по умолчанию оно сохраняется вечно). Вот как это должно выглядеть:

Для справки: резервное копирование на локальный общий ресурс - обходной путь, чтобы заставить историю файлов работать на одном жестком диске, в противном случае он утверждает, что это небезопасно.


Вот что я нашел в комментариях: конфигурация хранится в XML-файлах в %LocalAppData%\Microsoft\Windows\FileHistory\Configuration, На него ссылаются в разделе реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\fhsvc\Parameters\Configs со значением name = путь к папке конфигурации (как указано выше) и значением data = REG_DWORD:1,

Но простое добавление этих файлов и значений реестра и запуск службы ( для нее есть сценарий) не запускает резервное копирование, а конфигурация не обновляется в панели управления. Однако, если история файлов уже настроена, обновления для файлов xml отражаются на панели управления.

1 ответ

Решение

К сожалению, API не очень прост в использовании - большинство соответствующих вызовов относятся к COM-объекту, который не реализует IDispatch, Поэтому было бы чрезвычайно сложно и беспорядочно вызывать эти функции из PowerShell. Это звонки, которые нам нужно сделать:

  • CoCreateInstance чтобы получить FhConfigMgr объект
  • IFhConfigMgr::CreateDefaultConfiguration создать конфигурацию или заменить старую
  • IFhConfigMgr::ProvisionAndSetNewTarget установить целевую папку для резервного копирования
  • IFhConfigMgr::SetLocalPolicy установить политику для удаления только тогда, когда требуется место
  • IFhConfigMgr::SetBackupStatus включить историю файлов
  • IFhConfigMgr::SaveConfiguration совершить изменения
  • FhServiceOpenPipe чтобы получить дескриптор службы истории файлов
  • FhServiceReloadConfiguration сообщить службе перезагрузить ее настройки
  • FhServiceClosePipe закрыть ручку к сервису

Для вызова всех этих функций мы можем использовать мое приложение с открытым исходным кодом SprintDLL. Я написал этот скрипт для вас, прокомментировал эквиваленты faux-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 с позиций функций в COM-интерфейсе в стиле C для COM-объекта диспетчера истории файлов. Если скрипт завершится успешно, он скажет, что каждая функция вернула ноль.

Чтобы использовать скрипт, сохраните его в файл, например filehistory.sprint, Затем вы можете запустить его из командного файла следующим образом:

sprintdll run filehistory.sprint

При развертывании по сети вы можете включить команду, которая сначала копирует утилиту и сценарий на локальный компьютер.

Другие вопросы по тегам