Cómo usar una instantánea de volumen para hacer copias de seguridad

11

El plan es crear una instantánea de un volumen bastante grande de E / S pesado. Tiene 350 GB y contiene un índice de texto completo basado en un sistema de archivos organizado en cientos de carpetas y cientos de miles de archivos pequeños que necesitan estar en un estado consistente para una restauración exitosa.

Actualmente, el indexador se detiene, se ejecuta la tarea de copia de seguridad y luego se reinicia el indexador. Esto hace que el índice no esté disponible durante horas durante la copia de seguridad. Me gustaría hacer copias de seguridad consistentes a través de instantáneas, idealmente sin tener que detener el indexador.

Entonces, encendí Shadow Copy para ese volumen y lo configuré para hacer una instantánea una vez por noche, a un volumen diferente.

Ahora estoy un poco perdido: ¿cómo puedo acceder a la instantánea como un todo para poder hacer una copia de seguridad? Imagino una unidad de solo lectura que contiene los archivos tal como estaban en el momento de la última instantánea, pero tal vez las cosas funcionan completamente diferentes.

El sistema operativo es Windows Server 2003 SP2, el software de respaldo es CommVault Galaxy 7.0.


EDITAR : Tenga en cuenta que, mientras tanto, se han creado dos respuestas que implementan la funcionalidad necesaria en forma de script:

Tomalak
fuente
¿Commvault galaxy ya no usa VSS para crear la copia de seguridad? Recuerdo vagamente que Commvault fue uno de los primeros proveedores en implementar una solución de respaldo basada en VSS
Jim B
@ Jim: Sí, pero solo para archivos bloqueados de archivo a archivo. Lo que necesito es que todos los archivos en el disco estén en un estado consistente. Pero esto no sucederá a menos que a) el indexador no se ejecute ob) Tengo una copia instantánea, como las que VSS puede hacer.
Tomalak
VSS no funciona así, es una instantánea de VOLUME. Si usa VSS, la única diferencia es que, a diferencia de su software de copia de seguridad de instantáneas persistentes, utiliza instantáneas temporales. Supongo que una aplicación podría tomar instantáneas de eliminación por archivo, pero no solo sus copias de seguridad serían inconsistentes, sino que el tiempo de copia de seguridad, incluso una instalación predeterminada de Windows, sería del orden de días. Consulte msdn.microsoft.com/en-us/library/aa384589(VS.85).aspx para ver un diagrama de cómo funciona el procesamiento VSS. Me pondría en contacto con commvault y vería si pueden garantizar que su configuración de copia de seguridad sea correcta.
Jim B

Respuestas:

10

Así, en el espíritu de reinventar la rueda, les presento a excelente guión de Tomalak (véase más arriba) pero completamente reescrito en Powershell !!! La razón principal por la que hice esto fue para evangelizar los asombrosos poderes de Powershell, pero también porque desprecio vbscript con todo mi ser.

En su mayoría, la característica es idéntica, pero implementé algunas cosas de manera un poco diferente por varias razones. La salida de depuración es definitivamente más detallada.

Una cosa muy importante a tener en cuenta es que esta versión detecta la versión y el bitness del sistema operativo y llama a la versión adecuada de vshadow.exe. Incluí un cuadro a continuación para mostrar qué versiones de vshadow.exe usar, dónde obtenerlas y cómo nombrarlas.


Aquí está la información de uso:

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

Aquí está el guión:

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

Estas son las versiones de vshadow.exe para usar:

  1. Windows 2003 / 2003R2
    • Servicio de instantáneas de volumen SDK 7.2
    • x86: C: \ Archivos de programa \ Microsoft \ VSSSDK72 \ TestApps \ vshadow \ bin \ release-server \ vshadow.exe
      • Cambie el nombre a: vshadow_2003_x86.exe
    • x64: no he podido localizar una versión x64 de vshadow.exe para Windows 2003 x64
  2. Windows 2008
    • Windows SDK para Windows Server 2008 y .NET Framework 3.5
    • x86: C: \ Archivos de programa \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ vsstools \ vshadow.exe
      • Cambie el nombre a: vshadow_2008_x86.exe
    • x64: C: \ Archivos de programa \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ x64 \ vsstools \ vshadow.exe
      • Cambie el nombre a: vshadow_2008_x64.exe
  3. Windows 2008R2
    • Microsoft Windows SDK para Windows 7 y .NET Framework 4
    • x86: C: \ Archivos de programa (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ vsstools \ vshadow.exe
      • Cambie el nombre a: vshadow_2008R2_x86.exe
    • x64: C: \ Archivos de programa (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ x64 \ vsstools \ vshadow.exe
      • Cambie el nombre a: vshadow_2008R2_x64.exe
John Homer
fuente
2
por cierto ... pude implementar esto como parte de nuestra solución de respaldo usando Arcserve como respaldo de archivos abiertos de un pobre. Es mejor que pagar $ 800 por servidor por la licencia de agente. Si alguien está interesado, publicaré aquí.
John Homer el
+1 Esto es bastante asombroso. Gracias por tomarse el tiempo para portar esto a ps (a pesar de su odio hacia VBS) y por compartirlo aquí. Espero que más personas lo encuentren útil, ya que esto definitivamente merece más de un voto positivo.
Tomalak
9

Entonces ... he estado trabajando en un pequeño VBScript que puede:

  • tomar instantáneas VSS persistentes
  • montarlos en una carpeta (desde la cual puede hacer una copia de seguridad de los archivos)
  • desmontar instantáneas de VSS

Se basa en vshadow.exe( documentación ), parte del SDK 7.2 del Servicio de instantáneas de volumen disponible de Microsoft. He estado trabajando con esta versión: " VSHADOW.EXE 2.2 - Cliente de muestra de Volume Shadow Copy, Copyright (C) 2005 Microsoft Corporation " .

Básicamente, es una pequeña envoltura ordenada alrededor de estos cuatro comandos vshadow:

vshadow.exe -q - Lista todas las instantáneas en el sistema
vshadow.exe -p {lista de volúmenes}: administra las instantáneas persistentes
vshadow.exe -el = {SnapID}, dir - Exponer la instantánea como punto de montaje
vshadow.exe -ds = {SnapID}: elimina esta instantánea

Aquí está su pantalla de ayuda:

Herramienta de creación / montaje de instantáneas VSS

Uso:
cscript / nologo VssSnapshot.vbs / target: ruta {/ volumen: X | / desmontar} [/ depurar]

/ volume - letra de unidad del volumen a la instantánea
/ target: la ruta (absoluta o relativa) para montar la instantánea
/ debug - swich en la salida de depuración

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

Sugerencia: no es necesario desmontar antes de tomar una nueva instantánea.

Aquí algunos resultados de muestra:

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / volume: E
05/03/2010 17:13:04 preparando el punto de montaje VSS ...
05/05/2010 17:13:04 punto de montaje preparado en: C: \ VssSnapshot \ MountPoints \ E
05/03/2010 17:13:04 creando una instantánea VSS para el volumen: E
05/05/2010 17:13:08 instantánea creada con ID: {4ed3a907-c66f-4b20-bda0-9dcda3b667ec}
05/03/2010 17:13:08 Instantánea VSS montada con éxito
05/03/2010 17:13:08 terminado

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / desmontar
05/03/2010 17:13:35 preparación del punto de montaje VSS ...
05/03/2010 17:13:36 nada más que hacer
05/03/2010 17:13:36 terminado

Y aquí está el guión en sí. Se aplica el descargo de responsabilidad habitual: el software se proporciona tal cual, no doy garantías, lo uso bajo su propio riesgo, si algo rompe, el único culpable es usted mismo. Sin embargo, lo he probado a fondo y funciona bien para mí. No dude en notificarme de cualquier error a través de los comentarios a continuación.

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

Espero que esto ayude a alguien. Siéntase libre de usarlo de acuerdo con cc-by-sa . Todo lo que pido es que dejes intacto el enlace que señala aquí.

Tomalak
fuente
¿Y ha realizado una recuperación completa ante desastres de los datos de esto en un nuevo sistema? Hacer una copia de seguridad es fácil. Restaurar a veces no tanto.
Rob Moir
@Robert: Esto es tan cierto para este enfoque como para cualquier otro tipo de copia de seguridad. Haré un seguimiento tan pronto como sea a través de la puesta en escena.
Tomalak
1
+1 por no aceptar un no por respuesta y presionar para demostrar que existe una solución viable que algunos de los otros carteles podrían haber ofrecido en lugar de responder que no se puede hacer.
Chris Magnuson
¿Esto terminó proporcionando una copia de seguridad restaurable? ¿Se podría usar con Robocopy?
Kev
1
@Kev: Sí, pero definitivamente deberías probarlo tú mismo. Si encuentra un problema, por favor dígame aquí. Puede usar Robocopy o cualquier otra herramienta que prefiera, el volumen montado se comporta como una unidad normal.
Tomalak
6
  1. Use el comando vssadmin list shadowspara enumerar todas las instantáneas disponibles. Obtendrá una salida como esta ...
C: \> vssadmin lista de sombras
vssadmin 1.1: herramienta de línea de comandos administrativa del Servicio de instantáneas de volumen
(C) Copyright 2001 Microsoft Corp.

Contenido del ID del conjunto de instantáneas: {b6f6fb45-bedd-4b77-8f51-14292ee921f3}
   Contiene 1 instantáneas en el momento de la creación: 25/09/2016 12:14:23 PM
      ID de instantáneas: {321930d4-0442-4cc6-b2aa-ec47f21d0eb1}
         Volumen original: (C:) \\? \ Volumen {ad1dd231-1200-11de-b1df-806e6f6e6963} \
         Volumen de instantáneas: \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy68
         Máquina de origen: joshweb.josh.com
         Servicio de la máquina: joshweb.josh.com
         Proveedor: 'Proveedor de instantáneas de software de Microsoft 1.0'
         Tipo: Cliente Accesible
         Atributos: Persistente, accesible para el cliente, sin lanzamiento automático, sin escritores, diferencial

Contenido del ID del conjunto de instantáneas: {c4fd8646-57b3-4b39-be75-47dc8e7f881d}
   Contiene 1 instantáneas en el momento de la creación: 25/08/2016 7:00:18 a.m.
      ID de instantáneas: {fa5da100-5d90-493c-89b1-5c27874a23c6}
         Volumen original: (E:) \\? \ Volumen {4ec17949-12b6-11de-8872-00235428b661} \
         Volumen de instantáneas: \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy3
         Máquina de origen: joshweb.josh.com
         Servicio de la máquina: joshweb.josh.com
         Proveedor: 'Proveedor de instantáneas de software de Microsoft 1.0'
         Tipo: Cliente Accesible
         Atributos: Persistente, accesible para el cliente, sin lanzamiento automático, sin escritores, diferencial

C:\
  1. Anote el Shadow Copy Volumenombre de la instantánea que desea (lo más fácil para el portapapeles).

  2. Monta la copia de la sombra

En Windows 2003 ...

Deberá descargar las herramientas del kit de recursos para 2003 si aún no lo tiene.

Ingrese el comando ...

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

... dónde c:\shadowestá la ruta donde desea que aparezca la instantánea y \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69es el nombre que copió arriba. ¡Tenga en cuenta que debe agregar una barra diagonal inversa al final del nombre de la instantánea!

En Windows 2008 y versiones posteriores ...

Ingrese el comando ...

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

... dónde c:\shadowestá la ruta donde desea que aparezca la instantánea y \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69es el nombre que copió arriba. ¡Tenga en cuenta que debe agregar una barra diagonal inversa al final del nombre de la instantánea!

  1. Use la herramienta que desee (incluido el explorador de Windows o XCOPY) para acceder a los archivos c:\shadow.
Tero Kilkanen
fuente
Entonces ... para automatizar esto, ¿necesitaría analizar la salida list shadows?
Kev
Me gusta esta respuesta, pero no lo hizo bastante trabajo para mí cuando se monta el \\ \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy_n_ En lugar de eso utiliza el tiempo de archivo y de instantáneas de referencia de la cuota de raíz (C $, por ejemplo)? MKLINK / DD: \ TempMount \\ localhost \ C $ \ @ GMT-2011.01.01-06.00.08 - desafortunadamente es probable que sea un proceso manual, pero para emergencias, funciona.
Lewis
2

No está entendiendo cómo funciona VSS con el sistema de archivos (cómo funciona con las bases de datos es completamente diferente). En el sistema de archivos, VSS se usa para implementar la función "Versiones anteriores", que se usa únicamente para capturar instantáneas de cambios en archivos y carpetas en puntos predefinidos en el tiempo para la recuperación a través de la pestaña Versiones anteriores en los clientes. Estos cambios se fusionan con los datos en el volumen para construir el conjunto de recuperación. Por lo tanto, depende del volumen original que todavía esté allí para realizar la recuperación, lo que en otras palabras es inútil a los efectos de una copia de seguridad y restauración adecuadas.

Creo que debes alejarte de cómo quieres hacer esto y volver a pensar en lo que quieres hacer.

En realidad, 350 GB de datos no son muchos, y estoy dispuesto a apostar que el porcentaje de lo que se usa activamente en el día a día es bastante bajo. ¿Ha considerado hacer copias de seguridad diferenciales nocturnas con copias de seguridad completas solo los fines de semana? ¿O utilizar la replicación DFS programada en un almacenamiento alternativo para obtener una "instantánea" (que luego se respalda)?

Maximus Minimus
fuente
La cantidad de cambios es de alrededor de 60 GB por día, en términos de una copia de seguridad diferencial. La interrupción regular del servicio es lo suficientemente larga como para molestar a los usuarios ocasionalmente, tal vez las "horas" fueron un poco exageradas. Mi punto es: cuando hago una copia de seguridad de la instantánea VSS en cinta, tengo todo lo que necesito para restaurar los datos con éxito. Estoy trabajando en un script que hace lo que necesito actualmente, parece bastante prometedor. Lo publicaré aquí cuando termine.
Tomalak
@mh: publiqué mi guión. Se ha vuelto un poco más grande de lo que pretendía, pero funciona bien y es conveniente de usar. ¡Echar un vistazo! :)
Tomalak
1
-1 Has malinterpretado la pregunta. No está tratando de usar VSS como fuente de una copia de seguridad, está tratando de usarlo para crear una instantánea de solo lectura en el tiempo de sus archivos que luego puede transferir a una unidad de cinta u otro medio. No entiendo por qué este no es un gran caso de uso para esta tecnología.
Chris Magnuson
2

Espero que esto sea lo que quieres:

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
fuente
diskshadow es Windows Server 2008, AFAIK.
Tomalak
@jackbean: he creado un script que hace algo similar para Windows 2003, ya que hasta ahora no encontré nada convincente en Internet. Mira mi respuesta.
Tomalak
Mis disculpas, soy consciente de que es para 2008, pero de alguna manera lo tenía en mi cabeza que tiene 2008 R2.
jackbean
0

Con la API de VSS, es posible tomar una "instantánea" del volumen. Entonces tendrías que montar esa instantánea para copiarla. Estoy familiarizado con un producto ahora muerto que utilizó esta técnica para replicar datos a pesar de que los archivos se abren exclusivamente por otros procesos en el sistema de archivos en vivo. Se pueden plantear preguntas válidas sobre si los archivos en la instantánea de VSS son coherentes si están escritos por aplicaciones que no están integradas con las API de VSS. Puede haber otros productos que ofrecen capacidades similares.

Fred
fuente
@Fred: Eso es lo que hice, usando un VBScript y una herramienta de línea de comandos de Microsoft. Mira mi respuesta.
Tomalak
-1

Respuesta corta: no puedes.

Respuesta un poco más larga: el servicio de instantáneas se puede utilizar mediante programación a través de su API para permitir la copia de seguridad de los archivos abiertos, pero el servicio no crea instantáneas completas del sistema, solo instantáneas parciales.

John Gardeniers
fuente
2
Me niego a creer que esto sea imposible. No necesito una "instantánea completa del sistema", solo una copia puntual de un solo volumen. Soy consciente de cómo funciona internamente la instantánea y sé que se puede usar para hacer copias de seguridad de los archivos en uso (ejemplos destacados en la red son las bases de datos Exchange o SQL).
Tomalak
1
@ John: Resulta que puedo. ¡Mira mi respuesta!
Tomalak
Veo que está utilizando la API de la misma manera que lo haría el software de respaldo. Entonces, mientras usa el servicio VSS, es bastante diferente al uso de Volume Shadow Copy. Sin embargo, si hace lo que quiere, eso es todo lo que realmente importa. Bien hecho.
John Gardeniers
1
Sus respuestas cortas y largas son incorrectas y el término "Volume Shadow Copy" debería haber sido suficiente para indicar lo que el usuario estaba buscando, incluso si este término es ligeramente ambiguo. en.wikipedia.org/wiki/Shadow_Copy
Chris Magnuson
1
Quizás tengas razón. No entiendo cómo su respuesta, "No puede" es correcta cuando el OP encontró una manera de hacer lo que describió. Su respuesta larga no es relevante para la pregunta formulada porque, aunque la API solo permite "instantáneas parciales", aún puede montar una representación de todo el volumen en un punto en el tiempo y hacer una copia de seguridad como lo desee el OP. Si pudieras aclarar lo que quieres decir en tu publicación original para que se edite para abordar lo que el OP ha podido lograr, eliminaré el voto negativo y agregaré una mejora si la información es relevante.
Chris Magnuson