desseim / rdiff-backup-wrapper-win

Wrapper script to automatically: mount/connect a backup destination disk → perform backup with `rdiff-backup` → dismount/disconnect the backup destination. Particularly useful as a Windows scheduled task/job.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

This is a simple PowerShell script which wraps calls to rdiff-backup with the mounting/dismounting (or connecting/disconnecting) of the backup destination.

This is the same utility as rdiff-backup-wrapper, but adapted to a Windows environment.

Use case

Just like rdiff-backup-wrapper: I find it useful to keep the system’s backup destination offline (at least from the point of view of the backup source environment, i.e. unmounted) most of the time, significantly reducing the risk of unauthorized access to or accidental corruption of the backups. This makes particular sense in the case the backup destination is local to the backup source.

The script will first connect the system to the backup destination through a "mount" procedure (e.g. the mounting of a local disk or the connecting to a remote one), then, if successful, use rdiff-backup to delete old backup increments and perform a new backup, and finally "dismount" (e.g. unmount or disconnect) the backup destination.

It also offers a couple of reusable PowerShell modules which could also be useful on their own:

RdiffBackup module

A layer of abstraction to help calling Windows or WSL rdiff-backup executables from PowerShell. It notably allows dynamically switching between several executables (e.g. installed side-by-side) selecting them at call time through a parameter. It also automatically sets necessary (e.g. for bug workaround) or sensible options according to the version of the called rdiff-backup executable, the environment it is run in (e.g. WSL), or the invoked rdiff-backup action.

ToastNotification module

A PowerShell module to easily show toast notifications to a user’s Windows desktop. It supports sending a simple toast notification with a title and a message, and automatically displaying the toast on the desktop of the user currently logged into the local machine.

Development status / quality

This is a simple script intended mainly for a personal, rather constrained use case. It only supports a subset of rdiff-backup functionalities. As such it comes on an "as-is" basis and without any guarantee whatsoever (see license for details).

It nevertheless features minimal modularity, error-handling and documentation, and should be rather simple to adapt for similar use cases.

Usage

SYNTAX
    rdiffbackup-wrapper.ps1 [-BackupLabel] <String> [-SrcFullPath] <String>
    [-DestDriveId] <String> [-DestDriveLabel] <String> [-DestPath] <String> [-UseCompatibleTimestamps]
    [[-IncludeExcludeListFile] <String>] [[-RemoveOlderThan] <String>] [[-RdiffBackupVer] <String>]
    [[-RdiffBackupRemoveVer] <String>] [<CommonParameters>]

For example:

PS > $BackupParams = @{
         BackupLabel = 'System'
         DestDriveId = 'F1391FF7683E4147BB73340B7CA25810'
         DestDriveLabel = '_Sys_backup'
         DestPath = '/Backup'
         SrcFullPath = 'C:/'
         IncludeExcludeListFile = 'X:/etc/rdiff-backup/include_filelist'
         RdiffBackupVer = 'v210a1'
         RdiffBackupRemoveVer = 'v205'
     }
PS > X:\path\to\rdiffbackup-wrapper.ps1 @BackupParams

You can get a full description of the script including parameters using Get-Help in PowerShell:

PS > Get-Help X:\path\to\rdiffbackup-wrapper.ps1 -Detailed  # (1)
  1. Make sure script running is enabled by the current PowerShell execution policy lest Get-Help fail to retrieve the script’s local help and start searching for unexisting online help instead.

Options

rdiff-backup executable

Once defined in $RdiffBackupExes, each executable can be specified by passing its hash table key as the script’s -RdiffBackupVer (for the executable to use to perform the backup) or -RdiffBackupRemoveVer (for the executable to use to remove old backup increments) parameter ; both parameters are independent and it is possible to specify a different $RdiffBackupExes key to each of them in a same script call.

Installation

Simply put the script together with the Modules directory in a given directory of your choice (e.g. C:\Users\username\bin\).

Make sure the execution policy of the PowerShell session you run the script from allows for script running ; see Microsoft documentation on how to do so.

rdiff-backup executables

You can install several rdiff-backup executables (possibly side-by-side) and select at script-call time which one the wrapper script will call internally. Each executable must be defined in the $RdiffBackupExes hash table declared in RdiffBackup.psm1. You can refer to the few predefined entries there for syntax. The RdiffBackupExe::Api member variable refers to whether the rdiff-backup executable should be called with the old or new CLI, and the RdiffBackupExe::Environment should be one of RdiffBackupExeEnv::Win for "native" Windows executables or RdiffBackupExeEnv::WSL for ones installed in the Windows Subsystem for Linux. Executables so defined can then be selected at call time.

Tip
Each parameter has a default value which can be modified by editing rdiffbackup-wrapper.ps1.

WSL

WSL executables, after the script has mounted the destination drive, need to additionally mount the backup destination within WSL. Mount options used to mount the backup destination within WSL can be set through the DEST_WSL_MOUNT_* constants declared in rdiffbackup-wrapper.ps1.

Additionally, mount within WSL is called through sudo, so for it to work unattended the default user of the default WSL distribution must be authorized to run sudo mount passwordless, for example by adding the following at the end of the sudoers file:

/etc/sudoers (or for example /etc/sudoers.d/wslDefaultUserName — if the sudoers file ends with an @includedir /etc/sudoers.d statement)
wslDefaultUserName   ALL=(ALL) NOPASSWD: /usr/bin/mount, /usr/bin/umount  # (1)
  1. Replace wslDefaultUserName with the name of your default WSL user

Modules

Alternatively, modules can be stored anywhere ; you just need to change the value of the $MODULES_ABS_PATH constant in rdiffbackup-wrapper.ps1 to the new location of the Modules directory. Each module’s path can also be set individually through their respective $MODULE_***_PATH variable value.

It’s also possible to store some or all modules in a location specified in $env:PSModulePath ; in this case, their respective Import-Module call in rdiffbackup-wrapper.ps1 can be commented out and the modules will be automatically loaded (see Microsoft documentation on script modules for more on this).

Mount/dismount operation implementation

The script ships with a mock implementation (which does nothing) of the backup destination drive mount/dismount operation. This is fine for backups toward always-mounted drives, but if you want to automatically mount/dismount the destination drive respectively before/after the backup operations, you’ll have to implement the Mount-Drive and Dismount-Drive functions in the DriveMount module to do so according to your use case. Refer to the source comments and the given mock implementation for documentation.

Scheduled execution

Note
The script assumes such a scheduled usage in its default error messages.

It often makes sense to have Windows automatically run the script at regular intervals, for automated backups. This can be achieved for example with scheduled jobs:

Register a new scheduled job to run the script with a given set of parameters
PS > $RegularBackupParams = @{
         BackupLabel = 'System'
         ...  # (1)
     }
PS > Register-ScheduledJob -Name 'System backup' -ScriptBlock { param($parameters); X:\path\to\rdiffbackup-wrapper.ps1 @parameters; } -ArgumentList $RegularBackupParams
  1. Rest of the named arguments to pass to the script

Scheduled jobs are registered as regular scheduled tasks, the action of which is to start a PowerShell instance to run the defined job. As such, scheduled job properties, like its running time or interval, can be set through the command line using the Get-ScheduledJob and Set-ScheduledJob cmdlets, or with the Windows Task Scheduler GUI: scheduled jobs are registered under the Microsoft\Windows\PowerShell\ScheduledJobs folder in the Task Scheduler Library. Besides setting the appropriate user to run the task, or the run conditions, it might also be necessary to edit the task action to pass a proper -ExecutionPolicy argument to powershell.exe lest the script not get executed when the task run PowerShell.

The output of scheduled jobs can later be retrieved using the Receive-Job cmdlet. The list of previously run job intances can be retrieved with Get-Job. For example:

Retrieve a scheduled job’s output
PS > Get-Job
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
...
16     System backup   PSScheduledJob  Failed        True            localhost            param($parameters); C...
PS > Receive-Job -Keep -Id 16  # (1)
...  # job output
  1. -Keep prevents the job from being discarded and allows for potentially retrieving it again in the future with the same command.

The job’s definition and run outputs are stored in XML format at X:\Users\<task-running-user>\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJobs\<scheduled-job-name>.

About

Wrapper script to automatically: mount/connect a backup destination disk → perform backup with `rdiff-backup` → dismount/disconnect the backup destination. Particularly useful as a Windows scheduled task/job.

License:GNU General Public License v2.0


Languages

Language:PowerShell 100.0%