Azure AD Connect:暂存服务器和灾难恢复Azure AD Connect: Staging server and disaster recovery

当服务器处于暂存模式时,可以在激活服务器之前更改配置并预览更改。With a server in staging mode, you can make changes to the configuration and preview the changes before you make the server active. 它还允许运行完全导入和完全同步,以便在生产环境中应用所有更改之前验证这些更改是否符合预期。It also allows you to run full import and full synchronization to verify that all changes are expected before you make these changes into your production environment.

暂存模式 Staging mode

暂存模式可以用于许多方案,包括:Staging mode can be used for several scenarios, including:

  • 高可用性。High availability.
  • 测试和部署新的配置更改。Test and deploy new configuration changes.
  • 引入新的服务器并解除旧服务器。Introduce a new server and decommission the old.

可以在安装过程中选择将服务器置于暂存模式During installation, you can select the server to be in staging mode. 此操作可以激活服务器进行导入和同步,但不会运行任何导出。This action makes the server active for import and synchronization, but it does not run any exports. 处于暂存模式的服务器不会运行密码同步,即使在安装期间选择了这些功能。A server in staging mode is not running password sync, even if you selected these features during installation. 如果禁用暂存模式,服务器将开始导出,启用密码同步。When you disable staging mode, the server starts exporting, enables password sync.

Note

假设拥有已启用密码哈希同步功能的 Azure AD Connect。Suppose you have an Azure AD Connect with Password Hash Synchronization feature enabled. 如果启用暂存模式,则服务器停止同步本地 AD 的密码更改。When you enable staging mode, the server stops synchronizing password changes from on-premises AD. 如果禁用暂存模式,则服务器从上次离开的位置恢复同步密码更改。When you disable staging mode, the server resumes synchronizing password changes from where it last left off. 如果服务器长时间处于暂存模式,则服务器可能需要一段时间才能同步该时间段内发生的所有密码更改。If the server is left in staging mode for an extended period of time, it can take a while for the server to synchronize all password changes that had occurred during the time period.

仍然可以使用 Synchronization Service Manager 强制导出。You can still force an export by using the synchronization service manager.

处于暂存模式的服务器会继续接收来自 Active Directory 和 Azure AD 的更改。A server in staging mode continues to receive changes from Active Directory and Azure AD. 它始终都有最新更改的副本,并且可以非常快速地接管另一服务器的责任。It always has a copy of the latest changes and can very fast take over the responsibilities of another server. 如果对主要服务器进行配置更改,则需要负责对处于暂存模式的服务器进行相同的更改。If you make configuration changes to your primary server, it is your responsibility to make the same changes to the server in staging mode.

对于熟悉旧式同步技术的人员而言,暂存模式是不同的,因为服务器有自身的 SQL 数据库。For those of you with knowledge of older sync technologies, the staging mode is different since the server has its own SQL database. 此体系结构允许将暂存模式服务器放置在不同的数据中心。This architecture allows the staging mode server to be located in a different datacenter.

验证服务器的配置Verify the configuration of a server

若要应用此方法,请遵循以下步骤:To apply this method, follow these steps:

  1. 准备Prepare
  2. 配置Configuration
  3. 导入和同步Import and Synchronize
  4. 验证Verify
  5. 切换活动服务器Switch active server

准备 Prepare

  1. 安装 Azure AD Connect,选择“暂存模式”,然后取消选择安装向导中最后一页上的“启动同步”。Install Azure AD Connect, select staging mode, and unselect start synchronization on the last page in the installation wizard. 此模式允许手动运行同步引擎。This mode allows you to run the sync engine manually. ReadyToConfigureReadyToConfigure
  2. 注销/登录并从“开始”菜单选择“同步服务”。Sign off/sign in and from the start menu select Synchronization Service.

配置 Configuration

如果对主服务器进行了自定义更改并希望比较配置和临时服务器,则使用 Azure AD Connect 配置文档管理器If you have made custom changes to the primary server and want to compare the configuration with the staging server, then use Azure AD Connect configuration documenter.

导入和同步 Import and Synchronize

  1. 选择“连接器”,并选择第一个 Active Directory 域服务类型的连接器。Select Connectors, and select the first Connector with the type Active Directory Domain Services. 单击“运行”,然后依次选择“完全导入”和“确定”。Click Run, select Full import, and OK. 针对此类型的所有连接器执行这些步骤。Do these steps for all Connectors of this type.
  2. 选择 Azure Active Directory (Microsoft) 类型的连接器。Select the Connector with type Azure Active Directory (Microsoft). 单击“运行”,然后依次选择“完全导入”和“确定”。Click Run, select Full import, and OK.
  3. 确保“连接器”选项卡仍处于选中状态。Make sure the tab Connectors is still selected. 针对每个 Active Directory 域服务类型的连接器,单击“运行”,然后依次选择“增量同步”和“确定”。For each Connector with type Active Directory Domain Services, click Run, select Delta Synchronization, and OK.
  4. 选择 Azure Active Directory (Microsoft) 类型的连接器。Select the Connector with type Azure Active Directory (Microsoft). 单击“运行”,然后依次选择“增量同步”和“确定”。Click Run, select Delta Synchronization, and OK.

现在,已将导出更改暂存到 Azure AD 和本地 AD(如果你正在使用 Exchange 混合部署)。You have now staged export changes to Azure AD and on-premises AD (if you are using Exchange hybrid deployment). 后续步骤可让你在实际开始导出到目录之前,检查将要更改的内容。The next steps allow you to inspect what is about to change before you actually start the export to the directories.

验证 Verify

  1. 启动 cmd 提示符并转到 %ProgramFiles%\Azure AD Sync\binStart a cmd prompt and go to %ProgramFiles%\Azure AD Sync\bin
  2. 运行:csexport "Name of Connector" %temp%\export.xml /f:x 连接器名称可以在同步服务中找到。Run: csexport "Name of Connector" %temp%\export.xml /f:x The name of the Connector can be found in Synchronization Service. 它的名称类似于“contoso.com - AAD”(表示 Azure AD)。It has a name similar to "contoso.com - AAD" for Azure AD.
  3. 运行:CSExportAnalyzer %temp%\export.xml > %temp%\export.csv %temp% 中已有名为 export.csv 的文件,可在 Microsoft Excel 中检查。Run: CSExportAnalyzer %temp%\export.xml > %temp%\export.csv You have a file in %temp% named export.csv that can be examined in Microsoft Excel. 此文件包含要导出的所有更改。This file contains all changes that are about to be exported.
  4. 对数据或配置进行必要的更改并再次执行这些步骤(导入、同步和身份验证),直到要导出的更改都按预期进行。Make necessary changes to the data or configuration and run these steps again (Import and Synchronize and Verify) until the changes that are about to be exported are expected.

了解 export.csv 文件。大部分的文件都简单易懂。Understanding the export.csv file Most of the file is self-explanatory. 请理解内容中的的一些缩写:Some abbreviations to understand the content:

  • OMODT — 对象修改类型。OMODT - Object Modification Type. 指示对象级别的操作是添加、更新还是删除。Indicates if the operation at an object level is an Add, Update, or Delete.
  • AMODT — 属性修改类型。AMODT - Attribute Modification Type. 指示属性级别的操作是添加、更新还是删除。Indicates if the operation at an attribute level is an Add, Update, or delete.

检索通用标识符。export.csv 文件包含要导出的所有更改。Retrieve common identifiers The export.csv file contains all changes that are about to be exported. 每行都对应于连接器空间中某个对象的更改,该对象由 DN 属性标识。Each row corresponds to a change for an object in the connector space and the object is identified by the DN attribute. DN 属性是分配给连接器空间中对象的唯一标识符。The DN attribute is a unique identifier assigned to an object in the connector space. 当 export.csv 中存在较多待分析的行/更改时,仅凭 DN 属性可能难以判断哪些对象发生了更改。When you have many rows/changes in the export.csv to analyze, it may be difficult for you to figure out which objects the changes are for based on the DN attribute alone. 要简化分析更改的进程,请使用 csanalyzer.ps1 PowerShell 脚本。To simplify the process of analyzing the changes, use the csanalyzer.ps1 PowerShell script. 该脚本可检索对象的通用标识符(如 displayName 和 userPrincipalName 等)。The script retrieves common identifiers (for example, displayName, userPrincipalName) of the objects. 使用脚本:To use the script:

  1. 将 PowerShell 脚本从 CSAnalyzer 部分复制到名为 csanalyzer.ps1 的文件。Copy the PowerShell script from the section CSAnalyzer to a file named csanalyzer.ps1.
  2. 打开 PowerShell 窗口并浏览到已在其中创建 PowerShell 脚本的文件夹。Open a PowerShell window and browse to the folder where you created the PowerShell script.
  3. 运行:.\csanalyzer.ps1 -xmltoimport %temp%\export.xmlRun: .\csanalyzer.ps1 -xmltoimport %temp%\export.xml.
  4. 现在已有名为 processedusers1.csv 的文件,可在 Microsoft Excel 中检查。You now have a file named processedusers1.csv that can be examined in Microsoft Excel. 请注意,该文件提供从 DN 属性到通用标识符(如 displayName 和 userPrincipalName 等)的映射。Note that the file provides a mapping from the DN attribute to common identifiers (for example, displayName and userPrincipalName). 当前尚不包括要导出的实际属性更改。It currently does not include the actual attribute changes that are about to be exported.

切换活动服务器 Switch active server

  1. 在当前处于活动状态的服务器上,关闭服务器 (DirSync/FIM/Azure AD Sync),使它不会导出到 Azure AD,或将它设为暂存模式 (Azure AD Connect)。On the currently active server, either turn off the server (DirSync/FIM/Azure AD Sync) so it is not exporting to Azure AD or set it in staging mode (Azure AD Connect).
  2. 在处于“暂存模式”的服务器上运行安装向导,然后禁用“暂存模式”。Run the installation wizard on the server in staging mode and disable staging mode. ReadyToConfigureReadyToConfigure

灾难恢复Disaster recovery

实现设计的一部分是规划在灾难中失去同步服务器时如何应对。Part of the implementation design is to plan for what to do in case there is a disaster where you lose the sync server. 有不同的模型可用,要使用哪一种模型取决于许多因素,包括:There are different models to use and which one to use depends on several factors including:

  • 停机期间无法对 Azure AD 中的对象进行更改的容限度如何?What is your tolerance for not being able make changes to objects in Azure AD during the downtime?
  • 如果使用密码同步,用户是否接受他们在本地更改时必须在 Azure AD 中使用旧密码?If you use password synchronization, do the users accept that they have to use the old password in Azure AD in case they change it on-premises?

根据这些问题的回答和组织的策略,实施下列其中一个策略:Depending on the answers to these questions and your organization’s policy, one of the following strategies can be implemented:

  • 根据需要重建。Rebuild when needed.
  • 具有备用的待机服务器(称为 暂存模式)。Have a spare standby server, known as staging mode.
  • 使用虚拟机。Use virtual machines.

如果不使用内置的 SQL Express 数据库,则还应查看 SQL 高可用性 部分。If you do not use the built-in SQL Express database, then you should also review the SQL High Availability section.

根据需要重建Rebuild when needed

必要时规划服务器重建为可行的策略。A viable strategy is to plan for a server rebuild when needed. 通常,在几个小时内即可完成安装同步引擎以及执行初始导入和同步。Usually, installing the sync engine and do the initial import and sync can be completed within a few hours. 如果没有可用的备用服务器,则可以暂时使用域控制器托管同步引擎。If there isn’t a spare server available, it is possible to temporarily use a domain controller to host the sync engine.

同步引擎服务器不会存储有关对象的任何状态,因此可以通过 Active Directory 与 Azure AD 中的数据重建数据库。The sync engine server does not store any state about the objects so the database can be rebuilt from the data in Active Directory and Azure AD. sourceAnchor 属性可用于联接来自本地和云的对象。The sourceAnchor attribute is used to join the objects from on-premises and the cloud. 如果重新生成包含本地与云中现有对象的服务器,同步引擎会在重新安装时再次同时匹配这些对象。If you rebuild the server with existing objects on-premises and the cloud, then the sync engine matches those objects together again on reinstallation. 需要记录和保存的内容是对服务器进行的配置更改,例如筛选和同步规则。The things you need to document and save are the configuration changes made to the server, such as filtering and synchronization rules. 在开始同步之前,必须重新应用这些自定义配置。These custom configurations must be reapplied before you start synchronizing.

具有备用的待机服务器 - 暂存模式Have a spare standby server - staging mode

如果环境更复杂,我们建议使用一个或多个待机服务器。If you have a more complex environment, then having one or more standby servers is recommended. 可以在安装过程中启用服务器的暂存模式During installation, you can enable a server to be in staging mode.

有关详细信息,请参阅暂存模式For more information, see staging mode.

使用虚拟机Use virtual machines

常用的受支持方法是在虚拟机中运行同步引擎。A common and supported method is to run the sync engine in a virtual machine. 如果主机有问题,可将包含同步引擎服务器的映像迁移到另一个服务器。In case the host has an issue, the image with the sync engine server can be migrated to another server.

SQL 高可用性 SQL High Availability

如果未使用 Azure AD Connect 随附的 SQL Server Express,还应考虑 SQL Server 的高可用性。If you are not using the SQL Server Express that comes with Azure AD Connect, then high availability for SQL Server should also be considered. 支持的高可用性解决方案包括 SQL 群集和 AOA(Always On 可用性组)。The high availability solutions supported include SQL clustering and AOA (Always On Availability Groups). 不支持的解决方案包括镜像。Unsupported solutions include mirroring.

Azure AD Connect 版本 1.1.524.0 中添加了对 SQL AOA 的支持。Support for SQL AOA was added to Azure AD Connect in version 1.1.524.0. 安装 Azure AD Connect 之前,必须启用 SQL AOA。You must enable SQL AOA before installing Azure AD Connect. 在安装期间,Azure AD Connect 会检测是否已为提供的 SQL 实例启用 SQL AOA。During installation, Azure AD Connect detects whether the SQL instance provided is enabled for SQL AOA or not. 如果启用了 SQL AOA,Azure AD Connect 进一步指出如果 SQL AOA 配置为使用同步复制或异步复制。If SQL AOA is enabled, Azure AD Connect further figures out if SQL AOA is configured to use synchronous replication or asynchronous replication. 设置可用性组侦听器时,我们建议将 RegisterAllProvidersIP 属性设置为 0。When setting up the Availability Group Listener, it is recommended that you set the RegisterAllProvidersIP property to 0. 这是因为,Azure AD Connect 目前使用 SQL Native Client 连接到 SQL,而 SQL Native Client 不支持使用 MultiSubNetFailover 属性。This is because Azure AD Connect currently uses SQL Native Client to connect to SQL and SQL Native Client does not support the use of MultiSubNetFailover property.

附录 CSAnalyzer Appendix CSAnalyzer

有关如何使用此脚本的信息,请参阅验证部分。See the section verify on how to use this script.

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

后续步骤Next steps

概述主题Overview topics