Azure AD Connect - 用户更改时自动同步
如另一篇文章中所述,默认情况下,Azure AD Connect 每 30 分钟将 Active Directory 更改同步到 Azure。这意味着任何本地用户更改(密码更改除外)最多可能需要 30 分钟才能在 Azure/Office 365 中可见。
对于大多数管理员来说,这也意味着需要进行大量的 Azure AD Connect 手动同步。您和您的用户都不想在测试您刚刚在本地用户对象上配置的新邮件别名之前等待半个小时...
那么该怎么办呢?
我们不能将 Azure AD Connect 设置为每分钟同步吗?不幸的是不是…允许的最频繁的计划是默认的 30 分钟,由 ADSyncScheduler 的AllowedSyncCycleInterval 属性设置。这是根据设计配置的,无法进行管理设置
PS C:\Windows\system32> Get-ADSyncScheduler
AllowedSyncCycleInterval : 00:30:00
CurrentlyEffectiveSyncCycleInterval : 00:30:00
CustomizedSyncCycleInterval :
NextSyncCyclePolicyType : Delta
NextSyncCycleStartTimeInUTC : 5/3/2019 9:09:31 AM
PurgeRunHistoryInterval : 7.00:00:00
SyncCycleEnabled : True
MaintenanceEnabled : True
StagingModeEnabled : False
SchedulerSuspended : False
SyncCycleInProgress : False
怎么办???如果 Azure AD Connect 决定在每次创建或更新用户对象时进行自动同步,那不是很好吗?当然可以,为什么不呢!我们走吧…
“在每次本地用户对象更改时自动同步 Azure AD Connect”-PowerShell 脚本!
只要您限制查询的复杂性、不在查询中包含太多非索引属性以及,Active Directory LDAP 查询就会相当快不要检索太多属性。在大多数情况下,您应该能够在不到一秒的时间内运行根据whenChanged 属性进行筛选的用户搜索。除非您的 DC 资源已经紧张和/或您的用户数量远高于 5,000。
要测试您的 DC 性能,请尝试在您的系统上对以下代码进行计时(它将获取上周内更改的所有用户的基本属性):
Import-Module ActiveDirectory
$OneWeekAgo = (Get-Date) + (New-TimeSpan -Days -7)
[array]$Users = Get-ADUser -Filter 'whenChanged -gt $OneWeekAgo'如果查询(第 3 行)花费了几秒钟以上的时间才能完成,请调查原因。如果您的 DC 无法有效处理查询,则不应使用本文建议的 15 秒计划。
但如果上面的代码在大约一秒或更短的时间内执行,我认为每 15 秒针对您的一个域控制器运行一次是合理的。
使用日志文件对脚本进行计时和控制
确认 whenChanged 查询的影响较小后,让我们尝试构建它。我们需要以下内容:
- 运行查询以查看自上次运行查询以来是否有任何用户发生更改
- 如果用户发生更改,则触发 Azure AD Connect 同步
- 完成后,等待 15 秒再重新开始
有许多方法可以控制该流量。我更喜欢使用日志文件,因为它处理起来相对简单,并且可以给我们带来许多好处,例如执行历史记录和故障排除信息。
日志文件应执行以下操作:
写下我们进行查询的时间(这样我们就知道下次运行脚本时要查找多远的用户更改):
$Now = Get-Date
$Now.ToString("yyyyMMddHHmmss") + " Some status info." | Out-File $LogFile -Append请阅读我们上次进行的查询并检查此后发生更改的用户和组:
$LastLine = Get-Item -Path $LogFile | Get-Content -Tail 1 # Read last line of log file
$LastSync = [datetime]::parseexact($LastLine.Substring(0, 14), 'yyyyMMddHHmmss', $null) # Get last synchronization time
[array]$Users = Get-ADUser -Filter ‘whenChanged -gt $LastSync’ # Find users that changed since last time
[array]$Groups = Get-ADGroup -Filter 'whenChanged -gt $LastSync' # Find groups that changed since last time$ChangeCount = $Users.Count + $Groups.Count
If ($ChangeCount -gt 0) {
Import-Module ADSync
Start-ADSyncSyncCycle -PolicyType Delta
}If ((Test-Path $LogFile) -eq $False){ # Create log file if it doesn't exist
"Time Message" | Out-File $LogFile
"19990101000001 SyncAllChanges" | Out-File $LogFile -Append
}
$LastLine = Get-Item -Path $LogFile | Get-Content -Tail 1 # Read last line of log file
If ((Get-Item $LogFile).Length -gt $MaxSize){ # Reset log file if it has grown larger than $MaxSize
"Time Message" | Out-File $LogFile
$LastLine | Out-File $LogFile -Append
}Try {
# Main code goes here
}
Catch {
"19990101000001 " + $ErrorMessage | Out-File $LogFile -Append
}
(将上次同步时间设置为 1999 年 1 月 1 日将确保下次运行时更改的用户数大于 0,因此将触发 Azure AD Connect 增量同步。)
结束 Azure AD Connect 同步脚本
定义完所有细节后,我们就可以安排它了。关于调度,一些管理员更喜欢将其计划任务集中在专用批处理服务器上以跟踪自动化。为了支持这一点,我们需要实现远程处理,这需要进行一些调整才能执行正确的错误处理。
您将在下面找到完整的最终脚本。
# Azure AD Connect Auto Sync script - Provided as-is, use at own risk.
# Make sure ActiveDirectory module is available on system where script is scheduled.
# Will trigger Azure AD Connect synchronization when on-prem AD user or group is changed.
# Schedule to run every 5 minutes and to start after scheduled start is missed.
# For full info on script and how to schedule it:
# https://www.easy365manager.com/azure-ad-connect-automatic-synchronization-on-user-change
# Configure parameters before scheduling the script:
$AADConnectServer = "" # Azure AD Connect server (blank assumes local system)
$LogFile = "AD_Azure_Sync_Log.txt" # Log file used for keeping track of AD changes and troubleshooting
$MaxSize = 5242880 # Maximum size of log file in bytes (5MB)
$StartTime = Get-Date
While ((New-TimeSpan $StartTime (Get-Date)).Seconds -lt 300) {
Try {
Import-Module ActiveDirectory
If ((Test-Path $LogFile) -eq $False) {
# Create log file if it doesn't exist
"Time Message" | Out-File $LogFile
"19990101000001 SyncAllChanges" | Out-File $LogFile -Append
}
$LastLine = Get-Item -Path $LogFile | Get-Content -Tail 1 # Read last line of log file
If ((Get-Item $LogFile).Length -gt $MaxSize) {
# Reset log file if it has grown larger than $MaxSize
"Time Message" | Out-File $LogFile
$LastLine | Out-File $LogFile -Append
}
$Now = Get-Date
$LastSync = [datetime]::parseexact($LastLine.Substring(0, 14), 'yyyyMMddHHmmss', $null) # Get last synchronization time
[array]$Users = Get-ADUser -Filter 'whenChanged -gt $LastSync' # Find users that changed since last time
[array]$Groups = Get-ADGroup -Filter 'whenChanged -gt $LastSync' # Find groups that changed since last time
$ChangeCount = $Users.Count + $Groups.Count
If ($ChangeCount -gt 0) {
# If any users or groups were changed start the Azure AD Synchronization
If ($AADConnectServer -ne "" -and $AADConnectServer.ToLower() -ne $env:COMPUTERNAME.ToLower()) {
# Connect to Azure AD Connect server if not running on local system
$Session = New-PSSession $AADConnectServer
$Result = Invoke-Command -Session $Session -Scriptblock {
Try {
Import-Module ADSync
Start-ADSyncSyncCycle -PolicyType Delta
}
Catch {
return $_
}
}
Remove-PSSession $Session
}
Else {
Import-Module ADSync
Start-ADSyncSyncCycle -PolicyType Delta
}
If (!$Result -or $Result.ToString() -eq "Microsoft.IdentityManagement.PowerShell.ObjectModel.SchedulerOperationStatus") {
$Now.ToString("yyyyMMddHHmmss") + " Synchronized " + $ChangeCount + " Users/Groups." | Out-File $LogFile -Append
}
Else {
"19990101000001 " + ($Result.ToString().Split("`r")[0]) | Out-File $LogFile -Append
}
}
Else {
$Now.ToString("yyyyMMddHHmmss") + " No changes." | Out-File $LogFile -Append
}
}
Catch {
"19990101000001 " + ($_.ToString().Split("`r")[0]) | Out-File $LogFile -Append
}
Start-Sleep 15
}感谢新西兰环境保护局的 Phil Ready 建议将组更改纳入 AD 扫描!
调度同步脚本
要同步脚本,请使用任务计划程序中的以下设置。该脚本配置为运行五分钟,任务计划程序应每五分钟启动一次作业。这种组合可确保您全天候稳定运行。请小心遵循这些说明,以避免并行运行多个脚本或根本不运行任何脚本。
确保使用密码不过期的服务/批处理帐户。另外,请考虑该帐户需要访问权限才能触发 Azure AD Connect 同步并写入日志文件。
设置接下来几分钟内的开始日期/时间并让它自动开始。如果您手动启动它,则可能会面临两个并发线程的风险,这会给域控制器带来额外的负载并模糊日志文件的内容。
程序/脚本路径应该是 PowerShell.exe 文件的完整路径。参数应该是脚本文件的完整路径。起始文件夹应配置为包含脚本文件的文件夹。
确保将任务设置为在错过计划启动后尽快运行,以使其在系统重新引导后自动启动。
智能解决方案
您可以使用脚本解决几乎任何问题 - 如果您有时间……但如果您希望聪明地工作,我们建议您查看 Easy365Manager,它可以作为功能齐全的免费试用版提供。
Easy365Manager 通过添加两个新选项卡增强了 AD 用户和计算机控制台的功能。使用新设置,只要配置本地用户帐户,就可以自动触发 Azure AD Connect 同步。 Easy365Manager 还允许您直接配置 Office 365 许可证和邮箱设置。
无需在 AD 用户和计算机、Office 365 门户、Azure AD Connect 和 PowerShell 之间跳转 - 安装 Easy365Manager 并在扩展的 AD 用户和计算机控制台中智能工作.
要继续以脚本方式穿越世界,请在下面下载 ?
下载 Azure AD Connect 自动同步脚本
有关如何安排脚本的详细说明,请阅读本节。





