PeoplePickerPortProber.psm1
<#
.SYNOPSIS Start-PeoplePickerPortProber .DESCRIPTION Start-PeoplePickerPortProber resolves domain names, checks for open ports, and queries user objects to determine if SharePoint can contact the Domain Controller(s). .PARAMETER LdapPath Provide the LDAP path to connect to the domain. .PARAMETER LdapPort The LDAP port for the Domain Controller(s). .PARAMETER LdapsPort The LDAPS port for the Domain Controller(s). .PARAMETER LdapFilter The LDAP filter to use. .PARAMETER FindOne Restrict the LDAP search to a single object. Default true. .PARAMETER Credential Credentials used to connect to the Domain Controllers. .PARAMETER Timeout The time to wait to open connections to ports. .EXAMPLE Start-PeoplePickerPortProber -LdapPath 'LDAP://DC=example,DC=com' -Credential (Get-Credential) .EXAMPLE Start-PeoplePickerPortProber -LdapPath 'LDAP://DC=subdomain,DC=example,DC=com' -LdapFilter '(&(objectClass=User))' .NOTES Author: Trevor Seward Date: 09/15/2018 https://thesharepointfarm.com https://github.com/Nauplius #> Function Start-PeoplePickerPortProber { param ( [string] [ValidatePattern('(?i)^ldap(?-i)://.*(?i)DC(?-i)=.*')] [Parameter(Mandatory=$true)] $LdapPath, [int32] [Parameter(Mandatory=$false)] $LdapPort = 389, [int32] [Parameter(Mandatory=$false)] $LdapsPort = 636, [string] [Parameter(Mandatory=$false)] $LdapFilter = "(&(objectClass=user)(objectCategory=user))", [switch] [Parameter(Mandatory=$false)] $FindOne, [pscredential] $Credential, [int32] [Parameter(Mandatory=$false)] $Timeout = 200 ) $dnsName = Get-DnsName $LdapPath if($dnsName -eq '') { break } Write-Host -ForegroundColor Cyan "Resolved domain: $($dnsName)" $IPs = Test-Dns $dnsName foreach($IP in $IPs) { Test-Ports $IP $LdapPort $LdapsPort } Invoke-LdapSearch $LdapPath $LdapFilter $Credential $FindOne } Function Get-DnsName { param ( [string] [Parameter(Mandatory=$true)] $LdapPath ) $LdapPath = $LdapPath.ToLowerInvariant() $str = $LdapPath.Remove(0,$LdapPath.IndexOf('dc=')) $dnsName = $str.Replace('dc=','').Replace(',','.') return $dnsName } Function Test-Dns { param ( [string] [Parameter(Mandatory=$true)] $dnsName ) $IPs = @([System.Net.Dns]::GetHostAddresses($dnsName)) foreach($IP in $IPs) { try { $hostName = ([System.Net.Dns]::GetHostEntry($IP)).HostName Write-Host("$($IP) [$($hostName)]") } catch { Write-Host -ForegroundColor Red "Unable to resolve hostname for $($IP)" } } return $IPs } Function Test-Ports { param ( [string] [Parameter(Mandatory=$true)] $IPAddr, [int32] [Parameter(Mandatory=$true)] $LdapPort, [int32] [Parameter(Mandatory=$true)] $LdapsPort ) $tcpPorts = @($LdapPort, $LdapsPort, 135, 137, 138, 139, 3268, 3269, 53, 88, 445, 749, 750) foreach($tcpPort in $tcpPorts) { [string]$optionalPort if ($tcpPort -eq 749 -or $tcpPort -eq 750) { $optionalPort = "[Opt]" } [System.Net.Sockets.Socket]$socket = $null $socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InternetWork, [System.Net.Sockets.SocketType]::Stream, [System.Net.Sockets.ProtocolType]::Tcp) $socket.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::Socket, [System.Net.Sockets.SocketOptionName]::DontLinger, $false) [System.IAsyncResult]$result = $socket.BeginConnect($IPAddr, $tcpPort, $null, $null) [bool]$connected = $result.AsyncWaitHandle.WaitOne($timeout, $true) if($connected -eq $true) { Write-Host -ForegroundColor Green "$($IPAddr)`t:$($optionalPort)TCP/$($tcpPort) connected." -NoNewline } else { Write-Host -ForegroundColor Red "$($IPAddr)`t:$($optionalPort)TCP/$($tcpPort) failed." -NoNewline } $optionalPort = '' } Write-Host '' } Function Invoke-LdapSearch { param ( [string] [Parameter(Mandatory=$true)] $LdapPath, [string] [Parameter(Mandatory=$false)] $LdapFilter, [pscredential] $Credential, [bool] [Parameter(Mandatory=$false)] $FindOne = $true ) $de = New-Object System.DirectoryServices.DirectoryEntry($LdapPath.ToUpper()) if($Credential) { [System.IntPtr] $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password) $de.Username = $Credential.UserName $de.Password = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr) [System.Runtime.InteropServices.Marshal]::FreeBSTR($bstr) $de.AuthenticationType = [System.DirectoryServices.AuthenticationTypes]::Secure } $ds = New-Object System.DirectoryServices.DirectorySearcher($de) $ds.Filter = $LdapFilter $ds.SearchScope = [System.DirectoryServices.SearchScope]::Subtree $ds.PageSize = 100 $ds.ReferralChasing = [System.DirectoryServices.ReferralChasingOption]::All if($FindOne) { [System.DirectoryServices.SearchResult]$sr = $ds.FindOne() $dEntry = $sr.GetDirectoryEntry() Write-Host $dEntry.Path } else { [System.DirectoryServices.SearchResultCollection]$sc = $ds.FindAll() foreach($sr in $sc) { Write-Host $sr.Path } } } Export-ModuleMember -Function * |