Created
May 6, 2020 18:15
-
-
Save earthnuker/94a91faccc5b565a6661bc5245bd82b9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Windows PowerShell Script to use restic to backup files using the Volume Shadow Copy Service, allowing | |
# that are in use to be backed up. The script must be run with elevated privileges. | |
# The Volume Shadow Copy Service must be enabled for the disk volume that contains the files to be backed up. | |
# | |
# credit: https://github.com/turnkey-commerce | |
# | |
# Parameters | |
# Config | |
function call_cmd() { | |
$cwd = $PWD | |
Set-Location $env:TEMP | |
& cmd $MyInvocation.UnboundArguments | |
Set-Location $cwd | |
} | |
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition | |
Set-Location $scriptPath | |
$ProgressPreference = "SilentlyContinue" | |
$IsAdmin = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) | |
$env:RESTIC_PASSWORD_COMMAND = "gopass show -o misc/Restic_Backup" | |
if ($IsAdmin -eq $false) { | |
Write-Host "Running as admin!" | |
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs | |
exit | |
} | |
# ========================= | |
$env:RESTIC_REPOSITORY = '\\Server\RAID\Backups\restic\' + $env:COMPUTERNAME | |
$exclude_file = $env:RESTIC_REPOSITORY + '\exclude.txt' | |
$list_file = $env:TEMP + '\files_' + $env:COMPUTERNAME + '.txt' | |
$Volumes = @() | |
foreach ($part in (Get-Partition)) { | |
$disk = (Get-Disk -Partition $part) | |
If (($disk.Bustype -in ("SATA", "NVMe")) -and $part.DriveLetter) { | |
$Volumes += $part.DriveLetter | |
} | |
} | |
foreach ($sc in (Get-WmiObject Win32_ShadowCopy)) { | |
$sc.Delete() | |
} | |
if ((Test-Path ($env:RESTIC_REPOSITORY + '\config')) -eq $false) { | |
restic init | |
} | |
if (Test-Path "$env:TEMP\__shadowcopy__\") { | |
call_cmd /c rmdir /s /q "$env:TEMP\__shadowcopy__\" | |
} | |
New-Item -ItemType Directory -Path "$env:TEMP\__shadowcopy__\" | Out-Null | |
$Files = @() | |
$ShadowVolumes = @() | |
$Mountpoints = @() | |
foreach ($rootVolume in ($Volumes | Sort-Object)) { | |
Write-Host "Creating Snapshot for $rootVolume" | |
$ShadowPath = $env:TEMP + '\__shadowcopy__\' + $rootVolume | |
$s1 = (Get-WmiObject -List Win32_ShadowCopy).Create($rootVolume + ':\', "ClientAccessible") | |
$s2 = Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $s1.ShadowID } | |
$device = $s2.DeviceObject + "\" | |
if (Test-Path $ShadowPath) { | |
call_cmd /c rmdir $ShadowPath | |
} | |
call_cmd /c mklink /d $ShadowPath "$device" | |
$ShadowVolumes += $s2 | |
$Mountpoints += $ShadowPath | |
} | |
$L = (Get-Location) | |
$Files = @() | |
Set-Location ($env:TEMP + '\__shadowcopy__\') | |
(Get-ChildItem -Force .).Name | ForEach-Object { | |
$shadowPath = (Get-Item -LiteralPath ($env:TEMP + '\__shadowcopy__\')).FullName | |
$Files += (Get-ChildItem -Force $_).FullName.Replace("[","?").Replace("]","?").Replace($shadowPath,"") # Fix paths so restic doesn't intepret them as Regex patterns | |
} | |
$Files | Out-File $list_file | |
"" | Out-File $env:TEMP\restic_exclude.txt | |
if (Test-Path $exclude_file) { | |
(Get-Content $exclude_file) | ForEach-Object { | |
Write-Output ([Regex]::replace($_, "^([A-Z]):\\(.*)$", '$1\$2')) # make path relative to shadowcopy | |
} | Out-File $env:TEMP\restic_exclude.txt | |
} | |
restic cache --cleanup | |
restic backup --exclude-caches --exclude-file $env:TEMP\restic_exclude.txt --files-from $list_file | |
Set-Location $L | |
foreach ($vol in $ShadowVolumes) { | |
$vol.Delete() | |
} | |
foreach ($mount in $Mountpoints) { | |
call_cmd /c rmdir $mount | |
} | |
Remove-Item -Force $env:TEMP\restic_exclude.txt | |
Remove-Item -Force $list_file | |
Remove-Item -Force -Recurse $env:TEMP\__shadowcopy__ | |
Write-Host "Done!" | |
Write-Host "Press enter to exit" | |
Read-Host |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment