I saw there’s already discussion on implementing VSS but hasn’t been built as of yet.
I wanted to write something for myself that creates/destroys shadow copies before/after restic runs.
I came across this comment on the issue which lead me in the right direction but then I discovered that these Get-WmiObject
commands don’t work in Powershell 7.
If you try, you get:
Get-WmiObject: The term ‘Get-WmiObject’ is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
So, I tried using CimInstance
instead which worked after lots of hair pulling and internet searches.
Here’s what I came up with. I don’t claim to be the best scripter ever but it might help someone who wants to do VSS with Powershell 7 with no extra software installs:
# Absolute path for directories to backup. This version is only enabling VSS for the C:\
# Paths need to include \shadowcopy\. That is where the VSS for the drive is linked for the duration of the backup
$backupLocations = @(
"C:\shadowcopy\Users\Doni",
"C:\shadowcopy\Program Files (x86)\Steam"
)
# Restic options
$repo = "rclone:gcd_clear://restic"
$pFile = "C:\users\Doni\Documents\restic.txt"
$computername = $env:COMPUTERNAME.tolower()
# Check for currently running restic instance
$isRunning = Get-Process -Name "restic" -ErrorAction SilentlyContinue
if ($isRunning.ProcessName -eq "rclone") {
Write-Host "restic instance currently running. Exiting..."
Exit
}
# This section ends by removing ALL shadow copies indiscriminately
else {
foreach ($location in $backupLocations)
{
if ($null = Get-CimInstance -ClassName Win32_ShadowCopy) {
}
# Determine drive letter from path given in $backupLocations array
$driveLetter = ($location.ToCharArray() | Select-Object -First 3) -join ''
# Build shadowcopy and link
$deviceID = Get-CimInstance -ClassName win32_volume | Where-Object {$_.Name -eq "$driveLetter"} | Select-Object -ExpandProperty DeviceID
Invoke-CimMethod -ClassName Win32_ShadowCopy -Arguments @{ Volume = $deviceID; Context = "ClientAccessible"} -MethodName Create
$shadowObject = Get-CimInstance -ClassName Win32_ShadowCopy | Select-Object -ExpandProperty DeviceObject
$shadowPath = $shadowObject + "\"
cmd /c mklink /d C:\shadowcopy "$shadowPath"
restic -r $repo -p $pFile backup $location --host $computername
Get-CimInstance -ClassName Win32_ShadowCopy | Remove-CimInstance
Remove-Item C:\shadowcopy -Confirm:$false -Force
}
}