Как использовать теневую копию тома для создания резервных копий

11

План состоит в том, чтобы создать теневую копию довольно большого тома ввода-вывода. Это 350 ГБ, содержащий полнотекстовый индекс на основе файловой системы, организованный в сотни папок и сотни тысяч крошечных файлов, которые должны быть в согласованном состоянии для успешного восстановления.

В настоящее время индексатор остановлен, задание резервного копирования выполняется, а затем индексатор перезапускается. Это приводит к тому, что индекс будет недоступен в течение нескольких часов во время резервного копирования. Я хотел бы делать последовательные резервные копии с помощью теневого копирования, в идеале, без необходимости вообще останавливать индексатор.

Итак, я включил Shadow Copy для этого тома и настроил его для создания снимка раз в ночь на другой том.

Теперь я немного растерялся - как я могу получить доступ к теневой копии в целом, чтобы я мог сделать резервную копию? Я предполагаю диск только для чтения, который содержит файлы такими, какими они были во время последнего снимка, но, возможно, все работает совершенно иначе.

ОС Windows Server 2003 SP2, программное обеспечение для резервного копирования CommVault Galaxy 7.0.


РЕДАКТИРОВАТЬ : Обратите внимание, что - тем временем - были созданы два ответа, которые реализуют необходимую функциональность в виде сценария:

Томалак
источник
Разве commvault galaxy уже не использует VSS для создания резервной копии? Я смутно помню, что commvault был одним из первых поставщиков, который внедрил решение для резервного копирования на основе VSS
Джим Б
@Jim: Да, но только для заблокированных файлов на файловой основе. Что мне нужно, так это все файлы на диске в согласованном состоянии. Но этого не произойдет, если а) индексатор не запустится или б) у меня не будет моментальной копии, как те, что может сделать VSS.
Томалак
VSS так не работает - это теневая копия VOLUME. Если он использует VSS, единственное отличие состоит в том, что в отличие от вашего программного обеспечения для резервного копирования постоянных снимков временные снимки. Я предполагаю, что приложение может сделать снимки для каждого файла отдельно, но не только ваши резервные копии будут непоследовательными, но и время для резервного копирования, даже если установка Windows по умолчанию будет порядка нескольких дней. См. Msdn.microsoft.com/en-us/library/aa384589(VS.85).aspx для диаграммы того, как работает обработка VSS. Я бы связался с commvault и посмотрел, смогут ли они убедиться, что ваша конфигурация резервного копирования правильная.
Джим Би

Ответы:

10

Итак, в духе изобретения колеса, я представляю вам превосходный сценарий Томалака (см. Выше), но полностью переписанный в Powershell !!! Основная причина, по которой я это сделал, состояла в том, чтобы проповедовать удивительные силы 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
      • Переименовать в: vshadow_2003_x86.exe
    • x64: я не смог найти версию vshadow.exe для Windows 2003 x64 x64
  2. Windows 2008
    • Windows SDK для Windows Server 2008 и .NET Framework 3.5
    • x86: C: \ Program Files \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ vsstools \ vshadow.exe
      • Переименовать в: vshadow_2008_x86.exe
    • x64: C: \ Program Files \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ x64 \ vsstools \ vshadow.exe
      • Переименовать в: vshadow_2008_x64.exe
  3. Windows 2008R2
    • Microsoft Windows SDK для Windows 7 и .NET Framework 4
    • x86: C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ vsstools \ vshadow.exe
      • Переименовать в: vshadow_2008R2_x86.exe
    • x64: C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ x64 \ vsstools \ vshadow.exe
      • Переименовать в: vshadow_2008R2_x64.exe
Джон Гомер
источник
2
Кстати ... Я смог реализовать это как часть нашего решения для резервного копирования, используя Arcserve в качестве резервной копии открытого файла для бедного человека. Это лучше, чем платить 800 долларов за сервер за лицензию агента. Если кому-то интересно, я выложу здесь.
Джон Гомер
+1 Это довольно удивительно. Спасибо, что нашли время перенести это на ps (несмотря на вашу ненависть к VBS) и поделиться им здесь. Я надеюсь, что больше людей сочтут это полезным, поскольку это определенно заслуживает более одного голосования.
Томалак
9

Итак ... Я работал над небольшим VBScript, который может:

  • делать постоянные снимки VSS
  • смонтировать их в папку (из которой вы можете сделать резервную копию файлов)
  • размонтировать VSS снимки

Он опирается на vshadow.exe( документацию ), часть пакета Volume Shadow Copy Service SDK 7.2, доступного от Microsoft. Я работал с этой версией: « VSHADOW.EXE 2.2 - образец клиента Volume Shadow Copy, Copyright (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 / том: D
cscript / nologo VssSnapshot.vbs / target: C: \ Backup \ DriveD / unmount

Подсказка: не нужно размонтировать, прежде чем делать новый снимок.

Вот пример вывода:

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / том: E
03.05.2010 17:13:04 подготовка точки монтирования VSS ...
03.05.2010 17:13:04 Точка монтирования подготовлена ​​в: C: \ VssSnapshot \ MountPoints \ E
03.05.2010 17:13:04 создание снимка VSS для тома: E
03.05.2010 17:13:08 снимок создан с идентификатором: {4ed3a907-c66f-4b20-bda0-9dcda3b667ec}
03.05.2010 17:13:08 Снимок VSS успешно установлен
03.05.2010 17:13:08 закончено

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / unmount
03.05.2010 17:13:35 подготовка точки монтирования VSS ...
03.05.2010 17:13:36 больше ничего не делать
03.05.2010 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 . Все, что я прошу, это чтобы вы оставили ссылку нетронутой, которая указывает сюда.

Томалак
источник
И сделали ли вы полное аварийное восстановление данных с этого на новую систему? Делать резервную копию легко. Восстановление от этого иногда не так много.
Роб Мойр
@ Роберт: Это так же верно для этого подхода, как и для любого другого вида резервного копирования. Я буду следить, как только это через постановку.
Томалак
1
+1 за то, что не принял «нет» за ответ и настаивал на том, чтобы доказать, что существует жизнеспособное решение, которое могли бы предложить другие авторы, вместо ответа, что это невозможно сделать.
Крис Магнусон
Это в конечном итоге обеспечивает восстанавливаемую резервную копию? Может ли он быть использован с Robocopy?
Кев
1
@Kev: Да, но вы должны обязательно это проверить сами. Если вы обнаружили проблему, пожалуйста, сообщите мне здесь. Вы можете использовать Robocopy или любой другой инструмент, который вы предпочитаете, подключенный том ведет себя как обычный диск.
Томалак
6
  1. Используйте команду, vssadmin list shadowsчтобы получить список всех доступных теневых копий. Вы получите вывод, как это ...
C: \> vssadmin список теней
vssadmin 1.1 - инструмент командной строки для администрирования службы теневого копирования томов
(C) Copyright 2001 Microsoft Corp.

Содержимое идентификатора набора теневых копий: {b6f6fb45-bedd-4b77-8f51-14292ee921f3}
   Содержится 1 теневая копия во время создания: 25.09.2016 12:14:23
      Идентификатор теневой копии: {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
         Атрибуты: постоянный, доступный для клиента, без автоматического выпуска, без записи, дифференциальный

Содержимое идентификатора набора теневых копий: {c4fd8646-57b3-4b39-be75-47dc8e7f881d}
   Содержится 1 теневая копия во время создания: 25.08.2016 7:00:18
      Идентификатор теневой копии: {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 год, если у вас его еще нет.

Введите команду ...

ссылка 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 Explorer или XCOPY) для доступа к файлам c:\shadow.
Теро Килканен
источник
Итак ... чтобы автоматизировать это вам нужно проанализировать вывод list shadows?
Кев
Мне нравится этот ответ, но он не совсем подходит для меня при монтировании \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy_n_ Вместо этого я использовал указанный файл и время снимка с корневой папки (например, C $) mklink / DD: \ TempMount \\ localhost \ C $ \ @ GMT-2011.01.01-06.00.08 - к сожалению, это может быть ручной процесс, но в экстренных случаях он работает.
Льюис
2

Вы не понимаете, как VSS работает с файловой системой (как она работает с базами данных совершенно иначе). В файловой системе VSS используется для реализации функции «Предыдущие версии», которая используется исключительно для моментальных снимков изменений файлов и папок в заранее определенные моменты времени для восстановления на вкладке «Предыдущие версии» в клиентах. Затем эти изменения объединяются с данными тома для построения набора восстановления. Таким образом, для выполнения восстановления он зависит от исходного тома, который, другими словами, бесполезен для правильного резервного копирования и восстановления.

Я думаю, вам нужно отступить от того, как вы хотите это сделать, и снова подумать о том, что вы хотите сделать.

350 ГБ данных на самом деле не много, и я готов поспорить, что процент того, что активно используется на повседневной основе, довольно низок. Рассматривали ли вы делать ночные разностные резервные копии с полными резервными копиями только по выходным? Или использовать запланированную репликацию DFS в альтернативное хранилище, чтобы получить «снимок» (который затем будет скопирован)?

Максимус Минимус
источник
Количество изменений составляет около 60 ГБ в день, с точки зрения разностного резервного копирования. Регулярное прекращение обслуживания достаточно долго, чтобы время от времени раздражать пользователей, возможно, «часы» были немного преувеличены. Моя точка зрения - когда я делаю резервную копию снимка VSS на ленту, у меня есть все, что мне нужно для успешного восстановления данных. Я работаю над сценарием, который делает то, что мне нужно в данный момент, это выглядит довольно многообещающе. Я опубликую это здесь, когда закончите.
Томалак
@mh: я разместил свой сценарий. Он стал немного больше, чем я предполагал, но он хорошо работает и удобен в использовании. Взглянуть! :)
Томалак
1
-1 Вы неправильно поняли вопрос. Он не пытается использовать VSS в качестве источника резервной копии, он пытается использовать его для создания моментального снимка своих файлов, доступного только для чтения, который он затем может перенести на стример или на другой носитель. Я не понимаю, почему это не лучший вариант использования этой технологии?
Крис Магнусон
2

Надеюсь, это то, что вы хотите:

diskhadow -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
источник
diskhadow - это Windows Server 2008, AFAIK.
Томалак
@jackbean: я создал сценарий, который делает нечто подобное для Windows 2003, так как я пока не нашел ничего убедительного в Интернете. Посмотрите на мой ответ.
Томалак
Приношу свои извинения, я знаю, что это за 2008 год, но почему-то у меня это было в голове у вас 2008 R2.
бобы
0

Используя VSS API, можно сделать «снимок» тома. Затем вам нужно смонтировать этот снимок, чтобы скопировать с него. Я знаком с уже мертвым продуктом, который использовал эту технику для репликации данных, несмотря на то, что файлы открывались исключительно другими процессами в действующей файловой системе. Могут возникнуть вопросы о том, являются ли файлы в снимке VSS самосогласованными, если они пишутся приложениями, не интегрированными с API-интерфейсами VSS. Там могут быть другие продукты, которые предлагают аналогичные возможности.

Фред
источник
@Fred: Это то, что я сделал, используя VBScript и инструмент командной строки Microsoft. Смотри мой ответ.
Томалак
-1

Краткий ответ: вы не можете.

Немного более длинный ответ: сервис теневого копирования может использоваться программно через его API, чтобы разрешить резервное копирование открытых файлов, но сервис не создает полные снимки системы, только частичные снимки.

Джон Гарденье
источник
2
Я отказываюсь верить, что это невозможно. Мне не нужен полный «снимок системы», только копия на определенный момент времени одного тома. Я примерно знаю, как работает теневое копирование, и знаю, что его можно использовать для создания резервных копий используемых файлов (яркими примерами в сети являются базы данных Exchange или SQL).
Томалак
1
@ Джон: Оказывается, я могу. Посмотрите на мой ответ!
Томалак
Я вижу, что вы используете API почти так же, как и программное обеспечение для резервного копирования. Таким образом, пока вы используете сервис VSS, он сильно отличается от использования Volume Shadow Copy. Тем не менее, если он делает то, что вы хотите, это все, что действительно имеет значение. Отлично сработано.
Джон Гарденье
1
Ваш короткий и длинный ответ неверен, и термин «теневое копирование тома» должен был быть достаточным для указания того, что искал пользователь, даже если этот термин слегка двусмысленный. ru.wikipedia.org/wiki/Shadow_Copy
Крис Магнусон,
1
Может быть, ваше право. Я не понимаю, как ваш ответ «Вы не можете» является правильным, когда ОП нашел способ сделать то, что он описал. Ваш длинный ответ не имеет отношения к заданному вопросу, потому что, хотя API допускает только «частичные снимки», вы все равно можете смонтировать представление всего тома в определенный момент времени и сделать его резервную копию в соответствии с желаемым OP. Если бы вы могли уточнить, что вы имеете в виду в своем первоначальном сообщении, чтобы оно было отредактировано с учетом того, что ОП смогло выполнить, я с удовольствием уберу отрицательный голос и добавлю комментарий, если информация уместна.
Крис Магнусон