So i\'m essentially trying to retrieve the information in the screenshot but with PowerShell. Kind of getting stumped at the first hurdle.
Best i can find i
Accessing Volume Shadow Copy (VSS) Snapshots from powershell has some further information.
There is also a utility called vssadmin which appears to be the native utility. This link uses vssadmin and select-string to get the information. https://p0w3rsh3ll.wordpress.com/2014/06/21/mount-and-dismount-volume-shadow-copies/
There are a few of steps in PowerShell to get to browsing shadow copies. First, below code will display a list of drives and their shadow copies
$shadowStorageList = @();
$volumeList = Get-WmiObject Win32_Volume -Property SystemName,DriveLetter,DeviceID,Capacity,FreeSpace -Filter "DriveType=3" | select @{n="DriveLetter";e={$_.DriveLetter.ToUpper()}},DeviceID,@{n="CapacityGB";e={([math]::Round([int64]($_.Capacity)/1GB,2))}},@{n="FreeSpaceGB";e={([math]::Round([int64]($_.FreeSpace)/1GB,2))}} | Sort DriveLetter;
$shadowStorages = gwmi Win32_ShadowStorage -Property AllocatedSpace,DiffVolume,MaxSpace,UsedSpace,Volume |
Select @{n="Volume";e={$_.Volume.Replace("\\","\").Replace("Win32_Volume.DeviceID=","").Replace("`"","")}},
@{n="DiffVolume";e={$_.DiffVolume.Replace("\\","\").Replace("Win32_Volume.DeviceID=","").Replace("`"","")}},
@{n="AllocatedSpaceGB";e={([math]::Round([int64]($_.AllocatedSpace)/1GB,2))}},
@{n="MaxSpaceGB";e={([math]::Round([int64]($_.MaxSpace)/1GB,2))}},
@{n="UsedSpaceGB";e={([math]::Round([int64]($_.UsedSpace)/1GB,2))}}
# Create an array of Customer PSobject
foreach($shStorage in $shadowStorages) {
$tmpDriveLetter = "";
foreach($volume in $volumeList) {
if($shStorage.DiffVolume -eq $volume.DeviceID) {
$tmpDriveLetter = $volume.DriveLetter;
}
}
$objVolume = New-Object PSObject -Property @{
Volume = $shStorage.Volume
AllocatedSpaceGB = $shStorage.AllocatedSpaceGB
UsedSpaceGB = $shStorage.UsedSpaceGB
MaxSpaceGB = $shStorage.MaxSpaceGB
DriveLetter = $tmpDriveLetter
}
$shadowStorageList += $objVolume;
}
for($i = 0; $i -lt $shadowStorageList.Count; $i++){
$objCopyList = Get-WmiObject Win32_ShadowCopy | Where-Object {$_.VolumeName -eq $shadowStorageList[$i].Volume} | select DeviceObject, InstallDate
$shadowStorageList[$i] | add-member Noteproperty shadowcopies $objCopyList
$shadowStorageList[$i]
}
Sample output:
AllocatedSpaceGB : 9.17 DriveLetter : F: Volume : \?\Volume{6c974bfe-0525-11e7-80bf-0050568007f5}\ MaxSpaceGB : 15 UsedSpaceGB : 8.46 shadowcopies : {@{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy39; InstallDate=20170902070009.648986+600}, @{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy40; InstallDate=20170903070009.902376+600}, @{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy41; InstallDate=20170904070016.340573+600}, @{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy42; InstallDate=20170904120031.644419+600}...}
AllocatedSpaceGB : 6.28 DriveLetter : C: Volume : \?\Volume{4c22f9da-2b50-11e6-80b3-806e6f6e6963}\ MaxSpaceGB : 6.96 UsedSpaceGB : 5.78 shadowcopies : {@{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3; InstallDate=20170921070020.298687+600}, @{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4; InstallDate=20170921120026.126738+600}, @{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5; InstallDate=20170922070025.309517+600}, @{DeviceObject=\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy6; InstallDate=20170922120004.852824+600}...}
To browse a shadow copy (example GLOBALROOT\Device\HarddiskVolumeShadowCopy6), you need to create a symbolic link to it (windows shortcut) which you can then browse in Windows explorer. Example code below:
# Load assembly to create symlink
try {
$null = [mklink.symlink]
}
catch {
Add-Type @"
using System;
using System.Runtime.InteropServices;
namespace mklink
{
public class symlink
{
[DllImport("kernel32.dll")]
public static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
}
}
"@
}
# create symlink
[mklink.symlink]::CreateSymbolicLink('symlink path (example C:\temp\link1)', '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4\', 1);
Though it may not be an exact solution to the OP's question I'm adding this to several related posts in the hopes it will help someone else, who, like me, needed a way to list all snapshots off a remote path. Searching for this was agony and I was about to give up until I found the answer.
I searched and searched for the ability to list previous versions programmatically.. could not find a solution for viewing previous versions on an SMB / CIFS share. Volrest, vssadmin, alphaVss, etc.. round and round.. even win32_shadowCopy failed, because our target machines are netapps. Nothing worked.
Then I fount this posting says they can use SMB commands in Perl to view them. https://mark.clow.es/?blog/2018/02/listing-shadow-copies
If Perl can do it, surely some winAPI could also. FSCTL_SRV_ENUMERATE_SNAPSHOTS is the SMB command needed. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/bffc70f9-b16a-453b-939a-0b6d3c9263af
Finally found this genius ( God bless kenjiuno ) who created a dll for .NET: https://github.com/HiraokaHyperTools/LibEnumRemotePreviousVersion
After adding reference to kenjiuno's dll, I called it:
Dim s() as String = LibEnumRemotePreviousVersion.PreviousversionOnRemote("\\server\share")
it returned all previous versions as @GMT-blablabla. Then all you need to do is append the one you want to the end of your UNC path.
No mklink, no mapping drives, none of it.. everything works exactly and as simply as it should have if Microsoft would have pulled their head out and put this in .Net themselves.