HybridADJoin Object ADSync Force Script

I have been tinkering with HybridADJoin again, I needed a script which performs a force ADSync to upload the AD Object.

Micheal Niehaus explains it perfectly in this blog: Hybrid AD Join troubles

Furthermore, this is the script proposed in the blog: (This is just an example, I am pretty sure the one that Micheal uses is a lot more sophisticated)

HybridADJoin Object ADSync Force Script - Sample Image

I think we can do a little better than that. We want a trigger based script on new objects in a certain OU. After that, we want logging and we want to run a delta AD Sync twice with an interval of 5 minutes. Next, we want to schedule this script to run every 5 minutes. If there are no new objects, the script does nothing.

Prequisites

You already have a Hybrid AD Join Windows 10 Autopilot config running. If you don’t check out my blog on how to do so.

You have AD Connect running. In addition, Install the Active Directory Powershell module on the server where want to run the script from. Instructions


Script syntax

Save this code as a .ps1 file on the server where you want to schedule the script.

## Logging Function
function Write-Log
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true,
        ValueFromPipelineByPropertyName=$true)]
        [ValidateNotNullOrEmpty()]
        [Alias("LogContent")]
        [string]$Message,

        [Parameter(Mandatory=$false)]
        [Alias('LogPath')]
        [string]$Path='C:\Logs\ADSyncScript.log',
        
        [Parameter(Mandatory=$false)]
        [ValidateSet("Error","Warn","Info")]
        [string]$Level="Info",
        
        [Parameter(Mandatory=$false)]
        [switch]$NoClobber
    )

    Begin
    {
        # Set VerbosePreference to Continue so that verbose messages are displayed.
        $VerbosePreference = 'Continue'
    }
    Process
    {
        # If the file already exists and NoClobber was specified, do not write to the log.
        if ((Test-Path $Path) -AND $NoClobber) {
            Write-Error "Log file $Path already exists, and you specified NoClobber. Either delete the file or specify a different name."
            Return
            }

        # If attempting to write to a log file in a folder/path that doesn't exist create the file including the path.
        elseif (!(Test-Path $Path)) {
            Write-Verbose "Creating $Path."
            New-Item $Path -Force -ItemType File
            }
        else {
            # Nothing to see here yet.
            }
        # Format Date for our Log File
        $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        # Write message to error, warning, or verbose pipeline and specify $LevelText
        switch ($Level) {
            'Error' {
                Write-Error $Message
                $LevelText = 'ERROR:'
                }
            'Warn' {
                Write-Warning $Message
                $LevelText = 'WARNING:'
                }
            'Info' {
                Write-Verbose $Message
                $LevelText = 'INFO:'
                }
            }
        # Write log entry to $Path
        "$FormattedDate $LevelText $Message" | Out-File -FilePath $Path -Append
    }
    End
    {
    }
}

$MonitoredOU = Get-ADObject -filter * -SearchBase "YOUR ORGANISATIONAL UNIT" -properties *

$LatestItem = $MonitoredOU.Created | Sort-Object -Descending | Select-Object -First 1

$Date = (Get-Date).AddMinutes(-15)

if ($LatestItem -ge $date) {
    
    $Count = 2
    Write-Log "Newer AD Object Found, Starting AD Sync 3 times in 15 minutes." -Level Info -Verbose
}
Else {
    $Count = 0
    Write-Log "No newer AD Object found, waiting for 5 minutes" -Level Info -Verbose

}

If ($Count -ne 0){

    do {
        #Starting Count
        Write-Log "Starting First AD Sync Sync Cycle, count is now $($Count)" -Level Info -Verbose

        Start-ADSyncSyncCycle -PolicyType Delta

        Start-SLeep 300

        $Count -= 1

    } while ($Count -ne '0')
}
Else {
    Write-Log "No need to execute Do-While Loop" -Level Info -Verbose
}

Schedule the script

Firstly, we need to create a user which is able to run the script and has the least administrative permissions.

Go to your management server and open “Active Directory Users & Computers”.

After that, create a service account called:

HybridADJoin Object ADSync Force Script - Service Account


Next, log on to the AD Connect server. This is also the server where I plan to schedule the script.

Open computer management:

HybridADJoin Object ADSync Force Script - Computer Management

After that, go to “Local Users and Groups” and select Groups:

HybridADJoin Object ADSync Force Script - groups

Add the Service Account to the group called “ADSyncOperators” & “Backup Operators”:

HybridADJoin Object ADSync Force Script - Service Account 2

Next, go to scheduled tasks:

Create a task:

Select the service account here:

Next go triggers and set the following trigger:

At “Actions”, create the following action:

Program/script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Arguments: -ExecutionPolicy Bypass -File “PATH\ForceADSync.ps1”

After that, save the task.

Example Run

When a new object is created in the specified OU. The task will trigger. But when no new objects are found, the task will remain idle:

When a new object is found. The sync will trigger and report back to the log file:

And that is how you write a script to ADsync HybridADJoin Object with force!

2 thoughts on “HybridADJoin Object ADSync Force Script”

  1. Hi, do you think it is possible to modify the script to force adconnect sync? because I have groups on azure that I have brought onprem (via adconnect’s writeback feature) and I would like them to be synchronized faster than the 30 minutes imposed by adconnect

    Reply

Leave a Comment