Issue

Get the current status and version of the AAD Connect Sync Connector.
Check for sync connector or run profile issues.

Solution

Checking the AAD Connect Sync Connector status, performing event log lookups for common warnings or errors for Directory Synchronization and AAD Sync, with PowerShell.

High Level Overview
  1. Check the AAD Connect Server is reachable.
  2. Capture the ADSync Global Settings parameters.
  3. Check common Directory Sync and AD Sync event logs for warnings or errors.
  4. Output the status. Use Get-Date to use current culture to format DateTime and standardise format strings.
Code:


function Get-xAADSyncStatus {
    <#
.SYNOPSIS
    Check status and event logs for Directory Synchronisation/AD Sync warnings or errors.

.DESCRIPTION
    Check status and event logs for Directory Synchronisation/AD Sync warnings or errors.
    Check version status and schedules.

.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

    #>

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

    # DEFINITIONS: ------------------------------------------------------------
    $OffSet = 0 - $ComputerName.Length

    # GET: CHECK SYNC STATUS: -------------------------------------------------
    # Check the server is reachable.
    # Check the sync status.
    Write-Verbose ("{0,$OffSet} : {1}" -f "[ $ComputerName ]", "Check connectivity to the server... ")
    if (Test-Connection -ComputerName $ComputerName -Quiet -Count 1) {
        # Get the ADSyncGlobalSettings parameters.
        try {
            Write-Verbose ("{0,$OffSet} : {1}" -f "[ $ComputerName ]", "Get ADSyncGlobalSettings parameters. ")
            $ADSyncGlobalSettings = Invoke-Command -ComputerName $ComputerName -ScriptBlock { (Get-ADSyncGlobalSettings).Parameters } -ErrorAction Stop
            $SyncSchedule = (Get-ADSyncScheduler).CurrentlyEffectiveSyncCycleInterval.Minutes
        }
        catch {
            Write-Warning ("{0,-40} : {1}" -f "[ $ComputerName ]", "$($Error[0].Exception.Message)")
            Break

        } # END try/catch


        Write-Verbose ("{0,$OffSet} : {1}" -f "[ $ComputerName ]", "Check the last scheduled sync operation... ")
        $LastScheduledSyncParams = @{
            LogName      = "Application"
            ProviderName = "Directory Synchronization"
            ID           = "904"
            Data         = "Finished"

        } # END $LastScheduledSyncParams

        $LastScheduledSync = Get-WinEvent -ComputerName $ComputerName -MaxEvents 1 -FilterHashtable $LastScheduledSyncParams

        # GET: CHECK SYNC ERRORS: ---------------------------------------------
        # Check and capture the last connector sync error eventlog. Event ID 6100.
        Write-Verbose ("{0,$OffSet} : {1}" -f "[ $ComputerName ]", "Check for Run Profile error... ")
        $RunProfileErrorParams = @{
            LogName      = "Application"
            ProviderName = "ADSync"
            ID           = "6100"
            StartTime    = (Get-Date).AddMinutes(0 - $SyncSchedule)

        } # END $LastSuccessfulSyncParams

        $RunProfileError = Get-WinEvent -ComputerName $ComputerName -MaxEvents 1 -FilterHashtable $RunProfileErrorParams -ErrorAction SilentlyContinue

        # GET: CHECK MANAGEMENT PROFILE WARNING: ------------------------------
        # Check and capture the last connector sync error eventlog. Event ID 6127.
        # Usually, due to the configuration change that requires Initial Sync to update the profile.
        Write-Verbose ("{0,$OffSet} : {1}" -f "[ $ComputerName ]", "Check for sync connector warning... ")
        $RunProfileWarningParams = @{
            LogName      = "Application"
            ProviderName = "ADSync"
            ID           = "6127"
            StartTime    = (Get-Date).AddMinutes(0 - $SyncSchedule)

        } # END $LastSuccessfulSyncParams

        $RunProfileWarning = Get-WinEvent -ComputerName $ComputerName -MaxEvents 1 -FilterHashtable $RunProfileWarningParams -ErrorAction SilentlyContinue

        # GET: CHECK OBJECT EXPORT ERRORS: ------------------------------------
        # Check and capture the last connector sync error eventlog. Event ID 6803.
        # Usually, due to DataValidationFailed, InvalidSoftMatch, AttributeValueMustBeUnique. Event ID 6941 has more
        # details but more entries if many errors. Using the generic 6803 as a flag to investigate further.
        Write-Verbose ("{0,$OffSet} : {1}" -f "[ $ComputerName ]", "Check for generic object errors during export... ")
        $ExportStepErrorsParams = @{
            LogName      = "Application"
            ProviderName = "ADSync"
            ID           = "6803"
            StartTime    = (Get-Date).AddMinutes(0 - $SyncSchedule)

        } # END $ExportStepErrorsParams

        $ExportStepError = Get-WinEvent -ComputerName $ComputerName -MaxEvents 1 -FilterHashtable $ExportStepErrorsParams -ErrorAction SilentlyContinue

    }
    else {
        # Unable to connect to AAD Connect Server. Output Warning and Break.
        Write-Warning ("{0, $OffSet} : {1}" -f "[ $ComputerName ]", "$($Error[0].Exception.Message)")
        Return

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

    # OUTPUT: -----------------------------------------------------------------
    # Use Get-Date to use current culture to format DateTime and standardise format strings.
    $Output = [pscustomObject][ordered]@{
        Version                  = $ADSyncGlobalSettings.Where( {$_.Name -eq 'Microsoft.Synchonize.ServerConfigurationVersion'}).Value
        AutoUpgrade              = $ADSyncGlobalSettings.Where( {$_.Name -eq 'Microsoft.OptionalFeature.AutoUpgradeState'}).Value
        LastScheduledSync        = Get-Date $($LastScheduledSync.TimeCreated)
        NextScheduledSync        = Get-Date $ADSyncGlobalSettings.Where( {$_.Name -eq 'Microsoft.Synchronize.NextStartTime'}).Value
        SyncSchedule             = $SyncSchedule
        RunProfileError          = if ($RunProfileError) { Get-Date $($RunProfileError.TimeCreated) } else { $null }
        RunProfileErrorMessage   = $RunProfileError.Message
        RunProfileWarning        = if ($RunProfileWarning) { Get-Date $($RunProfileWarning.TimeCreated) } else { $null }
        RunProfileWarningMessage = $RunProfileWarning.Message
        ExportStepError          = if ($ExportStepError) { Get-Date $($ExportStepError.TimeCreated) } else { $null }
        ExportStepErrorMessage   = $ExportStepError.Message
    } # END Output

    Return $Output

} # END function Get-xAADSyncStatus ###########################################

Happy Coding!