Verwenden einer Volume Shadow-Kopie zum Erstellen von Backups

11

Es ist geplant, eine Schattenkopie eines ziemlich großen, E / A-lastigen Volumens zu erstellen. Es ist 350 GB groß und enthält einen dateisystembasierten Volltextindex, der in Hunderten von Ordnern und Hunderttausenden von winzigen Dateien organisiert ist, die für eine erfolgreiche Wiederherstellung in einem konsistenten Zustand sein müssen.

Derzeit wird der Indexer gestoppt, die Sicherungsaufgabe ausgeführt und der Indexer neu gestartet. Dies führt dazu, dass der Index während der Sicherung stundenlang nicht verfügbar ist. Ich möchte konsistente Backups per Schattenkopie erstellen, idealerweise ohne den Indexer jemals stoppen zu müssen.

Also habe ich Shadow Copy für dieses Volume aktiviert und es so konfiguriert, dass einmal pro Nacht ein Snapshot auf einem anderen Volume erstellt wird.

Jetzt bin ich etwas ratlos - wie kann ich auf die gesamte Schattenkopie zugreifen, um ein Backup zu erstellen? Ich stelle mir ein schreibgeschütztes Laufwerk vor, das die Dateien so enthält, wie sie zum Zeitpunkt des letzten Schnappschusses waren, aber vielleicht funktionieren die Dinge ganz anders.

Betriebssystem ist Windows Server 2003 SP2, Sicherungssoftware ist CommVault Galaxy 7.0.


BEARBEITEN : Beachten Sie, dass in der Zwischenzeit zwei Antworten erstellt wurden, die die erforderliche Funktionalität in Form eines Skripts implementieren:

Tomalak
quelle
Verwendet die Commvault-Galaxie nicht bereits VSS, um das Backup zu erstellen? Ich erinnere mich vage, dass Commvault einer der ersten Anbieter war, der eine VSS-basierte Backup-Lösung eingeführt hat
Jim B
@ Jim: Ja, aber nur für gesperrte Dateien von Datei zu Datei. Was ich brauche, sind alle Dateien auf dem Laufwerk in einem konsistenten Zustand. Dies wird jedoch nur geschehen, wenn a) der Indexer nicht ausgeführt wird oder b) ich eine Snapshot-Kopie habe, wie sie VSS erstellen kann.
Tomalak
VSS funktioniert so nicht - es ist eine VOLUME-Schattenkopie. Wenn VSS verwendet wird, besteht der einzige Unterschied darin, dass die Backup-Software für persistente Snaps temporäre Snaps verwendet. Ich nehme an, dass eine Anwendung Snapshots zum Löschen pro Datei erstellen könnte, aber nicht nur Ihre Sicherungen inkonsistent wären, sondern auch die Zeit zum Sichern selbst einer Standard-Windows-Installation in der Größenordnung von Tagen liegen würde. Unter msdn.microsoft.com/en-us/library/aa384589(VS.85).aspx finden Sie ein Diagramm zur Funktionsweise der VSS-Verarbeitung. Ich würde mich an commvault wenden und prüfen, ob Ihre Sicherungskonfiguration korrekt ist.
Jim B

Antworten:

10

Um das Rad neu zu erfinden, präsentiere ich Ihnen Tomalaks exzellentes Drehbuch (siehe oben), das jedoch vollständig in Powershell neu geschrieben wurde !!! Der Hauptgrund, warum ich das getan habe, war, die unglaublichen Kräfte von Powershell zu evangelisieren, aber auch, weil ich vbscript mit meinem ganzen Wesen verachte.

Es ist meistens ein Merkmal, das identisch ist, aber ich habe einige Dinge aus verschiedenen Gründen etwas anders implementiert. Die Debugging-Ausgabe ist definitiv ausführlicher.

Eine sehr wichtige Sache zu beachten ist, dass diese Version die Betriebssystemversion und die Bitness erkennt und die entsprechende Version von vshadow.exe aufruft. Ich habe unten eine Tabelle eingefügt, um zu zeigen, welche Versionen von vshadow.exe verwendet werden sollen, wo sie zu erhalten sind und wie sie zu benennen sind.


Hier sind die Nutzungsinformationen:

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

Hier ist das Skript:

# 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"

Hier sind die zu verwendenden Versionen von vshadow.exe:

  1. Windows 2003 / 2003R2
    • Volume Shadow Copy Service SDK 7.2
    • x86: C: \ Programme \ Microsoft \ VSSSDK72 \ TestApps \ vshadow \ bin \ release-server \ vshadow.exe
      • Umbenennen in: vshadow_2003_x86.exe
    • x64: Ich konnte keine x64-Version von vshadow.exe für Windows 2003 x64 finden
  2. Windows 2008
    • Windows SDK für Windows Server 2008 und .NET Framework 3.5
    • x86: C: \ Programme \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ vsstools \ vshadow.exe
      • Umbenennen in: vshadow_2008_x86.exe
    • x64: C: \ Programme \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ x64 \ vsstools \ vshadow.exe
      • Umbenennen in: vshadow_2008_x64.exe
  3. Windows 2008R2
    • Microsoft Windows SDK für Windows 7 und .NET Framework 4
    • x86: C: \ Programme (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ vsstools \ vshadow.exe
      • Umbenennen in: vshadow_2008R2_x86.exe
    • x64: C: \ Programme (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ x64 \ vsstools \ vshadow.exe
      • Umbenennen in: vshadow_2008R2_x64.exe
John Homer
quelle
2
Übrigens ... Ich konnte dies als Teil unserer Backup-Lösung implementieren, indem ich Arcserve als Open-File-Backup eines armen Mannes verwendete. Es ist besser, als 800 US-Dollar pro Server für die Agentenlizenz zu zahlen. Wenn jemand interessiert ist, werde ich hier posten.
John Homer
+1 Das ist ziemlich erstaunlich. Vielen Dank, dass Sie sich die Zeit genommen haben, dies auf ps zu portieren (trotz Ihres Hasses auf VBS) und es hier zu teilen. Ich hoffe, dass mehr Leute es nützlich finden, da dies definitiv mehr als eine Gegenstimme verdient.
Tomalak
9

Also ... ich habe an einem kleinen VBScript gearbeitet, das Folgendes kann:

  • Machen Sie dauerhafte VSS-Snapshots
  • Hängen Sie sie in einen Ordner ein (von dem Sie dann die Dateien sichern können).
  • Hängen Sie VSS-Snapshots aus

Es basiert auf vshadow.exe( Dokumentation ), einem Teil des von Microsoft erhältlichen Volume Shadow Copy Service SDK 7.2 . Ich habe mit dieser Version gearbeitet: " VSHADOW.EXE 2.2 - Beispielclient für Volume Shadow Copy, Copyright (C) 2005 Microsoft Corporation. "

Im Grunde ist es eine nette kleine Hülle um diese vier vshadow-Befehle:

vshadow.exe -q - Listet alle Schattenkopien im System auf
vshadow.exe -p {Datenträgerliste} - Verwaltet persistente Schattenkopien
vshadow.exe -el = {SnapID}, dir - Belichtet die Schattenkopie als Einhängepunkt
vshadow.exe -ds = {SnapID} - Löscht diese Schattenkopie

Hier ist der Hilfebildschirm:

Tool zum Erstellen / Bereitstellen von VSS-Snapshots

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

/ volume - Laufwerksbuchstabe des zu schnappenden Volumes
/ target - Der Pfad (absolut oder relativ), an den der Snapshot gemountet werden soll
/ debug - Swich bei Debug-Ausgabe

Beispiele:
cscript / nologo VssSnapshot.vbs / Ziel: C: \ Backup \ DriveD / Volume: D.
cscript / nologo VssSnapshot.vbs / target: C: \ Backup \ DriveD / unmount

Tipp: Sie müssen die Bereitstellung nicht aufheben, bevor Sie einen neuen Schnappschuss erstellen.

Hier einige Beispielausgaben:

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / Ziel: MountPoints \ E / Volume: E.
05/03/2010 17:13:04 VSS-Einhängepunkt vorbereiten ...
05/03/2010 17:13:04 Einhängepunkt vorbereitet unter: C: \ VssSnapshot \ MountPoints \ E.
05/03/2010 17:13:04 Erstellen eines VSS-Snapshots für Volume: E.
05/03/2010 17:13:08 Schnappschuss erstellt mit der ID: {4ed3a907-c66f-4b20-bda0-9dcda3b667ec}
05/03/2010 17:13:08 VSS-Snapshot erfolgreich gemountet
05/03/2010 17:13:08 fertig

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / unmount
05/03/2010 17:13:35 VSS-Einhängepunkt vorbereiten ...
05/03/2010 17:13:36 nichts anderes zu tun
05/03/2010 17:13:36 fertig

Und hier ist das Skript selbst. Es gilt der übliche Haftungsausschluss: Die Software wird unverändert zur Verfügung gestellt, ich gebe keine Gewährleistungen, die Verwendung erfolgt auf eigenes Risiko, wenn etwas kaputt geht, ist nur Sie selbst schuld. Ich habe es allerdings ziemlich gründlich getestet und es funktioniert gut für mich. Fühlen Sie sich frei, mich über Fehler in den Kommentaren unten zu benachrichtigen.

''# 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

Ich hoffe das hilft jemandem. Fühlen Sie sich frei, es in Übereinstimmung mit cc-by-sa zu verwenden . Ich bitte Sie nur, den Link intakt zu lassen, der hierher zurückführt.

Tomalak
quelle
Und haben Sie eine vollständige Notfallwiederherstellung der Daten von diesem auf einem neuen System durchgeführt? Ein Backup zu erstellen ist einfach. Wiederherstellen davon manchmal nicht so sehr.
Rob Moir
@ Robert: Dies gilt für diesen Ansatz genauso wie für jede andere Art von Sicherung. Ich werde nachverfolgen, sobald dies durch die Inszenierung erfolgt ist.
Tomalak
1
+1 für das Nicht-Akzeptieren von Nein für eine Antwort und das Durchsetzen, um zu beweisen, dass es eine praktikable Lösung gibt, die einige der anderen Poster hätten anbieten können, anstatt zu antworten, dass dies nicht möglich ist.
Chris Magnuson
Hat dies zu einem wiederherstellbaren Backup geführt? Könnte es mit Robocopy verwendet werden?
Kev
1
@ Kevin: Ja, aber du solltest es auf jeden Fall selbst testen. Wenn Sie ein Problem finden, sagen Sie es mir bitte hier. Sie können Robocopy oder ein anderes von Ihnen bevorzugtes Tool verwenden. Das bereitgestellte Volume verhält sich wie ein normales Laufwerk.
Tomalak
6
  1. Verwenden Sie den Befehl, vssadmin list shadowsum alle verfügbaren Schattenkopien aufzulisten. Sie erhalten eine Ausgabe wie diese ...
C: \> vssadmin listet Schatten auf
vssadmin 1.1 - Administratives Befehlszeilentool des Volume Shadow Copy Service
(C) Copyright 2001 Microsoft Corp.

Inhalt der ID des Schattenkopiesatzes: {b6f6fb45-bedd-4b77-8f51-14292ee921f3}
   Enthält 1 Schattenkopien zum Zeitpunkt der Erstellung: 25.09.2016 12:14:23 Uhr
      Schattenkopie-ID: {321930d4-0442-4cc6-b2aa-ec47f21d0eb1}
         Original-Volume: (C :) \\? \ Volume {ad1dd231-1200-11de-b1df-806e6f6e6963} \
         Shadow Copy Volume: \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy68
         Ursprungsmaschine: joshweb.josh.com
         Servicemaschine: joshweb.josh.com
         Anbieter: 'Microsoft Software Shadow Copy-Anbieter 1.0'
         Typ: ClientAccessible
         Attribute: Persistent, Client-zugänglich, Keine automatische Freigabe, Keine Writer, Differential

Inhalt der ID des Schattenkopiesatzes: {c4fd8646-57b3-4b39-be75-47dc8e7f881d}
   Enthält 1 Schattenkopien zum Zeitpunkt der Erstellung: 25.08.2016 07:00:18 Uhr
      Schattenkopie-ID: {fa5da100-5d90-493c-89b1-5c27874a23c6}
         Original-Volume: (E :) \\? \ Volume {4ec17949-12b6-11de-8872-00235428b661} \
         Shadow Copy Volume: \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy3
         Ursprungsmaschine: joshweb.josh.com
         Servicemaschine: joshweb.josh.com
         Anbieter: 'Microsoft Software Shadow Copy-Anbieter 1.0'
         Typ: ClientAccessible
         Attribute: Persistent, Client-zugänglich, Keine automatische Freigabe, Keine Writer, Differential

C: \
  1. Notieren Sie sich den Shadow Copy VolumeNamen für die gewünschte Schattenkopie (am einfachsten in die Zwischenablage).

  2. Hängen Sie die Schattenkopie ein

Unter Windows 2003 ...

Sie müssen die Resource Kit-Tools für 2003 herunterladen, falls Sie sie noch nicht haben.

Geben Sie den Befehl ein ...

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

... wo c:\shadowist der Pfad, in dem die Schattenkopie erscheinen soll, und \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69der Name, den Sie oben kopiert haben. Beachten Sie, dass Sie am Ende des Namens der Schattenkopie einen Backslash hinzufügen müssen !

Unter Windows 2008 und höher ...

Geben Sie den Befehl ein ...

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

... wo c:\shadowist der Pfad, in dem die Schattenkopie erscheinen soll, und \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69der Name, den Sie oben kopiert haben. Beachten Sie, dass Sie am Ende des Namens der Schattenkopie einen Backslash hinzufügen müssen !

  1. Verwenden Sie ein beliebiges Tool (einschließlich Windows Explorer oder XCOPY), um auf die Dateien zuzugreifen c:\shadow.
Tero Kilkanen
quelle
Also ... um dies zu automatisieren, müssten Sie die Ausgabe von analysieren list shadows?
Kev
Ich mag diese Antwort, aber sie hat beim Mounten von \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy_n_ nicht ganz funktioniert. Stattdessen habe ich die referenzierte Datei und die Snapshot-Zeit von der Root-Freigabe (z. B. C $) mklink / DD: \ TempMount verwendet \\ localhost \ C $ \ @ GMT-2011.01.01-06.00.08 - Leider ist dies wahrscheinlich ein manueller Vorgang, aber in Notfällen funktioniert er.
Lewis
2

Sie verstehen falsch, wie VSS mit dem Dateisystem funktioniert (wie es mit Datenbanken funktioniert, ist völlig anders). Im Dateisystem wird VSS verwendet, um die Funktion "Vorherige Versionen" zu implementieren, die ausschließlich zum Erstellen von Snapshot- Änderungen an Dateien und Ordnern zu vordefinierten Zeitpunkten für die Wiederherstellung über die Registerkarte "Vorherige Versionen" in Clients verwendet wird. Diese Änderungen werden dann mit den Daten auf dem Volume zum Erstellen des Wiederherstellungssatzes zusammengeführt. Es hängt also davon ab, ob das ursprüngliche Volume noch vorhanden ist, um die Wiederherstellung durchzuführen, was mit anderen Worten für die ordnungsgemäße Sicherung und Wiederherstellung unbrauchbar ist.

Ich denke, Sie müssen zurücktreten, wie Sie dies tun möchten, und noch einmal darüber nachdenken, was Sie tun möchten.

350 GB Daten sind nicht wirklich viel, und ich bin bereit zu wetten, dass der Prozentsatz dessen, was täglich aktiv genutzt wird, recht gering ist. Haben Sie darüber nachgedacht, nächtliche differenzielle Sicherungen mit vollständigen Sicherungen nur am Wochenende durchzuführen? Oder die geplante DFS-Replikation auf einen alternativen Speicher verwenden, um einen "Snapshot" zu erhalten (der dann gesichert wird)?

Maximus Minimus
quelle
Die Anzahl der Änderungen beträgt ungefähr 60 GB pro Tag, was eine differenzielle Sicherung betrifft. Regelmäßiger Serviceausfall ist lang genug, um Benutzer gelegentlich zu ärgern, vielleicht waren "Stunden" etwas übertrieben. Mein Punkt ist: Wenn ich den VSS-Snapshot auf Band sichere, habe ich alles, was ich brauche, um Daten erfolgreich wiederherzustellen. Ich arbeite an einem Skript, das das tut, was ich gerade brauche. Es sieht ziemlich vielversprechend aus. Ich werde es hier posten, wenn ich fertig bin.
Tomalak
@mh: Ich habe mein Skript gepostet. Es ist etwas größer geworden, als ich es beabsichtigt hatte, aber es funktioniert gut und ist bequem zu bedienen. Guck mal! :)
Tomalak
1
-1 Sie haben die Frage falsch interpretiert. Er versucht nicht, VSS als Quelle für ein Backup zu verwenden, sondern versucht, damit einen schreibgeschützten Snapshot seiner Dateien zu erstellen, den er dann auf ein Bandlaufwerk oder ein anderes Medium übertragen kann. Ich verstehe nicht, warum dies kein guter Anwendungsfall für diese Technologie ist.
Chris Magnuson
2

Hoffe das ist was du willst:

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
Jackbean
quelle
Festplattenschatten ist Windows Server 2008, AFAIK.
Tomalak
@jackbean: Ich habe ein Skript erstellt, das etwas Ähnliches für Windows 2003 tut, da ich im Internet bisher nichts Überzeugendes gefunden habe. Schau dir meine Antwort an.
Tomalak
Ich entschuldige mich, ich bin mir bewusst, dass es für 2008 ist, aber irgendwie hatte ich es in meinem Kopf, Sie haben 2008 R2.
Jackbean
0

Mit der VSS-API ist es möglich, einen "Snapshot" des Volumes zu erstellen. Dann müssten Sie diesen Snapshot mounten, um ihn zu kopieren. Ich bin mit einem inzwischen toten Produkt vertraut, das diese Technik zum Replizieren von Daten verwendete, obwohl Dateien ausschließlich von anderen Prozessen im Live-Dateisystem geöffnet wurden. Es können gültige Fragen dazu gestellt werden, ob die Dateien im VSS-Snapshot selbstkonsistent sind, wenn sie von Apps geschrieben werden, die nicht in die VSS-APIs integriert sind. Möglicherweise gibt es andere Produkte, die ähnliche Funktionen bieten.

Fred
quelle
@Fred: Das habe ich mit einem VBScript und einem Microsoft-Befehlszeilentool gemacht. Siehe meine Antwort.
Tomalak
-1

Kurze Antwort: Das kannst du nicht.

Etwas längere Antwort: Der Schattenkopiedienst kann programmgesteuert über seine API verwendet werden, um das Sichern geöffneter Dateien zu ermöglichen. Der Dienst erstellt jedoch keine vollständigen Snapshots des Systems, sondern nur teilweise Snapshots.

John Gardeniers
quelle
2
Ich weigere mich zu glauben, dass dies unmöglich ist. Ich benötige keinen vollständigen "Schnappschuss des Systems", sondern nur eine zeitpunktbezogene Kopie eines einzelnen Volumes. Ich bin in etwa weiß , wie Schattenkopie intern funktioniert, und ich bin mir bewusst , dass es kann verwendet werden , um Backups von Dateien in Gebrauch befindlichen zu machen (prominente Beispiele im Netz sind Exchange oder SQL - Datenbanken).
Tomalak
1
@ John: Es stellt sich heraus, dass ich kann. Schau dir meine Antwort an!
Tomalak
Ich sehe, dass Sie die API ähnlich wie Backup-Software verwenden. Während Sie den VSS-Dienst verwenden, unterscheidet sich dies erheblich von der Verwendung von Volume Shadow Copy. Wenn es jedoch tut, was Sie wollen, ist das alles, was wirklich zählt. Gut gemacht.
John Gardeniers
1
Ihre kurze und lange Antwort sind beide falsch und der Begriff "Volume Shadow Copy" sollte ausreichen, um anzuzeigen, wonach der Benutzer gesucht hat, auch wenn dieser Begriff etwas mehrdeutig ist. en.wikipedia.org/wiki/Shadow_Copy
Chris Magnuson
1
Vielleicht hast du recht. Ich verstehe nicht, wie Ihre Antwort "Sie können nicht" richtig ist, als das OP einen Weg gefunden hat, das zu tun, was er beschrieben hat. Ihre lange Antwort ist für die gestellte Frage nicht relevant, da Sie, obwohl die API nur "Teilschnappschüsse" zulässt, zu einem bestimmten Zeitpunkt eine Darstellung des gesamten Volumes bereitstellen und diese wie gewünscht sichern können. Wenn Sie klarstellen könnten, was Sie in Ihrem ursprünglichen Beitrag meinen, damit er bearbeitet wird, um zu klären, was das OP erreicht hat, werde ich die Abwärtsabstimmung gerne entfernen und eine Aufwertung hinzufügen, wenn die Informationen relevant sind.
Chris Magnuson