如何使用卷影复制进行备份

如何使用卷影复制进行备份

计划是创建一个相当大的 I/O 密集型卷的影子副本。它有 350GB,包含基于文件系统的全文索引,该索引组织在数百个文件夹中,还有数十万个小文件,这些文件需要保持一致的状态才能成功恢复。

目前,索引器已停止,备份任务已运行,然后索引器已重新启动。这导致索引在备份期间数小时不可用。我希望通过影子副本进行一致的备份,理想情况下根本不需要停止索引器。

因此,我打开了该卷的卷影复制并将其配置为每晚对不同的卷进行一次快照。

现在我有点不知所措 - 我如何才能访问整个卷影副本,以便进行备份?我设想了一个只读驱动器,其中包含上次快照时的文件,但事情可能完全不同。

操作系统是Windows Server 2003 SP2,备份软件是CommVault Galaxy 7.0。


编辑:请注意 - 与此同时 - 已经创建了两个答案,以脚本的形式实现必要的功能:

答案1

因此,本着重新发明轮子的精神,我向你介绍了 Tomalak 的优秀脚本(见上文),但完全重写了电源外壳!!! 我这样做的主要原因是为了宣传 Powershell 的强大功能,也是因为我全身心地鄙视 vbscript。

它的大部分功能都相同,但出于各种原因,我确实实现了一些略有不同的功能。调试输出肯定更详细。

需要注意的一件非常重要的事情是,此版本会检测操作系统版本和位数并调用适当版本的 vshadow.exe。我在下面附上了一个图表,以显示要使用哪些版本的 vshadow.exe、从何处获取它们以及如何命名它们。


以下是使用信息:

VssSnapshot.ps1

Description:
  Create, mount or delete a Volume Shadow Copy Service (VSS) Shadow Copy (snapshot)

Usage:
  VssSnapshot.ps1 Create -Target <Path> -Volume <Volume> [-Debug]
  VssSnapshot.ps1 Delete -Target <Path> [-Debug]

Paremeters:
  Create  - Create a snapshot for the specified volume and mount it at the specified target
  Delete  - Unmount and delete the snapshot mounted at the specified target
  -Target - The path (quoted string) of the snapshot mount point
  -Volume - The volume (drive letter) to snapshot
  -Debug  - Enable debug output (optional)

Examples:
  VssSnapshot.ps1 Create -Target D:\Backup\DriveC -Volume C
  - Create a snapshot of volume C and mount it at "D:\Backup\DriveC"

  VssSnapshot.ps1 Delete -Target D:\Backup\DriveC
  - Unmount and delete a snapshot mounted at "D:\Backup\DriveC"

Advanced:
  VssSnapshot.ps1 create -t "c:\vss mount\c" -v C -d
  - Create a snapshot of volume C and mount it at "C:\Vss Mount\C"
  - example mounts snapshot on source volume (C: --> C:)
  - example uses shortform parameter names
  - example uses quoted paths with whitespace
  - example includes debug output

脚本如下:

# VssSnapshot.ps1
# http://serverfault.com/questions/119120/how-to-use-a-volume-shadow-copy-to-make-backups/119592#119592

Param ([String]$Action, [String]$Target, [String]$Volume, [Switch]$Debug)
$ScriptCommandLine = $MyInvocation.Line
$vshadowPath = "."

# Functions
Function Check-Environment {
  Write-Dbg "Checking environment..."

  $UsageMsg = @'
VssSnapshot

Description:
  Create, mount or delete a Volume Shadow Copy Service (VSS) Shadow Copy (snapshot)

Usage:
  VssSnapshot.ps1 Create -Target <Path> -Volume <Volume> [-Debug]
  VssSnapshot.ps1 Delete -Target <Path> [-Debug]

Paremeters:
  Create  - Create a snapshot for the specified volume and mount it at the specified target
  Delete  - Unmount and delete the snapshot mounted at the specified target
  -Target - The path (quoted string) of the snapshot mount point
  -Volume - The volume (drive letter) to snapshot
  -Debug  - Enable debug output (optional)

Examples:
  VssSnapshot.ps1 Create -Target D:\Backup\DriveC -Volume C
  - Create a snapshot of volume C and mount it at "D:\Backup\DriveC"

  VssSnapshot.ps1 Delete -Target D:\Backup\DriveC
  - Unmount and delete a snapshot mounted at "D:\Backup\DriveC"

Advanced:
  VssSnapshot.ps1 create -t "c:\vss mount\c" -v C -d
  - Create a snapshot of volume C and mount it at "C:\Vss Mount\C"
  - example mounts snapshot on source volume (C: --> C:)
  - example uses shortform parameter names
  - example uses quoted paths with whitespace
  - example includes debug output
'@

  If ($Action -eq "Create" -And ($Target -And $Volume)) {
    $Script:Volume = (Get-PSDrive | Where-Object {$_.Name -eq ($Volume).Substring(0,1)}).Root
    If ($Volume -ne "") {
      Write-Dbg "Verified volume: $Volume"
    } Else {
      Write-Dbg "Cannot find the specified volume"
      Exit-Script "Cannot find the specified volume"
    }
    Write-Dbg "Argument check passed"
  } ElseIf ($Action -eq "Delete" -And $Target ) {
    Write-Dbg "Argument check passed"
  } Else {
    Write-Dbg "Invalid arguments: $ScriptCommandLine"
    Exit-Script "Invalid arguments`n`n$UsageMsg"
  }


  $WinVer = ((Get-WmiObject Win32_OperatingSystem).Version).Substring(0,3)
    Switch ($WinVer) {
    "5.2" {
      $vshadowExe = "vshadow_2003"
      $WinBit = ((Get-WmiObject Win32_Processor)[0]).AddressWidth
    }
    "6.0" {
      $vshadowExe = "vshadow_2008"
      $WinBit = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
    }
    "6.1" {
      $vshadowExe = "vshadow_2008R2"
      $WinBit = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
    }
    Default {
      Write-Dbg "Unable to determine OS version"
      Exit-Script "Unable to determine OS version"
    }
  }

  Switch ($WinBit) {
    {($_ -eq "32") -or ($_ -eq "32-bit")} {$vshadowExe += "_x86.exe"}
    {($_ -eq "64") -or ($_ -eq "64-bit")} {$vshadowExe += "_x64.exe"}
    Default {
      Write-Dbg "Unable to determine OS bitness"
      Exit-Script "Unable to determine OS bitness"
    }
  }

  $Script:vshadowExePath = Join-Path $vshadowPath $vshadowExe
  If (Test-Path $vshadowExePath) {
    Write-Dbg "Verified vshadow.exe: $vshadowExePath"
  } Else {
    Write-Dbg "Cannot find vshadow.exe: $vshadowExePath"
    Exit-Script "Cannot find vshadow.exe"
  }

  Write-Dbg "Environment ready"
}

Function Prepare-Target {
  Write-Log "Preparing target..."
  Write-Dbg "Preparing target $Target"


  If (!(Test-Path (Split-Path $Target -Parent))) {
  Write-Dbg "Target parent does not exist"
  Exit-Script "Invalid target $Target"
  }
  If ((Test-Path $Target)) {
    Write-Dbg "Target already exists"
    If (@(Get-ChildItem $Target).Count -eq 0) {
      Write-Dbg "Target is empty"
    } Else {
      Write-Dbg "Target is not empty"
      Exit-Script "Target contains files/folders"
    }
  } Else {
    Write-Dbg "Target does not exist. Prompting user..."
    $PromptYes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Create target folder"
    $PromptNo = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Do not create target folder"
    $PromptOptions = [System.Management.Automation.Host.ChoiceDescription[]]($PromptYes, $PromptNo)
    $PromptResult = $Host.UI.PromptForChoice("Create folder", "The target folder `"$target`" does not exist.`nWould you like to create the folder?", $PromptOptions, 0) 
    Switch ($PromptResult) {
      0 {
        Write-Dbg "User Accepted. Creating target..."
        $Null = New-Item -Path (Split-Path $Target -Parent) -Name (Split-Path $Target -Leaf) -ItemType "Directory"
      }
      1 {
        Write-Dbg "User declined. Exiting..."
        Exit-Script "Target does not exist"
      }
    }
  }
  Write-Log "Target ""$Target"" ready"
  Write-Dbg """$Target"" ready"
}

Function Create-Snapshot {
  Write-Log "Creating snapshot..."
  Write-Dbg "Creating snapshot of $Volume"
  $Cmd = "$vshadowExePath -p $Volume"
  $CmdResult = Run-Command $Cmd -AsString

  Write-Dbg "Snapshot created successfully"

  $SnapshotID = $CmdResult -Match 'SNAPSHOT ID = (\{[^}]{36}\})'
  If ($SnapshotID) {
    $SnapshotID = $Matches[1]
    Write-Dbg "SnapshotID: $SnapshotID"
    Write-Log "Snapshot $SnapshotID created"
  } Else {
    Write-Dbg "Unable to determine SnapshotID"
    Exit-Script "Unable to determine SnapshotID"
  }

  Return $SnapshotID
}

Function Mount-Snapshot ($SnapshotID) {
  Write-Log "Mounting snapshot..."
  Write-Dbg "Mounting $SnapshotID at ""$Target"""

  $Cmd = "$vshadowExePath `"-el=$SnapshotId,$Target`"" #Must use escaped quotes because Invoke-Expression gets all weird about curly braces
  $CmdResult = Run-Command $Cmd

  Write-Log "Snapshot $SnapshotID mounted at target ""$Target"""
  Write-Dbg "$SnapshotID mounted at ""$Target"""
}

Function Delete-Snapshot {
  Write-Log "Deleting snapshot..."
  Write-Dbg "Deleting snapshot at target ""$Target"""

  $SnapshotID = Get-SnapshotIdbyTarget

  $Cmd = "$vshadowExePath `"-ds=$SnapshotId`""
  $CmdResult = Run-Command $Cmd

  Write-Log "Snapshot $SnapshotID deleted at target ""$Target"""
  Write-Dbg "$SnapshotID deleted at ""$Target"""
}

Function Get-SnapshotIdbyTarget {
  Write-Dbg "Finding SnapshotID for $Target"

  $Cmd = "$vshadowExePath -q"
  $CmdResult = Run-Command $Cmd -AsString

  $TargetRegEx = '(?i)' + $Target.Replace('\','\\') + '\\?\r'
  $Snapshots = ($CmdResult.Split('*')) -Match $TargetRegEx | Out-String

  If ($Snapshots) {
    $Null = $Snapshots -Match '(\{[^}]{36}\})'
    $SnapshotID = $Matches[0]
  } Else {
    Write-Dbg "Unable to determine SnapshotID for target $Target"
    Exit-Script "Unable to determine SnapshotID"
  }  

  Write-Dbg "SnapshotID: $SnapshotID"

  Return $SnapshotID
}

Function Run-Command ([String]$Cmd, [Switch]$AsString=$False, [Switch]$AsArray=$False) {
  Write-Dbg "Running: $Cmd"

  $CmdOutputArray = Invoke-Expression $Cmd
  $CmdOutputString = $CmdOutputArray | Out-String
  $CmdErrorCode = $LASTEXITCODE

  If ($CmdErrorCode -eq 0 ) {
    Write-Dbg "Command successful. Exit code: $CmdErrorCode"
    Write-Dbg $CmdOutputString
  } Else {
    Write-Dbg "Command failed. Exit code: $CmdErrorCode"
    Write-Dbg $CmdOutputString
    Exit-Script "Command failed. Exit code: $CmdErrorCode"
  }

  If (!($AsString -or $AsArray)) {
    Return $CmdErrorCode
  } ElseIf ($AsString) {
    Return $CmdOutputString
  } ElseIf ($AsArray) {
    Return $CmdOutputArray
  }
}

Function Write-Msg ([String]$Message) {
  If ($Message -ne "") {
    Write-Host $Message
  }
}

Function Write-Log ([String]$Message) {
  Write-Msg "[$(Get-Date -Format G)] $Message"
}

Function Write-Dbg ([String]$Message) {
  If ($Debug) {
    Write-Msg ("-" * 80)
    Write-Msg "[DEBUG] $Message"
    Write-Msg ("-" * 80)
  }
}

Function Exit-Script ([String]$Message) {
  If ($Message -ne "") {
    Write-Msg "`n[FATAL ERROR] $Message`n"
  }
  Exit 1
}

# Main
Write-Log "VssSnapshot started"
Check-Environment

Switch ($Action) {
  "Create" {
    Prepare-Target
    $SnapshotID = Create-Snapshot
    Mount-Snapshot $SnapshotID
  }
  "Delete" {
    Delete-Snapshot
  }
}

Write-Log "VssSnapshot finished"

以下是要使用的 vshadow.exe 版本:

  1. Windows 2003/2003R2
    • 卷影复制服务 SDK 7.2
    • x86:C:\Program Files\Microsoft\VSSSDK72\TestApps\vshadow\bin\release-server\vshadow.exe
      • 重命名为:执行文件
    • x64:我无法找到适用于 Windows 2003 x64 的 x64 版本的 vshadow.exe
  2. Windows 2008
    • 适用于 Windows Server 2008 和 .NET Framework 3.5 的 Windows SDK
    • x86:C:\Program Files\Microsoft SDKs\Windows\v6.1\Bin\vsstools\vshadow.exe
      • 重命名为:执行文件
    • x64:C:\Program Files\Microsoft SDKs\Windows\v6.1\Bin\x64\vsstools\vshadow.exe
      • 重命名为:执行文件
  3. Windows 2008R2
    • 适用于 Windows 7 和 .NET Framework 4 的 Microsoft Windows SDK
    • x86:C:\Program 文件(x86)\Microsoft SDKs\Windows\v7.0A\Bin\vsstools\vshadow.exe
      • 重命名为:执行文件
    • x64:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64\vsstools\vshadow.exe
      • 重命名为:执行文件

答案2

所以…我一直在研究一个小的 VBScript,它可以:

  • 拍摄持久 VSS 快照
  • 将它们挂载到一个文件夹(然后您可以从中备份文件)
  • 卸载 VSS 快照

它依赖于vshadow.exe文档), 的一部分卷影复制服务 SDK 7.2可从 Microsoft 获取。我一直在使用这个版本:”VSHADOW.EXE 2.2 – 卷影复制示例客户端,版权所有 (C) 2005 Microsoft Corporation。

基本上,它是这四个 vshadow 命令的一个简洁的小包装:

vshadow.exe -q – 列出系统中的所有卷影副本
vshadow.exe -p {volume list} - 管理持久卷影副本
vshadow.exe -el={SnapID},dir - 将卷影副本公开为挂载点
vshadow.exe -ds={SnapID} - 删除此卷影副本

这是它的帮助屏幕:

VSS 快照创建/挂载工具

用法:
cscript /nologo VssSnapshot.vbs /target:path { /volume:X | /unmount } [/debug]

/volume - 要快照的卷的驱动器号
/target - 快照挂载到的路径(绝对或相对)
/debug-打开调试输出

例子:
cscript /nologo VssSnapshot.vbs /target:C:\Backup\DriveD /volume:D
cscript /nologo VssSnapshot.vbs /target:C:\Backup\DriveD /unmount

提示:拍摄新快照之前无需卸载。

这里是一些示例输出:

C:\VssSnapshot>cscript /nologo VssSnapshot.vbs /target:MountPoints\E /volume:E
2010 年 5 月 3 日 17:13:04 准备 VSS 挂载点...
2010 年 5 月 3 日 17:13:04 已准备好装载点:C:\VssSnapshot\MountPoints\E
2010 年 5 月 3 日 17:13:04 为卷创建 VSS 快照:E
2010 年 5 月 3 日 17:13:08 快照创建,ID:{4ed3a907-c66f-4b20-bda0-9dcda3b667ec}
2010 年 5 月 3 日 17:13:08 VSS 快照已成功安装
2010/05/03 17:13:08 完成

C:\VssSnapshot>cscript /nologo VssSnapshot.vbs /target:MountPoints\E /unmount
2010 年 5 月 3 日 17:13:35 准备 VSS 挂载点...
2010 年 5 月 3 日 17:13:36 没有其他事可做
2010/05/03 17:13:36 完成

这是脚本本身。适用通常的免责声明:软件按原样提供,我不提供任何保证,使用风险自负,如果出现问题,只能怪您自己。不过,我已经对它进行了彻底的测试,它对我来说运行良好。请随时通过下面的评论通知我任何错误。

''# VssSnapshot.vbs
''# http://serverfault.com/questions/119120/how-to-use-a-volume-shadow-copy-to-make-backups/119592#119592
Option Explicit

Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")

''# -- MAIN SCRIPT -------------------------------------------
Dim args, snapshotId, targetPath, success
Set args = WScript.Arguments.Named
CheckEnvironment

Log "preparing VSS mount point..."
targetPath = PrepareVssMountPoint(args("target"))

If args.Exists("unmount") Then
  Log "nothing else to do"
ElseIf targetPath <> vbEmpty Then
  Log "mount point prepared at: " & targetPath
  Log "creating VSS snapshot for volume: " & args("volume")
  snapshotId = CreateVssSnapshot(args("volume"))

  If snapshotId <> vbEmpty Then
    Log "snapshot created with ID: " & snapshotId
    success = MountVssSnapshot(snapshotId, targetPath)
    If success Then
      Log "VSS snapshot mounted sucessfully"
    Else
      Die "failed to mount snapshot"
    End If
  Else
    Die "failed to create snapshot"
  End If
Else
  Die "failed to prepare mount point"
End If

Log "finished"

''# -- FUNCTIONS ---------------------------------------------
Function PrepareVssMountPoint(target) ''# As String
  Dim cmd, result, outArray
  Dim path, snapshot, snapshotId
  Dim re, matches, match

  PrepareVssMountPoint = VbEmpty
  target = fso.GetAbsolutePathName(target)

  If Not fso.FolderExists(fso.GetParentFolderName(target)) Then 
    Die "Invalid mount point: " & target
  End If

  ''# create or unmount (=delete existing snapshot) mountpoint
  If Not fso.FolderExists(target) Then
    If Not args.Exists("unmount") Then fso.CreateFolder target
  Else
    Set re = New RegExp
    re.MultiLine = False
    re.Pattern = "- Exposed locally as: ([^\r\n]*)"

    cmd = "vshadow -q"
    result = RunCommand(cmd, false)
    outarray = Split(result, "*")

    For Each snapshot In outArray
      snapshotId = ParseSnapshotId(snapshot)
      If snapshotId <> vbEmpty Then
        Set matches = re.Execute(snapshot)
        If matches.Count = 1 Then
          path = Trim(matches(0).SubMatches(0))
          If fso.GetAbsolutePathName(path) = target Then
            cmd = "vshadow -ds=" & snapshotId
            RunCommand cmd, true
            Exit For
          End If
        End If
      End If
    Next

    If args.Exists("unmount") Then fso.DeleteFolder target
  End If

  PrepareVssMountPoint = target
End Function

Function CreateVssSnapshot(volume) ''# As String
  Dim cmd, result

  If Not fso.DriveExists(volume) Then
    Die "Drive " & volume & " does not exist."
  End If

  cmd = "vshadow -p " & Replace(UCase(volume), ":", "") & ":"
  result = RunCommand(cmd, false)
  CreateVssSnapshot = ParseSnapshotId(result)
End Function

Function MountVssSnapshot(snapshotId, target) ''# As Boolean
  Dim cmd, result

  If fso.FolderExists(targetPath) Then
    cmd = "vshadow -el=" & snapshotId & "," & targetPath
    result = RunCommand(cmd, true)
  Else
    Die "Mountpoint does not exist: " & target
  End If

  MountVssSnapshot = (result = "0")
End Function

Function ParseSnapshotId(output) ''# As String
  Dim re, matches, match

  Set re = New RegExp
  re.Pattern = "SNAPSHOT ID = (\{[^}]{36}\})"
  Set matches = re.Execute(output)

  If matches.Count = 1 Then
    ParseSnapshotId = matches(0).SubMatches(0)
  Else
    ParseSnapshotId = vbEmpty
  End If
End Function

Function RunCommand(cmd, exitCodeOnly) ''# As String
  Dim shell, process, output

  Dbg "Running: " & cmd

  Set shell = CreateObject("WScript.Shell")

  On Error Resume Next
  Set process = Shell.Exec(cmd)
  If Err.Number <> 0 Then
    Die Hex(Err.Number) & " - " & Err.Description
  End If
  On Error GoTo 0

  Do While process.Status = 0
    WScript.Sleep 100
  Loop
  output = Process.StdOut.ReadAll

  If process.ExitCode = 0 Then 
    Dbg "OK"
    Dbg output
  Else
    Dbg "Failed with ERRORLEVEL " & process.ExitCode
    Dbg output
    If Not process.StdErr.AtEndOfStream Then 
      Dbg process.StdErr.ReadAll
    End If
  End If  

  If exitCodeOnly Then
    Runcommand = process.ExitCode
  Else
    RunCommand = output
  End If
End Function

Sub CheckEnvironment
  Dim argsOk

  If LCase(fso.GetFileName(WScript.FullName)) <> "cscript.exe" Then
    Say "Please execute me on the command line via cscript.exe!"
    Die ""
  End If

  argsOk = args.Exists("target")
  argsOk = argsOk And (args.Exists("volume") Or args.Exists("unmount"))

  If Not argsOk Then
    Say "VSS Snapshot Create/Mount Tool" & vbNewLine & _
        vbNewLine & _
        "Usage: " & vbNewLine & _
        "cscript /nologo " & fso.GetFileName(WScript.ScriptFullName) & _
          " /target:path { /volume:X | /unmount } [/debug]" & _
        vbNewLine & vbNewLine & _
        "/volume  - drive letter of the volume to snapshot" & _
        vbNewLine & _
        "/target  - the path (absolute or relative) to mount the snapshot to" & _
        vbNewLine & _
        "/debug   - swich on debug output" & _
        vbNewLine & vbNewLine & _
        "Examples: " & vbNewLine & _
        "cscript /nologo " & fso.GetFileName(WScript.ScriptFullName) & _
          " /target:C:\Backup\DriveD /volume:D" &  vbNewLine & _
        "cscript /nologo " & fso.GetFileName(WScript.ScriptFullName) & _
          " /target:C:\Backup\DriveD /unmount" & _
        vbNewLine & vbNewLine & _
        "Hint: No need to unmount before taking a new snapshot." & vbNewLine

    Die ""
  End If
End Sub

Sub Say(message)
  If message <> "" Then WScript.Echo message
End Sub

Sub Log(message)
  Say FormatDateTime(Now()) & " " & message
End Sub

Sub Dbg(message)
  If args.Exists("debug") Then 
    Say String(75, "-")
    Say "DEBUG: " & message
  End If
End Sub

Sub Die(message)
  If message <> "" Then Say "FATAL ERROR: " & message
  WScript.Quit 1
End Sub

希望这对某些人有帮助。请随意按照cc-by-sa。我只要求您保留指向此处的链接。

答案3

  1. 使用该命令vssadmin list shadows列出所有可用的卷影副本。您将获得如下输出...
C:\> vssadmin 列出阴影
vssadmin 1.1 - 卷影复制服务管理命令行工具
(C)版权所有 2001 Microsoft Corp.

卷影副本集 ID 的内容: {b6f6fb45-bedd-4b77-8f51-14292ee921f3}
   创建时包含 1 个卷影副本:2016 年 9 月 25 日下午 12:14:23
      卷影副本 ID:{321930d4-0442-4cc6-b2aa-ec47f21d0eb1}
         原始卷:(C:)\\?\Volume{ad1dd231-1200-11de-b1df-806e6f6e6963}\
         卷影复制卷:\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy68
         原始机器:joshweb.josh.com
         服务机器:joshweb.josh.com
         提供商:‘Microsoft Software Shadow Copy 提供商 1.0’
         类型:ClientAccessible
         属性:持久性、客户端可访问、无自动发布、无写入器、差异

卷影副本集 ID 的内容: {c4fd8646-57b3-4b39-be75-47dc8e7f881d}
   创建时包含 1 个卷影副本:2016 年 8 月 25 日上午 7:00:18
      卷影复制 ID: {fa5da100-5d90-493c-89b1-5c27874a23c6}
         原始卷:(E:)\\?\Volume{4ec17949-12b6-11de-8872-00235428b661}\
         卷影复制卷:\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3
         原始机器:joshweb.josh.com
         服务机器:joshweb.josh.com
         提供商:‘Microsoft Software Shadow Copy 提供商 1.0’
         类型:ClientAccessible
         属性:持久性、客户端可访问、无自动发布、无写入器、差异

C:\
  1. 记下Shadow Copy Volume您想要的卷影副本的名称(最容易保存到剪贴板)。

  2. 装载卷影副本

在 Windows 2003 上...

您需要下载2003 年资源工具包如果你还没有的话。

输入命令...

linkd c:\shadow \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69\

...其中c:\shadow是您希望卷影副本出现的路径,\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69是您上面复制的名称。请注意,您必须在卷影副本名称末尾添加一个反斜杠!

在 Windows 2008 及更高版本上...

输入命令...

mklink c:\shadow \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69\

...其中c:\shadow是您希望卷影副本出现的路径,\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69是您上面复制的名称。请注意,您必须在卷影副本名称末尾添加一个反斜杠!

  1. 使用您想要的任何工具(包括 Windows 资源管理器或XCOPY)来访问文件c:\shadow

答案4

希望这是你想要的:

diskshadow -s vssbackup.cfg

vssbackup.cfg:

set context persistent
set metadata E:\backup\result.cab
set verbose on
begin backup
     add volume C: alias ConfigVolume
     create
     EXPOSE %ConfigVolume% Y:
     # Y is your VSS drive
     # run your backup script here
     delete shadows exposed Y:
end backup

相关内容