Cara menggunakan Volume Shadow Copy untuk membuat cadangan

11

Rencananya adalah untuk membuat salinan bayangan volume yang cukup besar, I / O-berat. Ini 350GB, berisi indeks fulltext berbasis sistem file yang diatur dalam ratusan folder dan ratusan ribu file kecil yang harus dalam keadaan konsisten untuk pemulihan yang berhasil.

Saat ini pengindeks dihentikan, tugas cadangan berjalan, dan kemudian pengindeks dimulai kembali. Ini menghasilkan indeks yang tidak tersedia selama berjam-jam selama pencadangan. Saya ingin membuat cadangan yang konsisten melalui salinan bayangan, idealnya tanpa harus menghentikan pengindeks sama sekali.

Jadi, saya telah mengaktifkan Shadow Copy untuk volume itu dan mengkonfigurasinya untuk membuat snapshot sekali setiap malam, ke volume yang berbeda.

Sekarang saya sedikit bingung - bagaimana saya bisa mengakses salinan bayangan secara keseluruhan, sehingga saya bisa membuat cadangan? Saya membayangkan drive baca-saja yang berisi file seperti pada saat snapshot terakhir, tetapi mungkin hal-hal bekerja sama sekali berbeda.

OS adalah Windows Server 2003 SP2, perangkat lunak cadangan adalah CommVault Galaxy 7.0.


EDIT : Perhatikan bahwa - sementara itu - dua jawaban telah dibuat yang mengimplementasikan fungsionalitas yang diperlukan dalam bentuk skrip:

Tomalak
sumber
Bukankah commvault galaxy sudah menggunakan VSS untuk membuat cadangan? Samar-samar saya ingat bahwa commvault adalah salah satu vendor pertama yang mengimplementasikan solusi cadangan berbasis VSS
Jim B
@ Jim: Ya, tetapi hanya untuk file yang dikunci berdasarkan file-ke-file. Yang saya butuhkan adalah semua file pada drive dalam keadaan konsisten. Tapi ini tidak akan terjadi kecuali a) pengindeks tidak berjalan atau b) Saya memiliki salinan snapshot, seperti yang dapat dibuat VSS.
Tomalak
VSS tidak berfungsi seperti itu - ini adalah salinan bayangan VOLUME. Jika menggunakan VSS, satu-satunya perbedaan adalah bahwa tidak seperti perangkat lunak cadangan Anda yang gigih menggunakan snap sementara. Saya kira aplikasi dapat mengambil snapshot hapus berdasarkan per file tetapi tidak hanya cadangan Anda tidak konsisten tetapi waktu untuk membuat cadangan bahkan menginstal windows standar akan sesuai urutan hari. Lihat msdn.microsoft.com/en-us/library/aa384589(VS.85).aspx untuk diagram tentang cara kerja pemrosesan VSS. Saya akan menghubungi commvault dan melihat apakah mereka dapat memastikan konfigurasi cadangan Anda sudah benar.
Jim B

Jawaban:

10

Jadi dengan semangat menciptakan kembali roda, saya sajikan kepada Anda naskah Tomalak yang sangat bagus (lihat di atas) tetapi sepenuhnya ditulis ulang dalam Powershell !!! Alasan utama saya melakukan ini adalah untuk menginjili kekuatan Powershell yang luar biasa, tetapi juga karena saya membenci vbscript dengan seluruh keberadaan saya.

Ini sebagian besar fitur untuk fitur yang sama, tetapi saya menerapkan beberapa hal sedikit berbeda karena berbagai alasan. Output debugging pasti lebih bertele-tele.

Satu hal yang sangat penting untuk diperhatikan adalah bahwa versi ini mendeteksi versi OS dan bitness dan memanggil versi vshadow.exe yang sesuai. Saya telah menyertakan bagan di bawah ini untuk menunjukkan versi vshadow.exe mana yang akan digunakan, di mana mendapatkannya, dan apa nama mereka.


Inilah info penggunaannya:

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

Ini skripnya:

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

Berikut adalah versi vshadow.exe untuk digunakan:

  1. Windows 2003 / 2003R2
    • Layanan Volume Shadow Copy SDK 7.2
    • x86: C: \ Program Files \ Microsoft \ VSSSDK72 \ TestApps \ vshadow \ bin \ release-server \ vshadow.exe
      • Ganti nama menjadi: vshadow_2003_x86.exe
    • x64: Saya belum dapat menemukan versi x64 vshadow.exe untuk Windows 2003 x64
  2. Windows 2008
    • Windows SDK untuk Windows Server 2008 dan .NET Framework 3.5
    • x86: C: \ Program Files \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ vsstools \ vshadow.exe
      • Ganti nama menjadi: vshadow_2008_x86.exe
    • x64: C: \ Program Files \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ x64 \ vsstools \ vshadow.exe
      • Ganti nama menjadi: vshadow_2008_x64.exe
  3. Windows 2008R2
    • Microsoft Windows SDK untuk Windows 7 dan .NET Framework 4
    • x86: C: \ Program Files (x86) \ Microsoft SDKs Windows \ v7.0A \ Bin \ vsstools \ vshadow.exe
      • Ganti nama menjadi: vshadow_2008R2_x86.exe
    • x64: C: \ Program Files (x86) \ Microsoft SDKs Windows \ v7.0A \ Bin \ x64 \ vsstools \ vshadow.exe
      • Ganti nama menjadi: vshadow_2008R2_x64.exe
John Homer
sumber
2
btw ... Saya bisa menerapkan ini sebagai bagian dari solusi cadangan kami menggunakan Arcserve sebagai cadangan file terbuka orang miskin. Ini lebih baik daripada membayar $ 800 per server untuk lisensi agen. Jika ada yang tertarik, saya akan memposting di sini.
John Homer
+1 Ini sangat menakjubkan. Terima kasih telah meluangkan waktu untuk port ini ke ps (terlepas dari kebencian Anda pada VBS) dan untuk berbagi di sini. Saya berharap lebih banyak orang akan merasakan manfaatnya, karena ini jelas layak mendapatkan lebih dari satu suara.
Tomalak
9

Jadi ... Saya telah mengerjakan VBScript kecil yang dapat:

  • mengambil snapshot VSS persisten
  • pasang mereka ke folder (dari mana Anda dapat membuat cadangan file)
  • lepaskan snapshot VSS

Itu bergantung pada vshadow.exe( dokumentasi ), bagian dari Volume Shadow Copy Service SDK 7.2 yang tersedia dari Microsoft. Saya telah bekerja dengan versi ini: " VSHADOW.EXE 2.2 - klien sampel Salin Volume Shadow, Hak Cipta (C) 2005 Microsoft Corporation. "

Pada dasarnya, ini adalah pembungkus kecil yang rapi di sekitar empat perintah vshadow ini:

vshadow.exe -q - Daftar semua salinan bayangan dalam sistem
vshadow.exe -p {daftar volume} - Mengelola salinan bayangan persisten
vshadow.exe -el = {SnapID}, dir - Paparkan salinan bayangan sebagai titik pemasangan
vshadow.exe -ds = {SnapID} - Menghapus salinan bayangan ini

Ini layar bantuannya:

VSS Snapshot Buat / Pasang Alat

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

/ volume - huruf drive volume untuk snapshot
/ target - path (absolut atau relatif) untuk memasang snapshot ke
/ debug - swich pada output debug

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

Petunjuk: Tidak perlu melepas gunung sebelum mengambil snapshot baru.

Berikut beberapa contoh output:

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / volume: E
05/03/2010 17:13:04 mempersiapkan VSS mount point ...
05/03/2010 17:13:04 mount point disiapkan di: C: \ VssSnapshot \ MountPoints \ E
05/03/2010 17:13:04 membuat snapshot VSS untuk volume: E
05/03/2010 17:13:08 cuplikan dibuat dengan ID: {4ed3a907-c66f-4b20-bda0-9dcda3b667ec}
05/03/2010 17:13:08 Snapshot VSS dipasang dengan sukses
05/03/2010 17:13:08 selesai

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / unmount
05/03/2010 17:13:35 mempersiapkan VSS mount point ...
05/03/2010 17:13:36 tidak ada lagi yang bisa dilakukan
05/03/2010 17:13:36 selesai

Dan ini skripnya sendiri. Penafian yang biasa berlaku: Perangkat lunak ini disediakan apa adanya, saya tidak memberikan jaminan, gunakan dengan risiko Anda sendiri, jika ada yang rusak satu-satunya yang bisa disalahkan adalah diri Anda sendiri. Saya telah mengujinya dengan cukup teliti, dan itu bekerja dengan baik untuk saya. Jangan ragu untuk memberi tahu saya jika ada bug melalui komentar di bawah.

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

Saya harap ini membantu seseorang. Jangan ragu untuk menggunakannya sesuai dengan cc-by-sa . Yang saya minta adalah Anda membiarkan tautan itu tetap utuh yang mengarah ke sini.

Tomalak
sumber
Dan apakah Anda sudah melakukan pemulihan total bencana dari data ini ke sistem baru? Mengambil cadangan itu mudah. Memulihkannya terkadang tidak terlalu banyak.
Rob Moir
@ Robert: Ini berlaku untuk pendekatan ini dan untuk jenis cadangan lainnya. Saya akan menindaklanjuti secepat ini melalui pementasan.
Tomalak
1
1 karena tidak menerima jawaban tidak dan mendorong untuk membuktikan bahwa ada solusi yang layak di luar sana bahwa beberapa poster lain dapat menawarkan bukannya menjawab bahwa itu tidak dapat dilakukan.
Chris Magnuson
Apakah ini pada akhirnya memberikan cadangan yang dapat disimpan? Bisakah ini digunakan dengan Robocopy?
Kev
1
@Kev: Ya, tapi Anda harus mengujinya sendiri. Jika Anda menemukan masalah, tolong beri tahu saya di sini. Anda dapat menggunakan Robocopy atau alat lain yang Anda inginkan, volume yang dipasang berperilaku seperti drive normal.
Tomalak
6
  1. Gunakan perintah vssadmin list shadowsuntuk mendaftar semua salinan bayangan yang tersedia. Anda akan mendapatkan output seperti ini ...
C: \> daftar vssadmin bayangan
vssadmin 1.1 - alat command-line administrasi Volume Shadow Copy Service
(C) Hak Cipta 2001 Microsoft Corp.

Isi ID set bayangan: {b6f6fb45-bedd-4b77-8f51-14292ee921f3}
   Berisi 1 salinan bayangan pada waktu pembuatan: 9/25/2016 12:14:23 PM
      ID Salin Bayangan: {321930d4-0442-4cc6-b2aa-ec47f21d0eb1}
         Volume Asli: (C:) \\? \ Volume {ad1dd231-1200-11de-b1df-806e6f6e6963} \
         Volume Salin Shadow: \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy68
         Mesin Asal: joshweb.josh.com
         Mesin Servis: joshweb.josh.com
         Penyedia: 'Penyedia Shadow Shadow Software Microsoft 1.0'
         Jenis: ClientAccessible
         Atribut: Persisten, Dapat diakses klien, Tidak ada rilis otomatis, Tidak ada penulis, Diferensial

Isi ID set bayangan: {c4fd8646-57b3-4b39-be75-47dc8e7f881d}
   Berisi 1 salinan bayangan pada waktu pembuatan: 8/25/2016 7:00:18 AM
      ID Salin Bayangan: {fa5da100-5d90-493c-89b1-5c27874a23c6}
         Volume Asli: (E:) \\? \ Volume {4ec17949-12b6-11de-8872-00235428b661} \
         Volume Salin Shadow: \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy3
         Mesin Asal: joshweb.josh.com
         Mesin Servis: joshweb.josh.com
         Penyedia: 'Penyedia Shadow Shadow Software Microsoft 1.0'
         Jenis: ClientAccessible
         Atribut: Persisten, Dapat diakses klien, Tidak ada rilis otomatis, Tidak ada penulis, Diferensial

C: \
  1. Catat Shadow Copy Volumenama untuk salinan bayangan yang Anda inginkan (paling mudah ke clipboard).

  2. Pasang Salin Bayangan

Pada Windows 2003 ...

Anda harus mengunduh alat kit sumber daya untuk tahun 2003 jika Anda belum memilikinya.

Masukkan perintah ...

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

... di mana c:\shadowjalur di mana Anda ingin salinan bayangan muncul dan \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69adalah nama yang Anda salin di atas. Perhatikan bahwa Anda harus menambahkan garis miring terbalik di akhir nama salin bayangan!

Pada Windows 2008 dan lebih tinggi ...

Masukkan perintah ...

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

... di mana c:\shadowjalur di mana Anda ingin salinan bayangan muncul dan \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69adalah nama yang Anda salin di atas. Perhatikan bahwa Anda harus menambahkan garis miring terbalik di akhir nama salin bayangan!

  1. Gunakan alat apa pun yang Anda inginkan (termasuk windows explorer atau XCOPY) untuk mengakses file dari c:\shadow.
Tero Kilkanen
sumber
Jadi ... untuk mengotomatisasi ini, Anda perlu mem-parsing keluaran dari list shadows?
Kev
Saya suka jawaban ini tetapi tidak cukup untuk saya ketika memasang \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy_n_ Alih-alih saya menggunakan file yang dirujuk dan waktu snapshot dari share root (C $ misalnya) mklink / DD: \ TempMount \\ localhost \ C $ \ @ GMT-2011.01.01-06-06.08.08 - sayangnya ini kemungkinan merupakan proses manual tetapi untuk keadaan darurat, ini berhasil.
Lewis
2

Anda salah paham bagaimana VSS bekerja dengan filesystem (cara kerjanya dengan database adalah benar-benar berbeda). Pada sistem file, VSS digunakan untuk mengimplementasikan fitur "Versi Sebelumnya", yang hanya digunakan untuk snapshotting perubahan pada file dan folder pada titik yang telah ditentukan pada waktunya untuk pemulihan melalui tab Versi Sebelumnya di klien. Perubahan ini kemudian digabungkan dengan data pada volume untuk membangun set pemulihan. Jadi itu tergantung pada volume asli masih ada di sana untuk melakukan pemulihan, yang dengan kata lain tidak berguna untuk keperluan pencadangan dan pemulihan yang tepat.

Saya pikir Anda perlu mundur dari bagaimana Anda ingin melakukan ini dan berpikir lagi tentang apa yang ingin Anda lakukan.

350 GB data tidak banyak sebenarnya, dan saya berani bertaruh bahwa persentase yang secara aktif digunakan setiap hari cukup rendah. Sudahkah Anda mempertimbangkan untuk melakukan pencadangan diferensial malam hari dengan cadangan lengkap hanya pada akhir pekan? Atau menggunakan replikasi DFS terjadwal ke penyimpanan alternatif untuk mendapatkan "snapshot" (yang kemudian dicadangkan)?

Maximus Minimus
sumber
Jumlah perubahan adalah sekitar 60GB per hari, dalam hal cadangan diferensial. Pemadaman layanan reguler cukup lama untuk mengganggu pengguna kadang-kadang, mungkin "jam" agak berlebihan. Maksud saya adalah - ketika saya mem-backup snapshot VSS ke tape, maka saya memiliki semua yang saya butuhkan untuk mengembalikan data dengan sukses. Saya sedang mengerjakan skrip yang melakukan apa yang saya butuhkan saat ini, terlihat cukup menjanjikan. Saya akan mempostingnya di sini setelah selesai.
Tomalak
@ mh: Saya telah memposting skrip saya. Ini telah menjadi sedikit lebih besar dari yang saya inginkan, tetapi bekerja dengan baik dan nyaman untuk digunakan. Silahkan lihat! :)
Tomalak
1
-1 Anda salah menginterpretasikan pertanyaan. Dia tidak mencoba menggunakan VSS sebagai sumber cadangan, dia mencoba menggunakannya untuk membuat snapshot hanya baca titik waktu file-file nya yang kemudian dapat ditransfer ke tape drive atau media lain. Saya tidak mengerti mengapa ini bukan kasus penggunaan yang bagus untuk teknologi ini?
Chris Magnuson
2

Semoga ini yang Anda inginkan:

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
sumber
diskshadow adalah Windows Server 2008, AFAIK.
Tomalak
@ jackbean: Saya telah membuat skrip yang melakukan sesuatu yang serupa untuk Windows 2003, karena saya tidak menemukan sesuatu yang meyakinkan di Internet sejauh ini. Lihatlah jawaban saya.
Tomalak
saya minta maaf, saya sadar ini untuk 2008, tapi entah bagaimana saya memilikinya di kepala Anda, Anda memiliki 2008 R2.
jackbean
0

Menggunakan VSS API, dimungkinkan untuk mengambil "snapshot" volume. Maka Anda harus memasang snapshot itu untuk menyalinnya. Saya akrab dengan produk yang sekarang sudah mati yang menggunakan teknik ini untuk mereplikasi data meskipun file secara eksklusif dibuka oleh proses lain dalam sistem file langsung. Pertanyaan yang valid dapat diajukan tentang apakah file dalam snapshot VSS konsisten sendiri jika mereka ditulis oleh aplikasi yang tidak terintegrasi dengan API VSS. Mungkin ada produk lain yang menawarkan kemampuan serupa.

Fred
sumber
@ Fred: Itulah yang saya lakukan, menggunakan VBScript dan alat baris perintah Microsoft. Lihat jawaban saya.
Tomalak
-1

Jawaban singkat: Anda tidak bisa.

Jawaban yang sedikit lebih lama: Layanan salin bayangan dapat digunakan secara programatik melalui API-nya untuk memungkinkan membuat cadangan file yang terbuka tetapi layanan ini tidak membuat snapshot lengkap dari sistem, hanya snapshot sebagian.

John Gardeniers
sumber
2
Saya menolak untuk percaya bahwa ini tidak mungkin. Saya tidak perlu melengkapi "snapshot sistem", hanya salinan point-in-time dari volume tunggal. Saya kira-kira menyadari bagaimana copy shadow bekerja secara internal, dan saya sadar bahwa itu dapat digunakan untuk membuat backup file yang sedang digunakan (contoh-contoh utama di internet adalah database Exchange atau SQL).
Tomalak
1
@ John: Ternyata saya bisa. Lihatlah jawaban saya!
Tomalak
Saya melihat bahwa Anda menggunakan API sama seperti perangkat lunak cadangan. Jadi, saat Anda menggunakan layanan VSS itu sangat berbeda dengan menggunakan Volume Shadow Copy. Namun demikian, jika melakukan apa yang Anda inginkan, itu yang paling penting. Sudah selesai dilakukan dengan baik.
John Gardeniers
1
Jawaban pendek dan panjang Anda salah dan istilah "Volume Shadow Copy" seharusnya sudah cukup untuk menunjukkan apa yang dicari pengguna meskipun istilah ini sedikit ambigu. en.wikipedia.org/wiki/Shadow_Copy
Chris Magnuson
1
Mungkin kamu benar. Saya tidak mengerti bagaimana jawaban Anda, "Anda tidak bisa" benar ketika OP menemukan cara untuk melakukan apa yang dia jelaskan. Jawaban panjang Anda tidak relevan dengan pertanyaan yang diajukan karena meskipun api hanya memungkinkan untuk "snapshot sebagian" Anda masih dapat memasang representasi seluruh volume pada suatu titik waktu dan mendukungnya sesuai keinginan OP. Jika Anda dapat mengklarifikasi apa yang Anda maksud dalam posting asli Anda sehingga diedit untuk mengatasi apa yang OP dapat capai, saya dengan senang hati akan menghapus suara turun dan menambahkan upvoate jika informasi tersebut relevan.
Chris Magnuson