Microsoft Entra 連線:預備伺服器和災害復原

利用預備模式中的伺服器,您可以在啟用伺服器之前變更組態並預覽變更。 它也可讓您執行完整匯入和完整同步處理,以確認所有變更都預期在生產環境中進行這些變更。

預備模式

預備模式可以用於許多案例,包括:

  • 高可用性。
  • 測試和部署新的組態變更。
  • 引進新的伺服器並解除委任舊伺服器。

在安裝期間,您可以選取要處於預備模式的伺服器。 此動作會讓伺服器啟用匯入和同步處理,但不會執行任何匯出。 預備模式中的伺服器不會執行密碼同步或密碼回寫,即使您在安裝期間選取這些功能也一樣。 當您停用預備模式時,伺服器會開始匯出、啟用密碼同步,以及啟用密碼回寫。

注意

假設您已啟用密碼哈希同步處理功能的 Microsoft Entra 連線。 當您啟用預備模式時,伺服器會停止從內部部署 AD 同步處理密碼變更。 當您停用暫存模式時,伺服器會繼續同步處理上次離開的密碼變更。 如果伺服器在預備模式中保留一段較長的時間,伺服器可能需要一段時間的時間,才能同步處理期間發生的所有密碼變更。

您仍然可以使用同步處理服務管理員來強制匯出。

預備模式中的伺服器會繼續接收 Active Directory 和 Microsoft Entra 識別碼的變更,而且在發生失敗時,可以快速接管另一部伺服器的責任。 如果您對主伺服器進行組態變更,您有責任在預備模式中對伺服器進行相同的變更。

對於您瞭解較舊同步處理技術的人,預備模式會有所不同,因為伺服器有自己的 SQL 資料庫。 此架構可讓預備模式伺服器位於不同的資料中心。

驗證伺服器的組態

若要套用此方法,請遵循下列步驟:

  1. 準備
  2. Configuration
  3. 匯入和同步處理
  4. Verify
  5. 切換作用中的伺服器

準備

  1. 安裝 Microsoft Entra 連線、選取預備模式,然後取消選取安裝精靈最後一頁的 [開始同步處理]。 此模式可讓您手動執行同步處理引擎。 此螢幕快照顯示 [Microsoft Entra 連線] 對話方塊中的 [準備設定] 頁面。
  2. 註銷/登入,然後從 [開始] 功能選取 [ 同步處理服務]。

組態

如果您已對主伺服器進行自定義變更,而且想要比較組態與預備伺服器,請使用 Microsoft Entra 連線 組態檔。

匯入和同步處理

  1. 選取 [連線 ors],然後選取類型為 Active Directory 網域服務 的第一個 連線 or。 按兩下 [執行],選取 [完整匯入],然後選取 [確定]。 針對此類型的所有 連線 器執行這些步驟。
  2. 選取類型為 Microsoft Entra ID (Microsoft) 的 連線 or。 按兩下 [執行],選取 [完整匯入],然後選取 [確定]。
  3. 確定仍選取索引標籤 連線 器。 針對每個類型為 Active Directory 網域服務 的 連線 or,按兩下 [執行],選取 [差異同步處理],然後選取 [確定]。
  4. 選取類型為 Microsoft Entra ID (Microsoft) 的 連線 or。 按兩下 [執行],選取 [差異同步處理],然後選取 [確定]。

您現在已暫存對 Microsoft Entra ID 和內部部署 AD 的變更(如果您使用 Exchange 混合式部署)。 後續步驟可讓您在實際開始導出至目錄之前,先檢查即將變更的內容。

Verify

  1. 啟動 Cmd 提示並移至 %ProgramFiles%\Microsoft Azure AD Sync\bin
  2. 執行:csexport "Name of Connector" %temp%\export.xml /f:x您可以在同步處理服務中找到 連線 器的名稱。 其名稱類似於 Microsoft Entra ID 的 「contoso.com – Microsoft Entra ID」。
  3. 執行: CSExportAnalyzer %temp%\export.xml > %temp%\export.csv 您在 %temp% 中具有名為 export.csv 的檔案,可在 Microsoft Excel 中檢查。 此檔案包含即將匯出的所有變更。
  4. 對數據或組態進行必要的變更,然後再次執行這些步驟(匯入和同步處理和驗證),直到即將導出的變更。

瞭解export.csv檔案

大部分的檔案都是自我解釋的。 了解內容的一些縮寫:

  • OMODT – 物件修改類型。 指出物件層級的作業是否為 Add、Update 或 Delete。
  • AMODT – 屬性修改類型。 指出屬性層級的作業是否為 Add、Update 或刪除。

擷取通用標識碼

export.csv檔案包含即將匯出的所有變更。 每個數據列都會對應至連接器空間中對象的變更,而且該物件是由 DN 屬性所識別。 DN 屬性是指派給連接器空間中物件的唯一標識碼。 當您在export.csv中有許多數據列/變更要分析時,可能很難根據 DN 屬性來找出變更所要使用的物件。 若要簡化分析變更的程式,請使用 csanalyzer.ps1 PowerShell腳本。 腳本會擷取物件的通用標識碼(例如 displayName、userPrincipalName)。 若要使用指令碼:

  1. 將 PowerShell 腳本從 CSAnalyzer 區段複製到名為 的csanalyzer.ps1檔案。
  2. 開啟 PowerShell 視窗,並流覽至您建立 PowerShell 腳本的資料夾。
  3. 執行: .\csanalyzer.ps1 -xmltoimport %temp%\export.xml
  4. 您現在有一個名為 processedusers1.csv 的檔案,可在 Microsoft Excel 中檢查。 請注意,檔案會提供從 DN 屬性到通用標識碼的對應(例如 displayName 和 userPrincipalName)。 它目前不包含即將導出的實際屬性變更。

切換作用中的伺服器

Microsoft Entra 連線 可以在主動-被動高可用性設定中設定,其中一部伺服器會主動將已同步 AD 對象的變更推送至 Microsoft Entra ID,而被動伺服器會在需要接管時暫存這些變更。

注意

您無法在 Active-Active 安裝程式中設定 Microsoft Entra 連線。 它必須是主動-被動。 請確定只有 1 個 Microsoft Entra 連線 伺服器會主動同步處理變更。

如需在預備模式中設定 Microsoft Entra 連線 同步伺服器的詳細資訊,請參閱預備模式

您可能需要執行同步伺服器的故障轉移,原因有數個,例如升級 Microsoft Entra 連線 版本,或收到同步服務健康情況服務未收到最新資訊的警示。 在這些事件中,您可以依照下列步驟嘗試同步伺服器的故障轉移。

重要

如果不符合下列條件,將預備伺服器切換至作用中模式可能會對同步處理造成嚴重影響。 在進行這項作業之前,請務必先執行初始同步處理週期並 確認 擱置的導出。

必要條件

  • 目前作用中的 Microsoft Entra 連線 Sync Server
  • 一個預備 Microsoft Entra 連線 Sync Server
  • 預備伺服器已啟用同步處理排程器,且最近已與 Microsoft Entra ID 同步處理
  • 如果同步處理規則或同步範圍中的任何更新,請執行初始同步處理週期
  • 確認您的 Microsoft Entra 連線 Sync Server 已設定為防止意外刪除
  • 確認 擱置的導出,並確認沒有重大更新,且預期會有這類更新
  • 檢查 Microsoft Entra 連線 Health 代理程式是否已更新,方法是檢查 Microsoft Entra 連線 Health 入口網站中的伺服器
  • 將目前的使用中伺服器切換至預備模式,再將預備伺服器切換為作用中

將目前作用中的同步伺服器變更為預備模式

我們需要確保在整個程式中,在任何指定時間,只有一部同步處理伺服器會同步處理變更。 如果目前使用中的同步伺服器可連線,您可以執行下列步驟,將它移至預備模式。 如果無法連線,請確定伺服器或 VM 不會透過關閉伺服器或將它與輸出連線隔離,意外地重新取得存取權。

  1. 針對目前使用中的 Microsoft Entra 連線 伺服器,開啟 [Microsoft Entra 連線 精靈],然後按兩下 [設定預備模式],然後按兩下 [下一步]:

    此螢幕快照顯示 [使用中 Microsoft Entra 連線] 對話框中反白顯示的暫存模式。

  2. 您必須使用全域 管理員 istrator 或混合式身分識別 管理員 認證來登入 Microsoft Entra ID:

    此螢幕快照顯示 [使用中 Microsoft Entra 連線] 對話框中的 [登入] 提示。

  3. 勾選預備模式的方塊,然後按 [下一步]:

    此螢幕快照顯示 [使用中 Microsoft Entra 連線] 對話框中的暫存模式設定。

  4. Microsoft Entra 連線 伺服器會檢查已安裝的元件,然後提示您是否要在組態變更完成時啟動同步處理程式:

    此螢幕快照顯示 [作用中 Microsoft Entra 連線] 對話方塊中的 [準備設定] 畫面。

由於伺服器會處於預備模式,因此不會將變更寫入 Microsoft Entra ID,而是在其 連線 或空間中保留 AD 的任何變更,準備好寫入這些變更。
建議您在預備模式中讓伺服器的同步處理程式保持開啟,因此如果它變成作用中,它會快速接管,而且不需要執行大型同步處理,才能趕上範圍內 Active Directory / Microsoft Entra 物件的目前狀態。

  1. 選取以啟動同步處理程式並按下 [設定] 之後,Microsoft Entra 連線 伺服器將會設定為預備模式。
    完成此動作時,系統會提示您顯示確認已啟用預備模式的畫面。
    您可以按下 [結束] 完成。

  2. 您可以使用下列命令,藉由開啟 Windows PowerShell、載入 “ADSync” 模組並驗證 ADSync 排程器設定,以確認伺服器已成功處於預備模式:

Import-Module ADSync
Get-ADSyncScheduler

從結果中,確認 「StagingModeEnabled」 設定的值。 如果伺服器已成功切換至預備模式,則此設定的值應該為 True ,如下列範例所示:

此螢幕快照顯示 [使用中 Microsoft Entra 連線] 對話方塊上的 [同步服務] 控制台。

將目前的預備同步處理伺服器變更為使用中模式

此時,我們所有的 Microsoft Entra 連線 同步伺服器都應該處於預備模式,而不會匯出變更。 我們現在可以將預備同步伺服器移至作用中模式,並主動同步變更。

  1. 現在移至原本處於預備模式的 Microsoft Entra 連線 伺服器,然後開啟 Microsoft Entra 連線 精靈。

    按兩下 [設定預備模式],然後按 [下一步]:

    此螢幕快照顯示 [暫存 Microsoft Entra 連線] 對話框中醒目提示的預備模式。

    精靈底部的訊息指出此伺服器處於預備模式。

  2. 登入 Microsoft Entra ID,然後移至 [預備模式] 畫面。

    取消勾選預備模式的方塊,然後按 [下一步]

    螢幕快照:顯示 [暫存 Microsoft Entra 連線] 對話框中的 [預備模式] 組態。

    根據此頁面上的警告,請務必確保沒有任何其他 Microsoft Entra 連線 伺服器正在主動同步處理。

    隨時應該只有一個作用中的 Microsoft Entra 連線 Sync 伺服器。

  3. 當系統提示您啟動同步處理程式時,請勾選此方塊,然後按下 [設定]:

    顯示 [預備 Microsoft Entra 連線] 對話框中 [準備設定] 畫面的螢幕快照。

  4. 完成此程序之後,您應該會看到下列確認畫面,您可以在其中按兩下 [結束] 完成:

    螢幕快照:顯示 [暫存 Microsoft Entra 連線] 對話框中的 [確認] 畫面。

  5. 您可以開啟同步服務控制台,並檢查匯出作業是否正在執行,以確認其運作正常:

    螢幕快照:顯示 [暫存 Microsoft Entra 連線] 對話方塊上的同步服務控制台。

災害復原

實作設計的一部分是規劃您在失去同步處理伺服器的災害中應如何應對。 有不同的模型可供使用,要使用哪一個模組取決於許多因素,包括:

  • 您在停機期間無法變更 Microsoft Entra 識別符中物件的容錯為何?
  • 如果您使用密碼同步化,使用者是否接受他們在內部部署變更時必須在 Microsoft Entra ID 中使用舊密碼?
  • 您是否對即時作業有相依性,例如密碼回寫?

根據這些問題和貴組織原則的解答,可以實作下列其中一個策略:

  • 視需要重建。
  • 擁有備用待命伺服器,稱為 預備模式
  • 使用虛擬機器。

如果您未使用內建 SQL Express 資料庫,則也應該檢閱 SQL 高可用性 一節。

必要時重建

可行的策略是在需要時規劃伺服器重建。 通常,安裝同步處理引擎並執行初始匯入和同步處理可以在幾個小時內完成。 如果沒有可用的備用伺服器,可以暫時使用域控制器來裝載同步處理引擎。

同步處理引擎伺服器不會儲存有關物件的任何狀態,因此可以從 Active Directory 和 Microsoft Entra ID 中的數據重建資料庫。 sourceAnchor 屬性可用來聯結來自內部部署和雲端的物件。 如果您使用內部部署和雲端的現有物件重建伺服器,則同步處理引擎會在重新安裝時再次比對這些物件。 您需要記錄和儲存的專案是對伺服器所做的設定變更,例如篩選和同步處理規則。 開始同步處理之前,必須先重新套用這些自定義組態。

擁有備用待命伺服器 - 預備模式

如果您有更複雜的環境,建議使用一或多個待命伺服器。 在安裝期間,您可以讓伺服器處於 預備模式

如需詳細資訊,請參閱 預備模式

使用虛擬機器

常見的和支援方法是在虛擬機中執行同步處理引擎。 如果主機發生問題,同步處理引擎伺服器的映像可以移轉至另一部伺服器。

SQL 高可用性

如果您未使用 Microsoft Entra 連線 隨附的 SQL Server Express,則也應該考慮 SQL Server 的高可用性。 支援的高可用性解決方案包括 SQL 叢集和 AOA(AlwaysOn 可用性群組)。 不支援的解決方案包括鏡像。

SQL AOA 的支援已新增至 1.1.524.0 版中的 Microsoft Entra 連線。 您必須先啟用 SQL AOA,才能安裝 Microsoft Entra 連線。 在安裝期間,Microsoft Entra 連線 會偵測是否為 SQL AOA 啟用提供的 SQL 實例。 如果已啟用 SQL AOA,Microsoft Entra 連線 進一步瞭解 SQL AOA 是否設定為使用同步復寫或異步複寫。 設定可用性群組接聽程式時,RegisterAllProvidersIP 屬性必須設定為 0。 這是因為 Microsoft Entra 連線 目前使用 SQL Native Client 連線到 SQL,SQL Native Client 不支援使用 MultiSubNetFailover 屬性。

附錄 CSAnalyzer

請參閱驗證如何使用此腳本一節

Param(
    [Parameter(Mandatory=$true, HelpMessage="Must be a file generated using csexport 'Name of Connector' export.xml /f:x)")]
    [string]$xmltoimport="%temp%\exportedStage1a.xml",
    [Parameter(Mandatory=$false, HelpMessage="Maximum number of users per output file")][int]$batchsize=1000,
    [Parameter(Mandatory=$false, HelpMessage="Show console output")][bool]$showOutput=$false
)

#LINQ isn't loaded automatically, so force it
[Reflection.Assembly]::Load("System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") | Out-Null

[int]$count=1
[int]$outputfilecount=1
[array]$objOutputUsers=@()

#XML must be generated using "csexport "Name of Connector" export.xml /f:x"
write-host "Importing XML" -ForegroundColor Yellow

#XmlReader.Create won't properly resolve the file location,
#so expand and then resolve it
$resolvedXMLtoimport=Resolve-Path -Path ([Environment]::ExpandEnvironmentVariables($xmltoimport))

#use an XmlReader to deal with even large files
$result=$reader = [System.Xml.XmlReader]::Create($resolvedXMLtoimport) 
$result=$reader.ReadToDescendant('cs-object')
if($result)
{
    do 
    {
        #create the object placeholder
        #adding them up here means we can enforce consistency
        $objOutputUser=New-Object psobject
        Add-Member -InputObject $objOutputUser -MemberType NoteProperty -Name ID -Value ""
        Add-Member -InputObject $objOutputUser -MemberType NoteProperty -Name Type -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name DN -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name operation -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name UPN -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name displayName -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name sourceAnchor -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name alias -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name primarySMTP -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name onPremisesSamAccountName -Value ""
        Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name mail -Value ""

        $user = [System.Xml.Linq.XElement]::ReadFrom($reader)
        if ($showOutput) {Write-Host Found an exported object... -ForegroundColor Green}

        #object id
        $outID=$user.Attribute('id').Value
        if ($showOutput) {Write-Host ID: $outID}
        $objOutputUser.ID=$outID

        #object type
        $outType=$user.Attribute('object-type').Value
        if ($showOutput) {Write-Host Type: $outType}
        $objOutputUser.Type=$outType

        #dn
        $outDN= $user.Element('unapplied-export').Element('delta').Attribute('dn').Value
        if ($showOutput) {Write-Host DN: $outDN}
        $objOutputUser.DN=$outDN

        #operation
        $outOperation= $user.Element('unapplied-export').Element('delta').Attribute('operation').Value
        if ($showOutput) {Write-Host Operation: $outOperation}
        $objOutputUser.operation=$outOperation

        #now that we have the basics, go get the details

        foreach ($attr in $user.Element('unapplied-export-hologram').Element('entry').Elements("attr"))
        {
            $attrvalue=$attr.Attribute('name').Value
            $internalvalue= $attr.Element('value').Value

            switch ($attrvalue)
            {
                "userPrincipalName"
                {
                    if ($showOutput) {Write-Host UPN: $internalvalue}
                    $objOutputUser.UPN=$internalvalue
                }
                "displayName"
                {
                    if ($showOutput) {Write-Host displayName: $internalvalue}
                    $objOutputUser.displayName=$internalvalue
                }
                "sourceAnchor"
                {
                    if ($showOutput) {Write-Host sourceAnchor: $internalvalue}
                    $objOutputUser.sourceAnchor=$internalvalue
                }
                "alias"
                {
                    if ($showOutput) {Write-Host alias: $internalvalue}
                    $objOutputUser.alias=$internalvalue
                }
                "proxyAddresses"
                {
                    if ($showOutput) {Write-Host primarySMTP: ($internalvalue -replace "SMTP:","")}
                    $objOutputUser.primarySMTP=$internalvalue -replace "SMTP:",""
                }
            }
        }

        $objOutputUsers += $objOutputUser

        Write-Progress -activity "Processing ${xmltoimport} in batches of ${batchsize}" -status "Batch ${outputfilecount}: " -percentComplete (($objOutputUsers.Count / $batchsize) * 100)

        #every so often, dump the processed users in case we blow up somewhere
        if ($count % $batchsize -eq 0)
        {
            Write-Host Hit the maximum users processed without completion... -ForegroundColor Yellow

            #export the collection of users as a CSV
            Write-Host Writing processedusers${outputfilecount}.csv -ForegroundColor Yellow
            $objOutputUsers | Export-Csv -path processedusers${outputfilecount}.csv -NoTypeInformation

            #increment the output file counter
            $outputfilecount+=1

            #reset the collection and the user counter
            $objOutputUsers = $null
            $count=0
        }

        $count+=1

        #need to bail out of the loop if no more users to process
        if ($reader.NodeType -eq [System.Xml.XmlNodeType]::EndElement)
        {
            break
        }

    } while ($reader.Read)

    #need to write out any users that didn't get picked up in a batch of 1000
    #export the collection of users as CSV
    Write-Host Writing processedusers${outputfilecount}.csv -ForegroundColor Yellow
    $objOutputUsers | Export-Csv -path processedusers${outputfilecount}.csv -NoTypeInformation
}
else
{
    Write-Host "Imported XML file is empty. No work to do." -ForegroundColor Red
}

下一步

概觀主題