วิธีใช้ Volume Shadow Copy เพื่อทำการสำรองข้อมูล


11

แผนคือการสร้าง shadow copy ของ I / O-heavy ที่มีขนาดค่อนข้างใหญ่ ขนาด 350GB ประกอบด้วยดัชนี fulltext ที่ใช้ระบบไฟล์จัดอยู่ในโฟลเดอร์หลายร้อยโฟลเดอร์และไฟล์เล็ก ๆ นับแสนไฟล์ซึ่งจำเป็นต้องอยู่ในสถานะที่สอดคล้องกันเพื่อให้การกู้คืนสำเร็จ

ขณะนี้ตัวจัดทำดัชนีหยุดทำงานการสำรองข้อมูลทำงานแล้วตัวทำดัชนีเริ่มต้นใหม่ ซึ่งส่งผลให้ดัชนีไม่พร้อมใช้งานเป็นเวลาหลายชั่วโมงในระหว่างการสำรองข้อมูล ฉันต้องการสำรองข้อมูลที่สอดคล้องกันผ่าน shadow copy โดยไม่ต้องหยุดตัวทำดัชนีเลย

ดังนั้นฉันจึงเปิด Shadow Copy สำหรับไดรฟ์ข้อมูลนั้นและกำหนดค่าให้ทำสแนปช็อตหนึ่งครั้งทุกคืนเพื่อเปลี่ยนเป็นวอลลุ่มอื่น

ตอนนี้ฉันรู้สึกผิดหวังนิดหน่อย - ฉันจะเข้าถึง Shadow Copy โดยรวมได้อย่างไรเพื่อที่จะสามารถสำรองข้อมูลได้ ฉันจินตนาการถึงไดรฟ์แบบอ่านอย่างเดียวที่มีไฟล์เหมือนในเวลาที่ถ่ายภาพสแนปช็อตครั้งล่าสุด แต่บางทีสิ่งต่าง ๆ อาจแตกต่างกันโดยสิ้นเชิง

ระบบปฏิบัติการคือ Windows Server 2003 SP2 ซอฟต์แวร์สำรองข้อมูลคือ CommVault Galaxy 7.0


แก้ไข : โปรดทราบว่า - ในขณะเดียวกัน - มีการสร้างคำตอบสองข้อที่ใช้การทำงานที่จำเป็นในรูปแบบของสคริปต์:


กาแลคซี commvault ไม่ได้ใช้ VSS เพื่อสร้างการสำรองข้อมูลหรือไม่ ฉันจำได้ชัดว่า commvault เป็นหนึ่งในผู้ขายรายแรกที่ใช้โซลูชันการสำรองข้อมูลแบบ VSS
Jim B

@Jim: ใช่ แต่สำหรับไฟล์ที่ล็อคไว้แบบไฟล์ต่อไฟล์ สิ่งที่ฉันต้องการคือไฟล์ทั้งหมดในไดรฟ์ในสถานะที่สอดคล้องกัน แต่สิ่งนี้จะไม่เกิดขึ้นเว้นแต่ก) ตัวสร้างดัชนีไม่ทำงานหรือ b) ฉันมีสแน็ปช็อตสำเนาเหมือนกับที่ VSS สามารถสร้างได้
Tomalak

VSS ไม่ทำงานอย่างนั้น - เป็นสำเนาเงาของ VOLUME หากใช้ VSS ความแตกต่างเพียงอย่างเดียวคือสิ่งที่แตกต่างจากซอฟต์แวร์สำรองสแน็ปแบบถาวรของคุณจะใช้สแน็ปชั่วคราว ฉันคิดว่าแอปพลิเคชันสามารถลบสแนปชอตต่อไฟล์ แต่ไม่เพียง แต่การสำรองข้อมูลของคุณจะไม่สอดคล้องกัน แต่เวลาในการสำรองข้อมูลแม้การติดตั้งเริ่มต้นของ Windows จะเป็นไปตามลำดับของวัน ดูmsdn.microsoft.com/en-us/library/aa384589(VS.85).aspxสำหรับไดอะแกรมว่าการประมวลผล VSS ทำงานอย่างไร ฉันจะติดต่อ commvault และดูว่าพวกเขาสามารถมั่นใจได้ว่าการกำหนดค่าการสำรองข้อมูลของคุณถูกต้อง
Jim B

คำตอบ:


10

ดังนั้นด้วยจิตวิญญาณของการคิดค้นวงล้อฉันได้นำเสนอบทที่ยอดเยี่ยมของ Tomalak (ดูด้านบน) แต่เขียนใหม่ในPowershellอย่างสมบูรณ์!!! เหตุผลหลักที่ฉันทำสิ่งนี้คือเพื่อประกาศพลังอันยอดเยี่ยมของ Powershell แต่ก็เป็นเพราะฉันดูถูก vbscript ด้วยความเป็นอยู่ทั้งหมดของฉัน

ส่วนใหญ่จะเป็นคุณลักษณะที่เหมือนกัน แต่ฉันใช้บางอย่างแตกต่างกันเล็กน้อยด้วยเหตุผลต่าง ๆ เอาต์พุตการดีบักเป็น verbose มากขึ้นแน่นอน

สิ่งสำคัญอย่างหนึ่งที่ควรทราบคือเวอร์ชันนี้ตรวจพบเวอร์ชันของระบบปฏิบัติการและการเป็นพยานและเรียก 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
    • Volume Shadow Copy Service SDK 7.2
    • x86: C: \ Program Files \ Microsoft \ VSSSDK72 \ TestApps \ vshadow \ bin \ release-server \ vshadow.exe
      • เปลี่ยนชื่อเป็น: vshadow_2003_x86.exe
    • x64: ฉันไม่สามารถค้นหา vshadow.exe รุ่น x64 สำหรับ Windows 2003 x64
  2. Windows 2008
    • Windows SDK สำหรับ Windows Server 2008 และ. NET Framework 3.5
    • x86: SDK: \ Program Files \ Microsoft SDKs \ Windows \ v6.1 \ Bin \ vsstools \ vshadow.exe
      • เปลี่ยนชื่อเป็น: vshadow_2008_x86.exe
    • x64: SDK: \ 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 ไฟล์ (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ vsstools \ vshadow.exe
      • เปลี่ยนชื่อเป็น: vshadow_2008R2_x86.exe
    • x64: C: \ Program ไฟล์ (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ x64 \ vsstools \ vshadow.exe
      • เปลี่ยนชื่อเป็น: vshadow_2008R2_x64.exe

2
btw ... ฉันสามารถใช้สิ่งนี้เป็นส่วนหนึ่งของโซลูชันสำรองข้อมูลของเราโดยใช้ Arcserve เป็นไฟล์สำรองข้อมูลที่เปิดโดยคนจน จะดีกว่าการจ่าย $ 800 ต่อเซิร์ฟเวอร์สำหรับใบอนุญาตตัวแทน หากใครสนใจฉันจะโพสต์ที่นี่
John Homer

+1 นี่ช่างยอดเยี่ยมมาก ขอบคุณสำหรับการสละเวลาในการย้ายสิ่งนี้ไปยัง ps (แม้จะมีความเกลียดชัง VBS ของคุณ) และสำหรับการแบ่งปันที่นี่ ฉันหวังว่าผู้คนจำนวนมากจะพบว่ามีประโยชน์เนื่องจากนี่สมควรได้รับมากกว่าหนึ่งคะแนน
Tomalak

9

ดังนั้น…ฉันได้ทำงานกับ VBScript เล็กน้อยที่สามารถ:

  • ถ่ายรูป VSS อย่างต่อเนื่อง
  • ต่อเชื่อมเข้ากับโฟลเดอร์ (ซึ่งคุณสามารถสำรองไฟล์ได้)
  • unmount VSS snapshots

ต้องอาศัยvshadow.exe( เอกสารประกอบ ) ซึ่งเป็นส่วนหนึ่งของVolume Shadow Copy Service SDK 7.2ตามที่มีอยู่จาก Microsoft ฉันทำงานกับเวอร์ชันนี้: " VSHADOW.EXE 2.2 - ไคลเอ็นต์ตัวอย่าง Volume Shadow Copy, ลิขสิทธิ์ (C) 2005 Microsoft Corporation "

โดยทั่วไปมันเป็น wrapper เล็กน้อยเรียบร้อยรอบคำสั่ง vshadow สี่เหล่านี้:

vshadow.exe -q - แสดงรายการ Shadow Copy ทั้งหมดในระบบ
vshadow.exe -p {รายการไดรฟ์ข้อมูล} - จัดการสำเนาเงาถาวร
vshadow.exe -el = {SnapID}, dir - แสดง shadow copy เป็นจุดเชื่อมต่อ
vshadow.exe -ds = {SnapID} - ลบสำเนาเงานี้

นี่คือหน้าจอความช่วยเหลือ:

เครื่องมือสร้าง / ติดตั้ง VSS Snapshot

การใช้งาน:
cscript / nologo VssSnapshot.vbs / target: path {/ volume: X | / unmount} [/ debug]

/ volume - อักษรชื่อไดรฟ์ของไดรฟ์ข้อมูลเพื่อ snapshot
/ target - พา ธ (สัมบูรณ์หรือญาติ) เพื่อเมานต์สแนปชอต
/ debug - swich บนเอาต์พุตการดีบัก

ตัวอย่าง:
cscript / nologo VssSnapshot.vbs / target: C: \ Backup \ DriveD / ไดรฟ์ข้อมูล: D
cscript / nologo VssSnapshot.vbs / target: C: \ Backup \ DriveD / unmount

คำแนะนำ: ไม่จำเป็นต้องยกเลิกการต่อเชื่อมก่อนถ่ายภาพใหม่

ตัวอย่างผลลัพธ์ที่นี่:

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / เป้าหมาย: MountPoints \ E / ปริมาณ: E
05/03/2010 17:13:04 เตรียมจุดเมานต์ VSS ...
05/03/2010 17:13:04 น. เตรียมจุดเมานต์ที่: C: \ VssSnapshot \ MountPoints \ E
05/03/2010 17:13:04 น. สร้างสแน็ปช็อต VSS สำหรับปริมาณ: E
05/03/2010 17:13:08 สร้างสแนปชอตด้วย ID: {4ed3a907-c66f-4b20-bda0-9dcda3b667ec}
05/03/2010 17:13:08 ภาพรวม VSS ติดตั้งสำเร็จแล้ว
05/03/2010 17:13:08 นเสร็จสิ้น

C: \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target: MountPoints \ E / unmount
05/03/2010 17:13:35 เตรียมจุดเมานต์ VSS ...
05/03/2010 17:13:36 ไม่มีอะไรให้ทำอีกแล้ว
05/03/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

ฉันหวังว่านี่จะช่วยใครซักคน รู้สึกอิสระที่จะใช้ในการตามซีซีโดย-SA ทั้งหมดที่ฉันถามก็คือคุณจะต้องทิ้งลิงค์ไว้เหมือนเดิม


และคุณได้ทำการกู้คืนข้อมูลจากภัยพิบัติที่สมบูรณ์ไปสู่ระบบใหม่หรือไม่? การสำรองข้อมูลเป็นเรื่องง่าย การกู้คืนจากมันบางครั้งก็ไม่มาก
Rob Moir

@Robert: นี่เป็นความจริงสำหรับวิธีนี้เช่นเดียวกับการสำรองข้อมูลชนิดอื่น ฉันจะติดตามทันทีที่ผ่านการจัดเตรียม
Tomalak

1
+1 สำหรับการไม่ยอมรับไม่ให้คำตอบและผลักดันผ่านเพื่อพิสูจน์ว่ามีวิธีแก้ไขปัญหาที่สามารถนำเสนอได้ซึ่งผู้โพสต์อื่น ๆ บางรายอาจเสนอให้แทนที่จะตอบกลับว่าไม่สามารถทำได้
Chris Magnuson

ท้ายนี้มีการสำรองข้อมูล restorable หรือไม่? สามารถใช้กับ Robocopy ได้หรือไม่?
Kev

1
@Kev: ใช่ แต่คุณควรทดสอบด้วยตัวเองอย่างแน่นอน หากคุณพบปัญหาโปรดบอกฉันที่นี่ คุณสามารถใช้ Robocopy หรือเครื่องมืออื่น ๆ ที่คุณต้องการไดรฟ์ที่เมาท์จะทำงานเหมือนไดรฟ์ปกติ
Tomalak

6
  1. ใช้คำสั่งvssadmin list shadowsเพื่อแสดงรายการ Shadow Copy ที่มีอยู่ทั้งหมด คุณจะได้ผลลัพธ์เช่นนี้ ...
C: \> vssadmin รายการเงา
vssadmin 1.1 - เครื่องมือบรรทัดคำสั่งการจัดการ Volume Shadow Copy Service
(C) ลิขสิทธิ์ 2001 Microsoft Corp.

เนื้อหาของชุด Shadow Copy ID: {b6f6fb45-bedd-4b77-8f51-14292ee921f3}
   มีสำเนาเงา 1 ชุด ณ เวลาที่สร้าง: 9/25/2016 12:14:23 PM
      ID สำเนาเงา: {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 Provider 1.0'
         ประเภท: ClientAccessible
         คุณสมบัติ: ต่อเนื่อง, เข้าถึงลูกค้าได้, ไม่ปล่อยอัตโนมัติ, ไม่มีตัวเขียน, ต่างกัน

เนื้อหาของชุดสำเนาเงา ID: {c4fd8646-57b3-4b39-be75-47dc8e7f881d}
   มีสำเนาเงา 1 ชุดในขณะสร้าง: 8/25/2016 7:00:18 AM
      ID สำเนาเงา: {fa5da100-5d90-493c-89b1-5c27874a23c6}
         ปริมาณดั้งเดิม: (E:) \\? \ ปริมาณ {4ec17949-12b6-11de-8872-00235428b661} \
         ปริมาณสำเนาเงา: \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy3
         เครื่องกำเนิด: joshweb.josh.com
         บริการเครื่อง: joshweb.josh.com
         ผู้ให้บริการ: 'Microsoft Software Shadow Copy Provider 1.0'
         ประเภท: ClientAccessible
         คุณสมบัติ: ต่อเนื่อง, เข้าถึงลูกค้าได้, ไม่ปล่อยอัตโนมัติ, ไม่มีตัวเขียน, ต่างกัน

ค:\
  1. บันทึกShadow Copy Volumeชื่อสำหรับสำเนาเงาที่คุณต้องการ (ง่ายที่สุดไปยังคลิปบอร์ด)

  2. เมานต์ Shadow Copy

บน Windows 2003 ...

คุณจะต้องดาวน์โหลดเครื่องมือชุดทรัพยากรสำหรับปี 2003หากคุณยังไม่มี

ป้อนคำสั่ง ...

linkd c: \ shadow \\? \ GLOBALROOT \ อุปกรณ์ \ HarddiskVolumeShadowCopy69 \

... ซึ่งc:\shadowเป็นเส้นทางที่คุณต้องการให้ shadow copy ปรากฏและ\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69เป็นชื่อที่คุณคัดลอกด้านบน โปรดทราบว่าคุณต้องเพิ่มแบ็กสแลชที่ส่วนท้ายของชื่อ shadow copy!

ใน Windows 2008 ขึ้นไป ...

ป้อนคำสั่ง ...

mklink c: \ shadow \\? \ GLOBALROOT \ อุปกรณ์ \ HarddiskVolumeShadowCopy69 \

... ซึ่งc:\shadowเป็นเส้นทางที่คุณต้องการให้ shadow copy ปรากฏและ\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy69เป็นชื่อที่คุณคัดลอกด้านบน โปรดทราบว่าคุณต้องเพิ่มแบ็กสแลชที่ส่วนท้ายของชื่อ shadow copy!

  1. ใช้สิ่งที่คุณต้องการเครื่องมือ (รวมถึง Windows Explorer หรือXCOPY) c:\shadowในการเข้าถึงไฟล์จาก

ดังนั้น ... ในการทำสิ่งนี้โดยอัตโนมัติคุณจะต้องแยกวิเคราะห์ผลลัพธ์จากlist shadowsไหน?
Kev

ฉันชอบคำตอบนี้ แต่มันก็ไม่ได้ผลสำหรับฉันเมื่อติดตั้ง \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy_n_ แทนฉันใช้ไฟล์อ้างอิงและเวลาสแน็ปช็อตจากส่วนแบ่งหลัก (C $ เป็นต้น) mklink / DD: \ TempMount \\ localhost \ C $ \ @ GMT-2011.01.01-06.00.08 - น่าเสียดายที่นี่น่าจะเป็นกระบวนการแบบแมนนวล แต่สำหรับกรณีฉุกเฉินมันใช้งานได้
Lewis

2

คุณเข้าใจผิดว่า VSS ทำงานกับระบบไฟล์อย่างไร (วิธีการทำงานกับฐานข้อมูลแตกต่างอย่างสิ้นเชิง) บนระบบไฟล์ VSS ใช้เพื่อใช้คุณสมบัติ "รุ่นก่อนหน้า" ซึ่งใช้สำหรับถ่ายภาพการเปลี่ยนแปลงไฟล์และโฟลเดอร์ตามจุดที่กำหนดไว้ล่วงหน้าในเวลาสำหรับการกู้คืนผ่านแท็บเวอร์ชันก่อนหน้าในไคลเอนต์ การเปลี่ยนแปลงเหล่านี้จะถูกรวมเข้ากับข้อมูลบนโวลุ่มเพื่อสร้างชุดการกู้คืน ดังนั้นจึงขึ้นอยู่กับปริมาณดั้งเดิมที่ยังคงอยู่เพื่อดำเนินการกู้คืนซึ่งกล่าวอีกนัยหนึ่งก็ไม่มีประโยชน์สำหรับวัตถุประสงค์ในการสำรองและกู้คืน

ฉันคิดว่าคุณต้องถอยกลับจากวิธีที่คุณต้องการทำสิ่งนี้และคิดอีกครั้งเกี่ยวกับสิ่งที่คุณต้องการทำ

ข้อมูล 350 GB มีจำนวนไม่มากนักและฉันยินดีที่จะเดิมพันว่าเปอร์เซ็นต์ของข้อมูลที่ได้รับการใช้งานในแต่ละวันนั้นค่อนข้างต่ำ คุณได้พิจารณาทำการสำรองข้อมูลต่างทุกคืนด้วยการสำรองข้อมูลเต็มรูปแบบเฉพาะวันหยุดสุดสัปดาห์หรือไม่ หรือใช้การจำลองแบบ DFS ตามกำหนดเวลาไปยังที่เก็บข้อมูลสำรองเพื่อรับ "ภาพรวม" (ซึ่งสำรองไว้แล้ว)?


จำนวนการเปลี่ยนแปลงประมาณ 60GB ต่อวันในแง่ของการสำรองข้อมูลที่แตกต่างกัน การหยุดทำงานของบริการปกตินานพอที่จะรบกวนผู้ใช้เป็นครั้งคราวอาจจะ "ชั่วโมง" เกินจริงไปหน่อย จุดของฉันคือ - เมื่อฉันสำรอง VSS snapshot ไปยังเทปจากนั้นฉันมีทุกสิ่งที่ฉันต้องการคืนค่าข้อมูลสำเร็จ ฉันกำลังทำงานกับสคริปต์ที่ทำในสิ่งที่ฉันต้องการในขณะนี้มันดูค่อนข้างสดใส ฉันจะโพสต์ไว้ที่นี่เมื่อเสร็จแล้ว
Tomalak

@mh: ฉันโพสต์สคริปต์แล้ว มันใหญ่ขึ้นเล็กน้อยกว่าที่ฉันตั้งใจ แต่มันใช้งานได้ดีและใช้งานได้สะดวก มาดูกัน! :)
Tomalak

1
-1 คุณตีความคำถามผิด เขาไม่ได้พยายามใช้ VSS เป็นแหล่งข้อมูลสำรองเขาพยายามใช้มันเพื่อสร้างจุดอ่านอย่างเดียวในเวลาที่ไฟล์ของเขาสามารถถ่ายโอนไปยังเทปไดรฟ์หรือสื่ออื่น ๆ ฉันไม่เข้าใจว่าทำไมนี่จึงไม่ใช่กรณีการใช้ที่ยอดเยี่ยมสำหรับเทคโนโลยีนี้
Chris Magnuson

2

หวังว่านี่คือสิ่งที่คุณต้องการ:

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

diskshadow เป็น Windows Server 2008, AFAIK
Tomalak

@jackbean: ฉันได้สร้างสคริปต์ที่คล้ายกับ Windows 2003 เนื่องจากฉันไม่พบสิ่งใดที่น่าเชื่อถือบนอินเทอร์เน็ตจนถึงตอนนี้ ดูคำตอบของฉัน
Tomalak

ขอโทษฉันรู้ว่ามันเป็น 2008 แต่อย่างใดฉันมีมันในหัวของฉันคุณมี 2008 R2
jackbean

0

การใช้ VSS API เป็นไปได้ที่จะใช้ "สแนปชอต" ของโวลุ่ม จากนั้นคุณจะต้องติดภาพรวมนั้นเพื่อคัดลอกจากมัน ฉันคุ้นเคยกับผลิตภัณฑ์ที่ตายแล้วซึ่งใช้เทคนิคนี้ในการทำซ้ำข้อมูลแม้ไฟล์จะถูกเปิดโดยกระบวนการอื่นในระบบไฟล์สด คำถามที่ถูกต้องสามารถถามได้ว่าไฟล์ในสแน็ปช็อต VSS นั้นสอดคล้องกันหรือไม่หากพวกเขาถูกเขียนโดยแอพที่ไม่ได้รวมเข้ากับ VSS API อาจมีผลิตภัณฑ์อื่นที่เสนอความสามารถที่คล้ายกัน


@ เฟรด: นั่นคือสิ่งที่ฉันทำโดยใช้ VBScript และเครื่องมือบรรทัดคำสั่งของ Microsoft ดูคำตอบของฉัน
Tomalak

-1

คำตอบสั้น ๆ : คุณทำไม่ได้

คำตอบที่ยาวขึ้นอีกเล็กน้อย: บริการ shadow copy สามารถใช้โดยทางโปรแกรมผ่าน API เพื่ออนุญาตให้สำรองไฟล์ที่เปิดอยู่ แต่บริการไม่ได้สร้างสแนปชอตที่สมบูรณ์ของระบบเพียงสแน็ปช็อตบางส่วนเท่านั้น


2
ฉันปฏิเสธที่จะเชื่อว่านี่เป็นไปไม่ได้ ฉันไม่ต้องการ "สแน็ปช็อตของระบบ" ที่สมบูรณ์เพียงสำเนาในเวลาเดียวของโวลุ่มเดียว ฉันรู้อย่างคร่าว ๆ ว่า shadow copy ทำงานอย่างไรภายในและฉันรู้ว่ามันสามารถใช้เพื่อทำการสำรองข้อมูลของไฟล์ที่ใช้งานอยู่ (ตัวอย่างที่เด่นชัดในเน็ตคือฐานข้อมูล Exchange หรือ SQL)
Tomalak

1
@ จอห์น: ปรากฎว่าฉันสามารถ ดูคำตอบของฉัน!
Tomalak

ฉันเห็นว่าคุณกำลังใช้ API เหมือนกับซอฟต์แวร์สำรองข้อมูล ดังนั้นในขณะที่คุณใช้บริการ VSS มันค่อนข้างแตกต่างจากการใช้ Volume Shadow Copy อย่างไรก็ตามหากทำในสิ่งที่คุณต้องการนั่นคือทั้งหมดที่สำคัญจริงๆ ทำได้ดี.
John Gardeniers

1
คำตอบสั้นและยาวของคุณทั้งผิดและคำว่า "Volume Shadow Copy" นั้นเพียงพอที่จะระบุสิ่งที่ผู้ใช้มองหาแม้ว่าคำนี้จะคลุมเครือเล็กน้อย en.wikipedia.org/wiki/Shadow_Copy
Chris Magnuson

1
อาจเป็นสิทธิของคุณ ฉันไม่เข้าใจว่าคำตอบของคุณ "คุณไม่สามารถ" ถูกต้องเมื่อ OP พบวิธีที่จะทำสิ่งที่เขาอธิบาย คำตอบยาว ๆ ของคุณไม่เกี่ยวข้องกับคำถามที่ถามเพราะถึงแม้ api จะอนุญาตเฉพาะ "สแนปชอตบางส่วน" คุณยังสามารถเมานต์เสียงทั้งหมดในเวลาและสำรองตามที่ต้องการ หากคุณสามารถชี้แจงสิ่งที่คุณหมายถึงในโพสต์ต้นฉบับของคุณเพื่อให้มีการแก้ไขเพื่อระบุสิ่งที่ OP สามารถทำได้ฉันจะลบการลงคะแนนอย่างมีความสุขและเพิ่ม upvoate หากข้อมูลมีความเกี่ยวข้อง
Chris Magnuson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.