Issue

Don't want to wait the default 30 mins for the next sync operation?

Solution

Checking the sync connector status and performing a remote manual AAD Connect sync cycle operation with PowerShell.

High Level Steps:
  1. Check connectivity to the AAD Connect server.
  2. Check the status of the sync connector.
  3. Start a sync using Invoke-Command if the connector is not busy (in operation).

The credentials for the session must be a member of the local security group, AADSYNCADMINS, on the AAD Connect Server for this function to, err, function.

Code:

function Start-xAADConnectSync {
    <#
.SYNOPSIS
    Check the AAD Connect Server sync status and triggers a manual sync if the service is not busy (syncing).

.DESCRIPTION
    Check the AAD Connect Server sync status and triggers a manual sync if the service is not busy (syncing).
    The account that runs the function MUST be a member of the local security group, AADSYNCADMINS.

.NOTES
    AUTHOR   : Steve Rackham
    BLOG     : https://siliconwolf.net
    GIT      : https://github.com/siliconWOLF
    TWITTER  : https://twitter.com/siliconW0LF
    LINKEDIN : https://nz.linkedin.com/in/steverackham
    TO-DO    : Pass local variables to the Invoke-Command ScriptBlock.

    #>
    
    #>

    [cmdletbinding()]
    param (
        [Parameter (
            Mandatory,
            HelpMessage = "Enter the hostname of the AAD Connect Server:"
        )] [string]$ComputerName,

        [Parameter (
            HelpMessage = "Enter Sync Type: Delta or Initial (Full)."
        )][ValidateSet ( 'DELTA', 'INITIAL' )][string]$PolicyType,

        [Parameter (
            HelpMessage = "Timeout. Default 180s (3mins)"
        )] [int]$TimeOut = 180

    ) # END-PARAM

    # DEFINITIONS: ------------------------------------------------------------
    $OffSet = 0 - $ComputerName.Length
    [int]$iDelay = 10
    [int]$i = 0

    # GET: CHECK SYNC STATUS: -------------------------------------------------
    # Check the server is reachable.
    # Check the sync status.
    # Loop and check again if the Sync Connector is busy.
    if (Test-Connection -ComputerName $ComputerName -Quiet -Count 1) {
        do {
            try {
                Write-Verbose ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "Getting sync status...")
                $SyncStatus = Invoke-Command -ComputerName $ComputerName -ScriptBlock { Get-ADSyncConnectorRunStatus } -ErrorAction Stop

            } catch {
                Write-Warning ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "$($Error[0].Exception.Message)")

            } # END-TRY/CATCH

            if ($SyncStatus) {
                Write-Progress -Activity "Checking Sync Connector..." -Status "Progress:" -PercentComplete ($i / $TimeOut * 100)
                Start-Sleep -Seconds $iDelay
                $i = $i + $iDelay
                Write-Verbose ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "Sync Connector Busy. Delay $iDelay seconds and retry...")

            } # END if (-not $SyncStatus)

            # if the syncStatus is null or the timeout is reached.
        } until ((-not $SyncStatus) -or ( $i -ge $TimeOut))
    } else {
        Write-Warning ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "$($Error[0].Exception.Message)")
        Return

    } # END if (Test-Connection -ComputerName $ComputerName -Quiet)

    # SET: START SYNC CYCLE: --------------------------------------------------
    try {
        Write-Verbose ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "Starting Sync Cycle: [ $PolicyType ]")
        switch ($PolicyType) {
            'DELTA' {
                $Command = Invoke-Command -ComputerName $ComputerName -ScriptBlock { Start-ADSyncSyncCycle -PolicyType Delta } -ErrorAction Stop
            }
            'INITIAL' {
                $Command = Invoke-Command -ComputerName $ComputerName -ScriptBlock { Start-ADSyncSyncCycle -PolicyType Initial } -ErrorAction Stop

            }
        } # END switch ($PolicyType)

    } catch {
        Write-Warning ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "$($Error[0].Exception.Message)")

    } # END-TRY/CATCH

    # OUTPUT: -----------------------------------------------------------------
    Write-Output ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "Result: [ $($Command.Result) ]") -Verbose

} # END-FUNCTION function Start-xAADSync ######################################

Happy Coding!