How to enumerate Shadow Copies of a given file or folder?

前端 未结 3 810
时光说笑
时光说笑 2021-01-15 02:25

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

3条回答
  •  清酒与你
    2021-01-15 03:03

    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);
    

提交回复
热议问题