볼륨 섀도 복사본을 사용하여 백업하는 방법


11

계획은 상당히 큰 I / O가 많은 볼륨의 섀도 복사본을 만드는 것입니다. 350GB이며, 수백 개의 폴더와 수백 개의 작은 파일로 구성된 파일 시스템 기반 전체 텍스트 인덱스를 포함하며 복원이 성공하려면 일관된 상태에 있어야합니다.

현재 인덱서가 중지되고 백업 작업이 실행 된 다음 인덱서가 다시 시작됩니다. 이로 인해 백업 중에 몇 시간 동안 인덱스를 사용할 수 없습니다. 인덱서를 전혀 중지하지 않고 섀도 복사본을 통해 일관된 백업을 만들고 싶습니다.

따라서 해당 볼륨에 대한 섀도 복사본을 켜고 매일 밤마다 다른 볼륨으로 스냅 샷을 만들도록 구성했습니다.

이제 약간의 손실이 발생했습니다. 섀도 복사본에 전체적으로 액세스하여 백업을 만들 수있는 방법은 무엇입니까? 마지막 스냅 샷 당시의 파일이 포함 된 읽기 전용 드라이브를 구상했지만 완전히 다른 방식으로 작동 할 수 있습니다.

OS는 Windows Server 2003 SP2이고 백업 소프트웨어는 CommVault Galaxy 7.0입니다.


편집 : 그 동안 스크립트 형태로 필요한 기능을 구현하는 두 가지 답변이 작성되었습니다.


commvault galaxy는 이미 VSS를 사용하여 백업을 만들지 않습니까? commvault가 VSS 기반 백업 솔루션을 구현 한 최초의 공급 업체 중 하나라는 것을 모호하게 기억합니다.
Jim B

@Jim : 그렇습니다. 그러나 파일 단위로 잠긴 파일에 대해서만 가능합니다. 필요한 것은 드라이브의 모든 파일 이 일관된 상태입니다. 그러나 이것은 a) 인덱서가 실행되지 않거나 b) VSS가 만들 수있는 것과 같은 스냅 샷 복사본이없는 경우에는 발생하지 않습니다.
Tomalak

VSS는 그렇게 작동하지 않습니다. VOLUME 섀도 복사본입니다. VSS를 사용하는 경우 영구 스냅 백업 소프트웨어가 임시 스냅을 사용하는 것과 달리 차이점이 있습니다. 응용 프로그램이 파일별로 삭제 스냅 샷을 찍을 수 있지만 백업이 일치하지 않을뿐만 아니라 기본 Windows 설치조차도 백업하는 시간은 며칠 정도라고 가정합니다. VSS 처리 작동 방식에 대한 다이어그램은 msdn.microsoft.com/ko-kr/library/aa384589(VS.85).aspx 를 참조 하십시오 . commvault에 연락하여 백업 구성이 올바른지 확인할 수 있습니다.
Jim B

답변:


10

그래서 바퀴를 재발 명하는 정신으로, 나는 당신에게 Tomalak의 훌륭한 대본 (위 참조)을 제시하지만 Powershell로 완전히 다시 작성되었습니다 ! 내가이 일을 한 주된 이유는 Powershell의 놀라운 힘을 복음화하기 위해서 였지만, 내 존재 전체와 함께 vbscript를 멸시했기 때문입니다.

대부분 동일한 기능을 제공하는 기능이지만 여러 가지 이유로 약간 다르게 구현했습니다. 디버깅 출력은 확실히 더 장황합니다.

주의해야 할 중요한 사항 중 하나는이 버전이 OS 버전과 비트를 감지하고 적절한 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 : Windows 2003 x64 용 vshadow.exe의 x64 버전을 찾을 수 없습니다
  2. Windows 2008
    • Windows Server 2008 및 .NET Framework 3.5 용 Windows SDK
    • 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
    • Windows 7 및 .NET Framework 4 용 Microsoft Windows SDK
    • 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
btw ... 나는 가난한 사람의 열린 파일 백업으로 Arcserve를 사용하여 백업 솔루션의 일부로 이것을 구현할 수있었습니다. 에이전트 라이센스에 대해 서버 당 $ 800를 지불하는 것이 좋습니다. 관심있는 사람은 여기에 게시하겠습니다.
John Homer

+1 이것은 정말 놀랍습니다. 시간을 내서 ps (VBS에 대한 증오에도 불구하고)로 포팅하고 여기에서 공유해 주셔서 감사합니다. 더 많은 사람들이 유용하다고 생각할 수 있기를 바랍니다.
Tomalak

9

그래서 ... 나는 할 수있는 작은 VBScript를 연구하고 있습니다.

  • 지속적인 VSS 스냅 샷 생성
  • 파일을 폴더에 마운트 한 다음 파일을 백업 할 수 있습니다.
  • VSS 스냅 샷 마운트 해제

Microsoft에서 제공 하는 Volume Shadow Copy Service SDK 7.2의 일부인 vshadow.exe( documentation ) 에 의존합니다 . 이 버전으로 작업했습니다 : " VSHADOW.EXE 2.2-볼륨 섀도 복사본 샘플 클라이언트, 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
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
ID : {4ed3a907-c66f-4b20-bda0-9dcda3b667ec}으로 생성 된 2010 년 5 월 3 일 17:13:08 스냅 샷
05/03/2010 17:13:08 VSS 스냅 샷이 성공적으로 마운트되었습니다
05/03/2010 17:13:08 완료

C : \ VssSnapshot> cscript / nologo VssSnapshot.vbs / target : MountPoints \ E / 마운트 해제
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

나는 이것이 누군가를 돕기를 바랍니다. cc-by-sa 에 따라 자유롭게 사용하십시오 . 내가 묻는 것은 여기에있는 링크를 그대로 두는 것입니다.


그리고이 시스템에서 새로운 시스템으로 데이터를 완전히 재해 복구 했습니까? 백업은 쉽습니다. 때로는 그렇게 많이 복원하지 않습니다.
Rob Moir

@Robert : 다른 백업 종류와 마찬가지로이 방법에서도 마찬가지입니다. 준비가 완료되는대로 후속 조치하겠습니다.
Tomalak

1
+1은 대답을 거절하지 않고 다른 포스터들 중 일부는 그것을 할 수 없다고 대답하는 대신 제공 할 수있는 실행 가능한 해결책이 있음을 증명하기 위해 추진합니다.
Chris Magnuson

이로 인해 복원 가능한 백업이 제공 되었습니까? Robocopy와 함께 사용할 수 있습니까?
Kev

1
@ 케빈 : 예,하지만 직접 테스트해야합니다. 문제가 발견되면 여기로 알려주십시오. Robocopy 또는 원하는 다른 도구를 사용할 수 있습니다. 탑재 된 볼륨은 일반 드라이브처럼 작동합니다.
Tomalak

6
  1. 사용 vssadmin list shadows가능한 모든 섀도 복사본을 나열 하려면 명령 을 사용하십시오 . 다음과 같은 결과가 나옵니다.
C : \> vssadmin 목록 그림자
vssadmin 1.1-볼륨 섀도 복사본 서비스 관리 명령 줄 도구
(C) 저작권 2001 Microsoft Corp.

쉐도우 복사본 세트 ID의 내용 : {b6f6fb45-bedd-4b77-8f51-14292ee921f3}
   생성시 섀도 복사본 1 개 포함 : 2016 년 9 월 25 일 오후 12:14:23
      섀도 복사본 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 공급자 1.0'
         유형 : ClientAccessible
         속성 : 영구, 클라이언트 액세스 가능, 자동 릴리스 없음, 작성자 없음, 차이

쉐도우 복사본 세트 ID의 내용 : {c4fd8646-57b3-4b39-be75-47dc8e7f881d}
   생성시 섀도 복사본 1 개 포함 : 2016 년 8 월 25 일 7:00:18 오전
      섀도 복사본 ID : {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
         속성 : 영구, 클라이언트 액세스 가능, 자동 릴리스 없음, 작성자 없음, 차이

씨:\
  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 탐색기 또는를 포함하여 원하는 도구를 사용하여 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는 "이전 버전"기능을 구현하는 데 사용됩니다.이 기능 은 클라이언트의 이전 버전 탭을 통해 복구를 위해 미리 정의 된 시점에 파일 및 폴더의 변경 사항 을 스냅 샷하는 데만 사용됩니다 . 그런 다음 이러한 변경 사항은 복구 세트를 작성하기위한 볼륨의 데이터와 병합됩니다. 따라서 복구를 수행하기 위해 여전히 존재하는 원래 볼륨에 의존합니다. 다시 말해서 적절한 백업 및 복원을 위해 쓸모가 없습니다.

나는 당신이 이것을하고 싶은 방법에서 물러서 고 당신이하고 싶은 일에 대해 다시 생각해야한다고 생각합니다.

350GB의 데이터는 실제로 그리 많지 않으며 매일 적극적으로 사용되는 데이터의 비율이 상당히 낮습니다. 주말에만 전체 백업으로 야간 차등 백업을 수행 한 적이 있습니까? 아니면 "스냅 샷"을 얻기 위해 예약 된 DFS 복제를 대체 스토리지에 사용 하는가 (이는 백업됩니까)?


차등 백업 측면에서 하루에 약 60GB 정도의 변경이 발생합니다. 정기적 인 서비스 중단은 때때로 사용자를 성가 시게 할 정도로 길며, "시간"은 다소 과장된 것일 수 있습니다. 요점은-VSS 스냅 샷을 테이프에 백업하면 데이터를 성공적으로 복원하는 데 필요한 모든 것이 있습니다. 현재 필요한 것을 수행하는 스크립트를 작성 중입니다. 매우 유망합니다. 완료되면 여기에 게시하겠습니다.
Tomalak

@mh : 스크립트를 게시했습니다. 의도했던 것보다 약간 커졌지 만 잘 작동하고 사용하기 편리합니다. 보세요! :)
Tomalak

1
-1 질문을 잘못 해석했습니다. VSS를 백업 소스로 사용하려고하지 않고 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와 통합되지 않은 앱에서 작성하는 경우 자체 일관성인지에 대한 유효한 질문이 제기 될 수 있습니다. 유사한 기능을 제공하는 다른 제품이있을 수 있습니다.


@Fred : VBScript와 Microsoft 명령 줄 도구를 사용하여 수행 한 작업입니다. 내 대답을 참조하십시오.
Tomalak

-1

짧은 대답 : 할 수 없습니다.

약간 더 긴 답변 : 섀도 복사 서비스는 API를 통해 프로그래밍 방식으로 사용하여 열린 파일을 백업 할 수 있지만 서비스는 시스템의 전체 스냅 샷을 생성하지 않고 부분 스냅 샷 만 생성합니다.


2
나는 이것이 불가능하다고 믿기를 거부합니다. 완전한 "시스템 스냅 샷"이 필요하지 않으며 단일 볼륨의 특정 시점 사본 만 필요합니다. 섀도 복사본이 내부적으로 작동하는 방식을 대략적으로 알고 있으며 사용중인 파일을 백업하는 데 사용할 있다는 것을 알고 있습니다 (인터넷의 주요 예는 Exchange 또는 SQL 데이터베이스입니다).
Tomalak

1
@ 존 : 내가 할 수있는 것으로 밝혀졌습니다. 내 대답을 봐!
Tomalak

백업 소프트웨어와 거의 동일한 API를 사용하고 있습니다. 따라서 VSS 서비스를 사용하는 동안 볼륨 섀도 복사본을 사용하는 것과는 다릅니다. 그럼에도 불구하고, 그것이 원하는 것을 수행한다면 그것은 정말로 중요한 전부입니다. 잘 했어.
John Gardeniers

1
짧고 긴 대답이 모두 틀리며 "볼륨 섀도 복사본"이라는 용어는이 용어가 약간 모호한 경우에도 사용자가 찾고 있던 것을 나타내기에 충분했을 것입니다. en.wikipedia.org/wiki/Shadow_Copy
Chris Magnuson

1
아마 당신의 권리. OP가 자신이 설명한 것을 수행 할 수있는 방법을 찾았을 때 "당신은 할 수 없습니다"라는 당신의 대답이 어떻게 정확한지 이해하지 못합니다. api가 "부분 스냅 샷"만 허용하더라도 긴 볼륨은 요청 된 질문과 관련이 없습니다. 여전히 전체 볼륨의 표현을 특정 시점에 마운트하고 원하는 OP로 백업 할 수 있기 때문입니다. OP가 달성 할 수 있었던 것을 해결하기 위해 원본 게시물의 의미를 명확히 할 수 있다면, 정보가 관련이 있다면 투표를 기꺼이 제거하고 의견을 추가 할 것입니다.
Chris Magnuson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.