2

I'm writing a simple powershell script that would automate offsite backup from Windows file server to another remote Windows server. Files might be in use, so in order for Robocopy to sucessfully copy them I need to copy the files from last available Volume Shadow Copy for that specific drive.

I can find the last Shadow Copy with Powershell just fine; the problem is that I cannot actually "referece" it (mount it) in order to access files on the Shadow Copy.

But this "magically" changes if I first access contents of the Shadow Copy via Windows Explorer GUI

Then all of the sudden, I can access the Shadow Copy just fine and copy the contents to a remote backup server.

Here's the code in question:

#Find the latest Shadow copy
$HDDriveID = (Get-WmiObject win32_volume -filter "DriveLetter='E:'").DeviceID
$LastShadowCopy = Get-WmiObject win32_shadowcopy | Where-Object {$_.VolumeName -eq $HDDriveID} | Sort-Object InstallDate | Select-Object -Last 1

# And parse the path so that we can mount it
$arr = $LastShadowCopy.InstallDate.Split('+').Split('.')
$VolumeShadowCopytime = [DateTime]::ParseExact($arr[0], 'yyyyMMddHHmmss', $null)
$UTCTime = $VolumeShadowCopytime.AddHours(-[int]$arr[2]/60)
$VolumeShadowCopyPath = "\\127.0.0.1\E$\@GMT-" + (Get-Date $UTCTime).ToString("yyyy.MM.dd-HH.mm.ss") + "\"

# Then, let's actually mount it:
New-PSDrive -Name Y -PSProvider FileSystem -Root $VolumeShadowCopyPath

If I run this part of a script without accessing the last Shadow Copy via GUI, I receive the following error:

New-PSDrive : The specified drive root "\\127.0.0.1\E$\@GMT-2018.06.27-05.00.09\" either does not exist, or it is not a folder.
At [scriptlocation]\BackupToAzureDrive.ps1:21 char:1
+ New-PSDrive -Name Y -PSProvider FileSystem -Root $VolumeShadowCopyPat ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ReadError: (Y:PSDriveInfo) [New-PSDrive], IOException
    + FullyQualifiedErrorId : DriveRootError,Microsoft.PowerShell.Commands.NewPSDriveCommand

Again, as soon as the Shadow copy is (aparently?) properly referenced by Windows when I open it via Windows Explorer, I get no such error. Shadow Copy gets mounted without any problems and I can access files&folders.

I'm no Powershell guru nor am I very enthusiastic about it. I'm stuck with this problem for days now. Does anyone have an idea how to solve this and/or knows of the workaround?

imag0dei
  • 21
  • 4
  • PowerShell adds the `ConvertToDateTime()` method to WMI objects to help convert CIM_DATETIMEs . You could simplify your script with: `$VolumeShadowCopyPath = '\\127.0.0.1\E$\@GMT-{0:yyyy.MM.dd-HH.mm.ss}\' -f $LastShadowCopy.ConvertToDateTime($LastShadowCopy.InstallDate).ToUniversalTime()` – Bacon Bits Jun 27 '18 at 13:03
  • If you're on PowerShell 3+ (you should be) you could use the newer CIM commands instead of the WMI commands, which would make it even easier since it automatically converts most fields to the appropriate data type: `$LastShadowCopy = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter='E:'" -KeyOnly | Get-CimAssociatedInstance -ResultClassName Win32_ShadowCopy | Sort-Object -Property InstallDate | Select-Object -Last 1; $VolumeShadowCopyPath = '\\127.0.0.1\E$\@GMT-{0:yyyy.MM.dd-HH.mm.ss}\' -f $LastShadowCopy.InstallDate.ToUniversalTime();` – Bacon Bits Jun 27 '18 at 13:09
  • Thanks for the suggestion. This is nice to know, however, I still have my original problem :) Do you (or anyone else) have some hints about that? – imag0dei Jun 28 '18 at 06:12
  • Unfortunately none of our systems use VSS anymore so I don't have any way to test it. I don't remember this happening when I accessed the snapshots, but it's been a couple years. I added what I did as a comment to maybe help if there were any bugs in your method, but other than obvious things like "are you running as an admin?" I haven't seen a similar problem before. – Bacon Bits Jun 29 '18 at 02:12

1 Answers1

0

Upon looking at this stackoverflow question here I got my answer. I've come across this answer earlier but I dismissed it because it suggest using mklink to "map" a VS Copy and not the native New-PSDrive. In fact I've glanced over the answer too quickly and missed the crucial advice. My bad. Kudos to the guy answering it the first time, Ansgar Wiechers.

Anyway, it seems that the correct way to reference the Shadow Copy is to first select the desired Shadow copy and then accessing the DeviceObject Property. This way my code required to map the specific Shadow Copy is down to three lines (and yes, it can most probably be reduced even further (and converted to CIM instead od WMI)):

#Find the latest Shadow copy
$HDDriveID = (Get-WmiObject win32_volume -filter "DriveLetter='E:'").DeviceID
$LastShadowCopy = Get-WmiObject win32_shadowcopy | Where-Object {$_.VolumeName -eq $HDDriveID} | Sort-Object InstallDate | Select-Object -Last 1
# Then mount it:
New-PSDrive -Name Y -PSProvider FileSystem -Root ($LastShadowCopy.DeviceObject + "\")

Works perfectly. Again, behavior is consistent with previous: once I reference (and map to drive letter) specific Shadow Copy with the code above, I can again use the form "\127.0.0.1\E$\@GMT-2018.06.27-05.00.09\". This doesn't matter anyway, tho, because once I have the Shadow Copy mapped to a drive letter, I can obviously access content via this drive letter.

Anyway, I'm happy with the solution. Although the question has been asked and answered I thought it might help somebody with the same problem if I don't just link to existing question.

imag0dei
  • 21
  • 4
  • Update: this does not work (anymore?). I'm running the script I saved more than a month ago when I marked the question as answered and it just doesn't work. I've checked and rechecked and triplechecked for any typos in the script. So, I guess this is not solved. Back to square one. – imag0dei Aug 10 '18 at 10:07
  • snapshot files can be accessed directly using the correct device object name. e.g. from PS, cmd /c "dir \\?\HarddiskVolumeShadowCopy3\Windows\System32\drivers" will walk and list snapshot files just like a regular physical volume dir cmd – Neelabh Mam Sep 04 '22 at 06:26