使用 VSS 自動化系統復原進行災害復原

執行災害復原的 VSS 備份和復原應用程式 (也稱為裸機復原) 可以使用自動化系統復原 (ASR) 寫入器與 Windows 預先安裝環境 (Windows PE) 來備份和還原可開機系統狀態的重要磁片區和其他元件。 備份應用程式會實作為 VSS 要求者。

注意 使用 ASR 的應用程式必須授權 Windows PE。

Windows Server 2003 和 Windows XP: ASR 不會實作為 VSS 寫入器。

如需您可以搭配 ASR 使用之追蹤工具的詳細資訊,請參閱 搭配 VSS ASR 應用程式使用追蹤工具

本文內容:

備份階段工作概觀

在備份時,要求者會執行下列步驟。

注意

除非另有指示,否則所有步驟都是必要的。

 

  1. 呼叫 CreateVssBackupComponents 函式來建立 IVssBackupComponents 介面的實例,並呼叫 IVssBackupComponents::InitializeForBackup 方法來初始化實例來管理備份。

  2. 呼叫 IVssBackupComponents::SetCoNtext 來設定陰影複製作業的內容。

  3. 呼叫 IVssBackupComponents::SetBackupState 來設定備份。 將 bBackupBootableSystemState 參數設定為 true ,表示備份將包含可開機的系統狀態。

  4. 選擇 ASR 寫入器的寫入器元資料檔案中哪些重要元件來備份,並為每個元件呼叫 IVssBackupComponents::AddComponent

  5. 呼叫 IVssBackupComponents::StartSnapshotSet 來建立新的空白陰影複製集。

  6. 呼叫 IVssBackupComponents::GatherWriterMetadata 以起始與寫入器的非同步連絡人。

  7. 呼叫 IVssBackupComponents::GetWriterMetadata 以擷取 ASR 寫入器的寫入器元資料檔案。 ASR 寫入器的寫入器識別碼是 BE000CBE-11FE-4426-9C58-531AA6355FC4,而寫入器名稱字串為 「ASR 寫入器」。

  8. 呼叫 IVssExtomWriterMetadata::SaveAsXML 以儲存 ASR 寫入器的寫入器元資料檔案複本。

  9. 針對可以參與陰影複製的每個磁片區呼叫 IVssBackupComponents::AddToSnapshotSet ,將磁片區新增至陰影複製集。

  10. 呼叫 IVssBackupComponents::P repareForBackup 以通知寫入器準備備份作業。

  11. 呼叫 IVssBackupComponents::GatherWriterStatusIVssBackupComponents::GetWriterStatus (或 IVssBackupComponentsEx3::GetWriterStatus) 以確認 ASR 寫入器的狀態。

  12. 此時,您可以查詢寫入 器在其 CVssWriter::OnPrepareBackup 方法中設定的失敗訊息。 如需示範如何檢視這些訊息的範例程式碼,請參閱 IVssComponentEx::GetPrepareForBackupFailureMsg

  13. 呼叫 IVssBackupComponents::D oSnapshotSet 來建立磁片區陰影複製。

  14. 呼叫 IVssBackupComponents::GatherWriterStatusIVssBackupComponents::GetWriterStatus 來驗證 ASR 寫入器的狀態。

  15. 備份資料。

  16. 指出備份作業是否成功,方法是呼叫IVssBackupComponents::SetBackupSucceeded。

  17. 呼叫 IVssBackupComponents::BackupComplete 以指出備份作業已完成。

  18. 呼叫 IVssBackupComponents::GatherWriterStatusIVssBackupComponents::GetWriterStatus。 寫入器會話狀態記憶體是有限的資源,而且寫入器最終必須重複使用會話狀態。 此步驟會將寫入器的備份會話狀態標示為已完成,並通知 VSS 此備份會話位置可由後續備份作業重複使用。

    注意

    這僅適用于 Windows Server 2008 Service Pack 2 (SP2) 和更早版本。

     

  19. 呼叫 IVssBackupComponents::SaveAsXML 以儲存要求者備份元件檔的複本。 當要求者呼叫 IVssBackupComponents::InitializeForRestore 方法時,會使用備份元件檔中的資訊。

選擇要備份的重要元件

在備份初始化階段,ASR 寫入器會在其寫入器元資料檔案中報告下列類型的元件:

  • 重要磁片區,例如開機、系統和 Windows 復原環境 (Windows RE) 磁片區,以及與目前執行的 Windows Vista 實例或 Windows Server 2008 實例相關聯的Windows RE磁碟分割。 如果磁片區包含系統狀態資訊,則磁片區是 重要的磁片 區。 系統會自動包含開機和系統磁片區。 要求者必須包含包含寫入器所報告之系統關鍵元件的所有磁片區,例如包含 Active Directory 的磁片區。 系統關鍵元件標示為「無法選取備份」。在 VSS 中,「不可選取」表示「不是選擇性」。因此,要求者必須將它們備份為系統狀態的一部分。 如需詳細資訊,請參閱 備份和還原系統狀態。 設定VSS_CF_NOT_SYSTEM_STATE旗標的元件不是系統關鍵。

    注意

    ASR 元件是 ASR 寫入器所報告的系統關鍵元件。

     

  • 磁碟。 電腦上的每個固定磁片都會公開為 ASR 中的元件。 如果備份期間未排除磁片,則會在還原期間指派磁片,並可重新建立和重新格式化。 請注意,在還原期間,要求者仍然可以呼叫 IVssBackupComponents::SetRestoreOptions 方法,重新建立備份期間排除的磁片。 如果選取動態磁碟套件中的一個磁片,也必須選取該套件中的所有其他磁片。 如果因為磁片區是重要的磁片區 (而選取,也就是包含系統狀態資訊的磁片區) ,則也必須選取包含該磁片區範圍的每個磁片。 若要尋找磁片區的範圍,請使用 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS 控制項程式碼。

    注意

    在備份期間,要求者應包含所有固定磁片。 如果包含要求者備份組的磁片是本機磁片,則應該包含此磁片。 在還原期間,要求者必須排除包含要求者備份組的磁片,以防止覆寫它。

     

    在叢集環境中,ASR 不會重新建立叢集共用磁片的配置。 在Windows RE中還原作業系統之後,應該在線上還原這些磁片。

  • 開機設定資料 (BCD) 存放區。 此元件會指定包含 BCD 存放區之目錄的路徑。 要求者必須指定此元件,並備份 BCD 存放區目錄中的所有檔案。 如需 BCD 存放區的詳細資訊,請參閱 關於 BCD

    注意

    在使用擴充韌體介面 (EFI) 的電腦上,EFI 系統分割區 (ESP) 一律會隱藏,而且不能包含在磁片區陰影複製中。 要求者必須備份此分割區的內容。 因為此分割區不能包含在磁片區陰影複製中,所以備份只能從即時磁片區執行,而不是從陰影複製執行。 如需 EFI 和 ESP 的詳細資訊,請參閱 啟動指南

元件名稱會使用下列格式:

  • 針對磁片元件,格式為

    <COMPONENT logicalPath=「Disks」 componentName=「harddiskn」 componentType=「filegroup」 />

    其中 n 是磁片編號。 只會記錄磁片編號。 若要取得磁片編號,請使用 IOCTL_STORAGE_GET_DEVICE_NUMBER 控制項程式碼。

  • 針對磁片區元件,格式為

    <COMPONENT logicalPath=「Volume」 componentName=「Volume{GUID}」 componentType=「filegroup」 />

    其中 GUID 是磁片區 GUID。

  • 針對 BCD 存放區元件,格式為

    <COMPONENT logicalPath=「BCD」 componentName=「BCD」 componentType=「filegroup」 componentCaption = 「這是開機 BCD 存放區和開機管理員的路徑...此目錄中的所有檔案都必須備份...」>

    如果系統分割區具有磁片區 GUID 名稱,則此元件是可選取的。 否則,它無法選取。

    注意

    ASR 會將檔案新增至 BCD 存放區元件的檔案群組,如下所示:

    • 針對 EFI 磁片,ASR 會新增

      SystemPartitionPath\EFI\Microsoft\Boot\*.*

      其中 SystemPartitionPath 是系統分割區的路徑。

    • 針對 GPT 磁片,ASR 會新增

      SystemPartitionPath\Boot\*.*

      其中 SystemPartitionPath 是系統分割區的路徑。

    • 您可以在下列登錄機碼下找到系統分割區路徑:HKEY_LOCAL_MACHINE\System\Setup\SystemPartition

     

在還原時,必須還原標示為重要磁片區的所有元件。 如果無法還原一或多個重要磁片區,還原作業就會失敗。

在還原順序的 PreRestore 階段中,預設會重新建立和重新格式化備份期間未排除的磁片。 不過,如果它們符合下列條件,則不會重新建立或重新格式化:

  • 如果磁片配置保持不變或只對它進行加法變更,則不會重新建立基本磁碟。 如果下列條件成立,磁片配置會保持不變:

    • 磁片簽章、磁片樣式 (GPT 或 MBR) 、邏輯磁區大小和磁片區開始位移不會變更。
    • 磁片區大小不會減少。
    • 針對 GPT 磁片,磁碟分割識別碼不會變更。
  • 如果動態磁碟配置保持不變,或只對它進行加法變更,則不會重新建立動態磁碟。 若要讓動態磁碟保持不變,必須符合基本磁碟的所有條件。 此外,整個磁片套件的磁片區結構必須保持不變。 如果磁片套件符合下列條件,磁片套件的磁片區結構會保持不變,這同時適用于 MBR 和 GPT 磁片:

    • 還原期間實體套件中可用的磁片區數目必須大於或等於備份期間 ASR 寫入器中繼資料中指定的磁片區數目。

    • 每個磁片區的 plex 數目必須保持不變。

    • 成員數目必須保持不變。

    • 實體磁片範圍的數目必須大於 ASR 寫入器中繼資料中指定的磁片範圍數目。

    • 新增其他磁片區時,或套件中的磁片區擴充 (,例如,從簡單磁片區延伸至跨區磁片區) ,則完整套件會保持不變。

      注意

      如果鏡像簡單磁片區,套件不會保持不變,而且將會重新建立,以確保 BCD 和開機磁片區狀態在還原之後保持一致。 如果刪除磁片區,則會重新建立套件。

       

  • 如果動態磁碟套件的磁片區結構保持不變,而且只會對它進行加法變更,則不會重新建立套件中的磁片。

    Windows Vista: 動態磁碟一律會重新建立。 請注意,此行為已隨著 Windows Server 2008 和 Windows Vista Service Pack 1 (SP1) 而變更。

在還原階段開始時,要求者隨時都可以藉由設定HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ASR\RestoreSession登錄機碼來指定磁片應該快速格式化。 在此機碼下,有一個名為 QuickFormat 的值,其資料類型為 REG_DWORD。 如果此值不存在,您應該建立此值。 將 QuickFormat 值的資料設定為 1,以便快速格式化,或將 0 設定為慢速格式。

如果 QuickFormat 值不存在,磁片的格式會變慢。

快速格式化速度明顯比慢速格式設定 (也稱為完整格式設定) 。 不過,快速格式化不會驗證磁片區上的每個磁區。

還原階段工作概觀

在還原時,要求者會執行下列步驟:

注意

除非另有指示,否則所有步驟都是必要的。

 

  1. 呼叫CreateVssBackupComponents 函式以建立 IVssBackupComponents介面的實例,並呼叫IVssBackupComponents::InitializeForRestore方法,藉由將要求的備份元件檔載入實例,以初始化實例以進行還原。

  2. [只有在要求者需要變更是否為一或多個磁片指定 「IncludeDisk」 或 「ExcludeDisk」 時,才需要此步驟。 呼叫 IVssBackupComponents::SetRestoreOptions 來設定 ASR 寫入器元件的還原選項。 ASR 寫入器支援下列選項:「IncludeDisk」 可讓要求者將目標系統上的磁片納入考慮進行還原,即使未在備份階段選取。 「ExcludeDisk」 可讓要求者防止重新建立目標系統上的磁片。 請注意,如果為包含重要磁片區的磁片指定 「ExcludeDisk」,後續呼叫 IVssBackupComponents::P reRestore 將會失敗。

    下列範例示範如何使用 SetRestoreOptions 來防止重新建立磁片 0 和磁片 1,並將協力廠商驅動程式插入還原的開機磁片區。

    Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支援插入協力廠商驅動程式。

    此範例假設 IVssBackupComponents 指標m_pBackupComponents有效。

        m_pBackupComponents->SetRestoreOptions(
            AsrWriterId,
            VSS_CT_FILEGROUP,
            NULL,
            TEXT("ASR"),
            TEXT("\"ExcludeDisk\"=\"0\", \"ExcludeDisk\"=\"1\" "),
            TEXT("\"InjectDrivers\"=\"1\" ")
            );
    

    若要排除指定磁片區的所有磁片,請參閱下列「排除磁片區的所有磁片」。

  3. 呼叫 IVssBackupComponents::P reRestore 以通知 ASR 寫入器準備還原作業。 呼叫 IVssAsync::QueryStatus ,直到 pHrResult 參數中傳回的狀態值未VSS_S_ASYNC_PENDING為止。

  4. 還原資料。 在還原階段,ASR 會針對每個磁片區重新設定磁片區 GUID 路徑 (\\?\Volume{GUID}) ,以符合備份階段期間所使用的磁片區 GUID 路徑。 不過,不會保留磁碟機號,因為這會導致與復原環境中自動指派的磁碟機號發生衝突。 因此,還原資料時,要求者必須使用磁片區 GUID 路徑,而不是磁碟機號來存取磁片區。

  5. 設定HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ASR\RestoreSession登錄機碼,以指出已還原或重新格式化的磁片區集。

    在此機碼下,有一個名為 RestoredVolumes 的值,其資料類型為 REG_MULTI_SZ。 如果此值不存在,您應該建立此值。 在此值下,您的要求者應該為每個已還原的磁片區建立磁片區 GUID 專案。 此專案的格式應如下:\\?\Volume{78618c8f-aefd-11da-a898-806e6f6e6963}。 每次執行裸機復原時,ASR 會將 RestoredVolumes 值設定為 ASR 還原的磁片區集。 如果要求者還原了其他磁片區,它應該將此值設定為要求者還原的磁片區集和 ASR 還原的磁片區集的聯集。 如果要求者未使用 ASR,它應該取代磁片區清單。

    您也應該使用資料類型REG_SZ建立名為 LastInstance 的值。 此金鑰應包含可唯一識別目前還原作業的隨機 Cookie。 您可以使用 UuidCreateUuidToString 函式來建立這類 Cookie。 每次執行裸機復原時,ASR 會重設此登錄值,以通知要求者和非 VSS 備份應用程式發生復原。

  6. 呼叫 IVssBackupComponents::P ostRestore 以指出還原作業的結尾。 呼叫 IVssAsync::QueryStatus ,直到 pHrResult 參數中傳回的狀態值未VSS_S_ASYNC_PENDING為止。

在還原階段,ASR 可能會建立或移除分割區,以將電腦還原到其先前的狀態。 要求者不得嘗試將磁片編號從備份階段對應至還原階段。

還原時,要求者必須排除包含要求者備份組的磁片。 否則,還原作業可以覆寫備份組。

在還原時,如果磁片未在備份期間選取為元件,或透過在還原期間呼叫 IVssBackupComponents::SetRestoreOptions 明確排除磁片,則會排除該磁片。

請務必注意,在 WinPE 災害復原期間,ASR 寫入器功能存在,但沒有其他寫入器可供使用,且 VSS 服務未執行。 WinPE 災害復原完成後,電腦已重新開機,且 Windows 作業系統正常執行,VSS 服務可以啟動,而且要求者可以執行任何其他需要 ASR 寫入器參與的還原作業。

如果在還原會話期間,備份應用程式偵測到磁片區唯一識別碼不變,因此備份期間的所有磁片區都存在且在 WinPE 中保持不變,則備份應用程式只能繼續復原磁碟區的內容,而不需涉及 ASR。 在此情況下,備份應用程式應該在還原的作業系統中設定下列登錄機碼來指出電腦已還原:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ASR\RestoreSession

在此機碼底下,針對值名稱指定 LastInstance 、針對實數值型別指定REG_SZ,以及 UuidCreate 函式所建立的 GUID,) 為值資料指定隨機 (Cookie。

如果在還原會話期間,備份應用程式偵測到一或多個磁片區已變更或遺失,備份應用程式應該使用 ASR 來執行還原。 ASR 會重新建立磁片區,就像備份時一樣,並設定 RestoreSession 登錄機碼。

排除磁片區的所有磁片

下列範例示範如何排除指定磁片區的所有磁片。

HRESULT BuildRestoreOptionString
(
    const WCHAR             *pwszVolumeNamePath,
    CMyString               *pstrExclusionList
)
{
    HANDLE                  hVolume           = INVALID_HANDLE_VALUE;
    DWORD                   cbSize            = 0;
    VOLUME_DISK_EXTENTS     * pExtents        = NULL;
    DISK_EXTENT             * pExtent         = NULL;
    ULONG                   i                 = 0;
    BOOL                    fIoRet            = FALSE;
    WCHAR                   wszDest[MAX_PATH] = L"";
    CMyString               strVolumeName;
    CMyString               strRestoreOption;

    // Open a handle to the volume device.
    strVolumeName.Set( pwszVolumeNamePath );
    // If the volume name contains a trailing backslash, remove it.
    strVolumeName.UnTrailing( L'\\' );
    hVolume = ::CreateFile(strVolumeName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, 0);
    // Check whether the call to CreateFile succeeded.

    // Get the list of disks used by this volume.
    cbSize = sizeof(VOLUME_DISK_EXTENTS);
    pExtents = (VOLUME_DISK_EXTENTS *)::CoTaskMemAlloc(cbSize);

    ::ZeroMemory(pExtents, cbSize);

    fIoRet = ::DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, pExtents, cbSize, &cbSize, 0);
    if ( !fIoRet && GetLastError() == ERROR_MORE_DATA )
    {
        // Allocate more memory.
        cbSize = FIELD_OFFSET(VOLUME_DISK_EXTENTS, Extents) + pExtents->NumberOfDiskExtents * sizeof(DISK_EXTENT);
        ::CoTaskMemFree(pExtents);
        pExtents = NULL;

        pExtents = (VOLUME_DISK_EXTENTS *) ::CoTaskMemAlloc(cbSize);
        // Check whether CoTaskMemAlloc returned an out-of-memory error.
        ::ZeroMemory(pExtents, cbSize);

        // Now the buffer should be big enough.
        ::DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, pExtents, cbSize, &cbSize, 0);
        // Check whether the IOCTL succeeded.
    }
    // Check for errors; note that the IOCTL can fail for a reason other than insufficient memory.

    // For each disk, mark it to be excluded in the Restore Option string.
    for (i = 0; i < pExtents->NumberOfDiskExtents; i++)
    {
        pExtent = &pExtents->Extents[i];

        *wszDest = L'\0';
        StringCchPrintf(wszDest, MAX_PATH, L"\"ExcludeDisk\"=\"%d\", ", pExtent->DiskNumber); // check errors

        strRestoreOption.Append(wszDest);
        // Check for an out-of-memory error.
    }

    // Remove the trailing comma.
    strRestoreOption.TrimRight();
    strRestoreOption.UnTrailing(',');

    // Set the output parameter.
    strRestoreOption.Transfer( pstrExclusionList );

Exit:
    if( pExtents )
    {
        ::CoTaskMemFree(pExtents);
        pExtents = NULL;
    }

    if( hVolume != INVALID_HANDLE_VALUE )
    {
        ::CloseHandle(hVolume);
        hVolume = INVALID_HANDLE_VALUE;
    }

    return ( hr );
}