Using rsync and Shadow Copy for Backing up a Windows Machine


rsync is a cool free and open source tool allowing for efficient creation of incremental and differential backups locally and over network.

Doing the same which can easily be done on Unix/Linux with a Windows system is possible but much more tedious.

This article describes how one can do a Mac Timemachine alike backup from a Windows machine to a Unix storage system (FreeBSD, FreeNAS in our case).

There are two major problems you have to overcome to achieve that objective:

  1. Get a version of rsync and other Unix tools running on Windows
  2. Make the files on a Windows filesystem readable for rsync, even if they are opened by some other processes.

The first can be acomplished by installing cygwin. And the second can be acomplished by creating a shadow copy of the file system subtree to backup and then run rsync on that shadow copy.

Installing rsync using cygwin

Download cygwin setup-x86_64.exe and run it as Administrator.

setup-x86_64.exe is kind of a package manager which has only the very basic packages preselected for install.

Search for the following packages and mark them for installation aswell: vim, openssh, git, rsync(, bash-completion, ...)

Get a decent script that does the backup using rsync

There are a lot of free scripts doing the backup task all with different features and configuration options.
I decided for
Rsync time backup. For it's features see here.

Setup ssh for public-key authentication

To be able to non-interactively establish an ssh connection to the remote storage system, a public/private keypair must be generated on the system which wants to push it's backup. Then the public key part must be made available to the storage system.

Run ssh-keygen and copy the created public key to the target system's ~/.ssh/authorized_keys

ssh-keygen -f /home/bup_user/.ssh/id_rsa_bupmachine

Create a new shadow copy and make it available by symbolic link

The following powershell commands create a new shadow copy of the drive "G:" and makes it accessible by symolic linking it to C:\bup_shadow.

$bup_new_shadow=(Get-WmiObject -list win32_shadowcopy).create("G:\","ClientAccessible")
$bup_shadow=Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $bup_new_shadow.ShadowID }
$bup_shadow_link_target = $bup_shadow.DeviceObject + "\"
cmd /c mklink /d C:\bup_shadow "$bup_shadow_link_target"

As it has been reported that powershell cannot create symbolic links, it can be done by calling cmd.

One the other hand it has been reported that the following powershell command should work (and it does on my system).

New-Item -ItemType SymbolicLink -Path C:\bup_shadow -Target "$bup_shadow_link_target"

Run the Backup Script

/home/lukas/downloads/rsync-time-backup/ -i /home/bup_user/.ssh/id_rsa_bupmachine /cygdrive/c/bup_shadow bup_user@storage.server:/storage/bup

Delete the Shadow Copy

Finally, to delete the shadow copy run the appropriate vssadmin command. To specify which shadow copy to delete, you need to provide the "Shadow Copy ID".

vssadmin delete shadows /shadow={d768ddfc-5d01-4c72-8cfd-39c94efca6e8}

The even better option would be to do it natively through WMI using $bup_shadow.Delete()

Finally delete the symbolic link.

As it seems like powershell not only cannot create symbolic links but also cannot remove them, this needs to be done using cmd again (see here).

cmd /c rmdir C:\bup_shadow

A native powershell command to this might be

(Get-Item C:\bup_shadow).Delete()

The Final Powershell Script

# rsync-tmbackup backup script
# (C) 2019 Lukas Zimmermann, University of Basel

## create new shadow copy
$bup_new_shadow=(Get-WmiObject -list win32_shadowcopy).create("D:\","ClientAccessible")
$bup_shadow=Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $bup_new_shadow.ShadowID }

## create symbolic link to just created shadow copy
$bup_shadow_link_target = $bup_shadow.DeviceObject + "\"
cmd /c mklink /d D:\bup_shadow "$bup_shadow_link_target"
##New-Item -ItemType SymbolicLink -Path D:\bup_shadow -Target "$bup_shadow_link_target"

## run backup
## need to prepend "/usr/bin" to $PATH, otherwise the wrong ssh client is used
C:\cygwin64\bin\bash -c "PATH=/usr/bin:$PATH; /home/lukas/downloads/rsync-time-backup/ -i /home/bup_user/.ssh/id_rsa_backedup_machine /cygdrive/d/bup_shadow bup_user@storage.server:/storage/bup  /home/bup_useR/.rsync_tmbackup/rsync_tmbackup_exclude.txt"

## delete symbolic link to shadow copy
(Get-Item D:\bup_shadow).Delete()

## delete shadow copy itself

Configure Windows to Allow Powershell Scripts

Start Windows PowerShell with the "Run as Administrator" option. Enable running unsigned scripts by entering:

set-executionpolicy remotesigned

Regularly Run by Task Scheduler

Setup a Scheduled Task by using Windows Task Scheduler or other means.

A typical Scheduled Task may look like the following, when running the following Powershell commands.

New-Object -ComObject "Schedule.Service"; $taskService.Connect(); $rootTaskFolder = $taskService.GetFolder("\"); $task = $rootTaskFolder.GetTask("backup_g_drive"); $task

Name               : backup_drive
Path               : \backup_drive
State              : 3
Enabled            : True
LastRunTime        : 20.08.2019 05:00:02
LastTaskResult     : 0
NumberOfMissedRuns : 0
NextRunTime        : 21.08.2019 05:00:00
Definition         : System.__ComObject
Xml                : <?xml version="1.0" encoding="UTF-16"?>
                     <Task version="1.4" xmlns="">
                         <Description>Start backup of D: drive to bup_user@storage.server</Description>
                         <Principal id="Author">
                       <Actions Context="Author">

Remote Administration

To be able to remotely administer the backup processing despite a user being logged in to the Windows console, one may install the RDP Wrapper Library.

More details on the use of RDPWrapper


This site maintained by:
My public PGP key
last updated: 2019-07-08 Valid CSS! Valid XHTML 1.0 Strict