所以……我一直在研究一个可以执行以下操作的VBScript:
- 拍摄持久的VSS快照
- 将它们安装到文件夹(然后可以从中备份文件)
- 卸载VSS快照
它依赖于vshadow.exe
(文档),它是Microsoft提供的Volume Shadow Copy Service SDK 7.2的一部分。我一直在使用以下版本:“ VSHADOW.EXE 2.2-卷影复制示例客户端,版权所有(C)2005 Microsoft Corporation。 ”
基本上,这是围绕这四个vshadow命令的简洁小包装:
vshadow.exe -q-列出系统中的所有卷影副本
vshadow.exe -p {卷列表}-管理持久卷影副本
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
05/03/2010 17:13:04为卷E创建VSS快照
2010年5月3日17:13:08创建了ID为{4ed3a907-c66f-4b20-bda0-9dcda3b667ec}的快照
05/03/2010 17:13:08 VSS快照已成功安装
2010年5月3日17:13:08完成
C:\ VssSnapshot> cscript / nologo VssSnapshot.vbs / target:MountPoints \ E / unmount
2010年5月3日17:13:35准备VSS安装点...
05/03/2010 17:13:36没什么可做的
2010年5月3日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使用它。我要问的是,您保留指向此处的链接完整无缺。