Pull server name from ADFS eventlog and check LDAP connection

When it comes to ADFS, network connectivity to the global catalog servers is one of the most important aspects. You may often see in ADFS logs that LDAP server returned a specific error when it was queried or it’s even unresponsive.

As an engineer you need to determine either its temporary network connectivity problem or maybe something wrong with one of your Domain Controllers. I also had this problem so I decided to create script which will scan all GC connection errors in ADFS eventlog and to automatically check if LDAP connection is working fine.

List of ADFS events for LDAP connection failure can be found here.

Function:

function Get-LDAPEvents {
    [CmdletBinding()]
       
    param
    ( 
        [Parameter(Position=0, Mandatory=$true, HelpMessage="Server names", ValueFromPipeline = $true)] 
        [String[]]$servers,

        [Parameter(Position=1, Mandatory=$true, HelpMessage="Hours back", ValueFromPipeline = $true)] 
        [Int]$hours
    ) 
       
    $ErrorActionPreference = 'SilentlyContinue'
    $ComplexArray = @()

    # Get credentials for LDAP connection check
    $Cred = Get-Credential

    # Loop for servers
    ForEach($server in $servers)
    {
        Write-host "Checking $server" -ForegroundColor Green
    
        $hostname = " "             
        $hostname = [System.Net.Dns]::GetHostAddresses($Server)    
    
            If(!$hostname.ipaddresstostring)
            {
                Write-Warning "$Server does not exist"
            }
            Else
            {
                # Checking events related to LDAP Connection failure
                $ids = Invoke-Command $server -ScriptBlock{(Get-WinEvent -ProviderName 'AD FS' | Where {$_.ID -eq '247' -or $_.ID -eq '305' -or $_.ID -eq '306' -or $_.ID -eq '246' -and $_.TimeCreated -gt ((Get-Date).AddHours(-"$using:hours"))})}
             
                # If events not found display warninig message
                If(!$ids)
                {
                    Write-Warning "No events found"   
                } 
                Else 
                {
                    # If events found get event properties into PS object
                    ForEach($id in $ids)
                    {

                        $messageline = ($id.message -split '\n')[0]
                        $dc = ($id.message -split '\n')[4]
                        $dc = $dc.Split(":")[1]
                        $dc = $dc.Substring(1).Split(".")[0]
 
                        # Proceed if DC found
                        If($dc)
                        {
                            # Create a custom object 
                            $ComplexObject = New-Object PSCustomObject
                            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Server name" -Value $server
                            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Event ID" -Value $id.id
                            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Event date" -Value $id.timecreated
                            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Event Description" -Value $messageline
                            $ComplexObject | Add-Member -MemberType NoteProperty -Name "DC Name" -Value $dc
                
                            # Testing LDAP connection on port 3268
                            $LDAP = ("LDAP://" + "$dc" + ":3268")
                            $LDAPConnection = Invoke-Command $server -Authentication Credssp -Credential $Cred -ScriptBlock{param($LDAP)$ADSI = [ADSI]"$LDAP" ; $adsi } -args $LDAP
 
                            # Adding result into variable
                            If($LDAPConnection)
                            {
                                 $LDAPResult = "Connection successfull"    
                            }
                            Else
                            {
                                 $LDAPResult = "Connection failed"
                            }

                            # Add LDAP result to PS Object
                            $ComplexObject | Add-Member -MemberType NoteProperty -Name "LDAP Connection to DC" -Value $LDAPResult

                            # Add custom object to our array
                            $ComplexArray += $ComplexObject
                        }
                                
                    }

                }
    }
}
    If($ComplexArray)
    {
         $ComplexArray | Out-GridView -Title "LDAP Connection Errors"
    }
}

Usage:

Get-LDAPEvents -servers ADFS01,ADFS02 -hours 2

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.