Accessing Volume Shadow Copy (VSS) Snapshots from powershell

前端 未结 4 447
一向
一向 2020-12-08 02:54

I am attempting to create and access a Volume Shadow Copy snapshot using the Windows Power Shell in Windows 7. I found that I can create snapshots using the following via a

相关标签:
4条回答
  • 2020-12-08 03:45

    So with the information provided here and the official microsoft documentation here https://docs.microsoft.com/en-us/previous-versions/windows/desktop/vsswmi/create-method-in-class-win32-shadowcopy I created a couple powershell functions/cmdlets that solve this problem. Random note, as of powershell 5 new-item has the itemType of symbolicLink but when I tried to make one with the target being the shadow snapshot it fails saying the path doesn't exist, so the mklink tool is still the way to go.

    function New-ShadowLink {
    [CmdletBinding()]
    param (
        $linkPath="$($ENV:SystemDrive)\ShadowCopy"
    )
    
    begin {
        Write-Verbose "Creating a snapshot of $($ENV:SystemDrive)\"
        $class=[WMICLASS]"root\cimv2:win32_shadowcopy";
        $result = $class.create("$ENV:SystemDrive\", "ClientAccessible");
        Write-Verbose "Getting the full target path for a symlink to the shadow snapshot"
        $shadow = Get-CimInstance -ClassName Win32_ShadowCopy | Where-Object ID -eq $result.ShadowID
        $target = "$($shadow.DeviceObject)\";
    }
    
    process {
        Write-Verbose "Creating SymLink to shadowcopy at $linkPath"
        Invoke-Expression -Command "cmd /c mklink /d '$linkPath' '$target'";
    }
    
    end {
        Write-Verbose "Created link to shadowcopy snapshot of $($ENV:SystemDrive)\ at $linkPath";
        Write-Verbose "Returning shadowcopy snapshot object"
        return $shadow;
    }
    

    }

    function Remove-ShadowLink {
    [CmdletBinding()]
    param (
        $shadow,
        $linkPath="$($ENV:SystemDrive)\ShadowCopy"
    )
    
    begin {
        Write-verbose "Removing shadow copy link at $linkPath"
    }
    
    process {
        Write-Verbose "Deleting the shadowcopy snapshot"
        $shadow.Delete();
        Write-Verbose "Deleting the now empty folder"
        Try {
            Remove-Item -Force -Recurse $linkPath -ErrorAction Stop;
        }
        catch {
            Invoke-Expression -Command "cmd /c rmdir /S /Q '$linkPath'";
        }
    }
    
    end {
        Write-Verbose "Shadow link and snapshot have been removed";
        return;
    }
    

    }

    These could be utilized by copy pasting both functions then running them like this

    $shadow = New-ShadowLink -Verbose;
    ls C:\ShadowCopy # would show snapshot version of c drive
    Remove-ShadowLink -shadow $shadow -Verbose;
    ls C:\ShadowCopy # will give error as it doesn't exist
    
    $s = New-ShadowLink -verbose
    VERBOSE: Creating a snapshot of C:\
    VERBOSE: Getting the full target path for a symlink to the shadow snapshot
    VERBOSE: Creating SymLink to shadowcopy at C:\ShadowCopy
    VERBOSE: Created link to shadowcopy snapshot of C:\ at C:\ShadowCopy
    VERBOSE: Returning shadowcopy snapshot object
    PS C:\> ls C:\ShadowCopy
        Directory: C:\ShadowCopy
    #ommitted my C drive listing, but it would be here
    PS C:\> Remove-ShadowLink -shadow $s -Verbose
    VERBOSE: Removing shadow copy link at C:\ShadowCopy
    VERBOSE: Deleting the shadowcopy snapshot
    VERBOSE: Deleting the now empty folder
    VERBOSE: Shadow link and snapshot have been removed
    PS C:\> ls C:\ShadowCopy
    ls : Cannot find path 'C:\ShadowCopy' because it does not exist.
    
    0 讨论(0)
  • 2020-12-08 03:45

    This is because the Invoke-Expression in the New-ShadowLink returns a string. If you modify the line to:

    Invoke-Expression -Command "cmd /c mklink /d '$linkPath' '$target'" | Out-Null
    

    it will fix the problem.

    0 讨论(0)
  • 2020-12-08 03:45

    Try replacing $shadow.Delete() with Remove-CimInstance -InputObject $shadow

    This has worked for me

    Before I was getting similar error:

    $shadow.Delete() was giving me error:

    Error en la invocación del método porque [Microsoft.Management.Infrastructure.CimInstance] no contiene ningún método llamado 'Delete'. En línea: 42 Carácter: 9 + $shadow.Delete(); + ~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (Delete:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound

    0 讨论(0)
  • 2020-12-08 03:48

    How did you create the symlink? As outlined in that article, you have to specify the device path with a trailing backslash:

    $s1 = (Get-WmiObject -List Win32_ShadowCopy).Create("C:\", "ClientAccessible")
    $s2 = Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $s1.ShadowID }
    
    $d  = $s2.DeviceObject + "\"   # <-- this here
    
    cmd /c mklink /d C:\shadowcopy "$d"
    

    After this, I was able to access the shadow copy mounted to C:\shadowcopy just fine.

    To unmount the shadow copy call $s2.Delete(), as @KeyszerS pointed out in the comments.

    0 讨论(0)
提交回复
热议问题