Configuring Windows 8/8.1/10 File History via command line

10,701

Unfortunately the API is not very straightforward to use - most of the relevant calls are to a COM object that doesn't implement IDispatch. It would therefore be exceedingly difficult and messy to call these functions from PowerShell. These are the calls we need to make:

To call all these functions, we can use my open-source application SprintDLL. I wrote this script for you, commented with faux-C++ equivalents of each section:

// 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)

I got the VTable field IDs from the positions of the functions in the C-style COM interface for the File History manager COM object. If the script succeeds, it will say that every function returned zero.

To use the script, save it to a file, e.g. filehistory.sprint. You can then run it from a batch file like this:

sprintdll run filehistory.sprint

If deploying across the network, you might want to include a command that copies the utility and the script onto the local machine first.

Share:
10,701

Related videos on Youtube

Nauf_M
Author by

Nauf_M

DevOps engineer at Intremedia. My opinion is in no way relevant to opinion of my bosses. Release process, code repositories organization, IaC (in AWS using Terraform and Ansible), CI/CD (Jenkins mostly, some Groovy), some coding (Go, JavaScript, Python). Some experience with Azure DevOps (aka TFS), GitLab CI/CD. Contacts: Telegram: @aderbenev_intermedia_net vkontakte: @logicdaemon (checking 1-2 times per week; care, FSB spies on you!) facebook messenger: @LogicDaemon (well, in 2019 I found out someone tried to contact me in 2016)

Updated on September 18, 2022

Comments

  • Nauf_M
    Nauf_M over 1 year

    tl;dr: Is there a way to configure windows 8 file history via unattended command-line/some script?

    long story: I'm configuring a lot of stand-alone (non-domain) PCs and I think some backup is better than no backup. On Windows 7, I even configure its standard backup, despite it's retarded – by default it significantly slows computer every Monday, unless by some obscure reason user didn't turn off their PC before weekend, and it fills backup medium and stops backing up.

    And I resigned to try to automate its configuration, but at least there I can set it up once as admin, and it's effective for all, including new, users. And I'm scheduling (scheduling is automated) custom script to remove old backups when backup media is low on space, so it's does not require maintenance afterwards (set once and forget).

    Since Windows 8, there is this thingy called File History, which is a lot less intrusive for users (it's performance impact is barely noticeable), and it can clean up for itself (automatic history management based on age or free space). It's real back up solution, for real now :) But it also requires manual configuration for each user. Which is not acceptable, as users will forget to configure it.

    My plan is to configure it per-user using some runonce logon script. I'm already doing some things via runonce-logon scripts, so installing such a script is not a problem. But I don't know how to configure File History via a script.

    I tried some research, but the only official (there are some unofficial findings, see below screenshots) related tool I found is FhManagew.exe, which removes old file versions. And I need to set it up via GUI first. On the link, there is complete API, and seemingly File History can be configured via that API. But I assume this is API for .NET apps, so it can't be used via command line. Or can it?

    Tried registry search, but file history location is not found anywhere :(

    For specifics, let's say I want to set up file history to \\localhost\FileHistory$ and to keep file version until free space needed (by default it keeps forever). Here's how it should look:

    File History in classic Control Panel File History Advanced Settings File History Select Drive

    For reference: backup to local share is workaround to make File History work on single HDD, otherwise it claims it's unsafe.


    Here is what I found via comments: configuration is stored in xml files in %LocalAppData%\Microsoft\Windows\FileHistory\Configuration. It's referenced in registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\fhsvc\Parameters\Configs with value name = path to configuration folder (as above), and value data = REG_DWORD:1.

    But simply adding these files and registry values and starting the service (there's script for it) does not start backups, neither configuration gets updated in Control Panel. However if File History is configured already, updates to xml files get reflected in control panel.

    • Admin
      Admin about 8 years
      Take a look at this link. This might help you out.
    • Admin
      Admin about 8 years
      thanks, following its traces found another. Trying to write setup script using these two.
    • Admin
      Admin over 7 years
      I still have no success with it. And I have no idea what can be wrong. Will append initial question with my findings.
    • Admin
      Admin over 5 years
      I found though that once FileHistory is setup, I can modify the Config1.xml file and the changes seem to take affect right away.
  • Reid Rankin
    Reid Rankin about 6 years
    Ok, so not only has this saved me a significant amount of time in MSDN documentation hell for this particular issue, but I'm loving SprintDLL! The lack of documentation sucks a bit, but the code itself is straightforward enough it sort of pulls double duty. Good on you for putting it out there, and you might even see a PR or two from me soon :)
  • Charles Kenyon
    Charles Kenyon about 3 years
    Adding comment on behalf of new user. @Janusz Testowy --- See superuser.com/questions/1648607/… --- I'm trying to implement the file history functionality in my organization, I used an application written by Ben N and his service startup script. However, I would like to add exclusions for specific folders to it, the question is is there an option to do this from this apk ???