'Binding to a different active directory ldap instance in Powershell

I am trying to connect to some independent LDAP stores (ADAM - Active Directory Application Mode) using a specific set of credentials to bind with, but having trouble working out the best way to do this. Here is an example which I had hoped would work:

$ldapHost = New-Object System.DirectoryServices.DirectoryEntry("LDAP://{serverip}:{port}/dc=acme,dc=com","cn=myuser,dc=acme,dc=com","myPassw0rd")
$ldapQuery = New-Object System.DirectoryServices.DirectorySearcher
$ldapQuery.SearchRoot = $ldapHost
$ldapQuery.Filter = "(objectclass=*)"
$ldapQuery.SearchScope = "Base"
$ldapQuery.FindAll()

This will get me:

Exception calling "FindAll" with "0" argument(s): "A local error has occurred.
"
At line:1 char:19
+ $ldapQuery.FindAll <<<< ()
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException    

I also tried:

$ldapHost = New-Object System.DirectoryServices.DirectoryEntry("LDAP://{myip}:{port}/dc=acme,dc=com")
$ldapHost.Username = "cn=myuser,dc=acme,dc=com"

which results:

The following exception occurred while retrieving member "Username": "The specified directory            service attribute or valu
e does not exist.
"
At line:1 char:11
+ $ldapHost. <<<< Username = "cn=myuser,DC=acme,dc=com"
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException

I've tried a few variations with filter etc. Most of the documentation I can find on this just assumes that I'm connecting to ldap from within the same directory/am connecting with the correct user for the query.

If you're familiar with Python's ldap module, this is how I do it in that:

import ldap
ld = ldap.initialize("ldap://{myip}:{port}")
ld.bind_s("cn=myuser,dc=acme,dc=com","Passw0rd")
ld.search_s("dc=acme,dc=com",ldap.SCOPE_BASE,"objectclass=*")

Any pointers on how to approach this? I can definitely connect via the various LDAP clients out there. I might need to explicitly specify authentication, but I'm not sure because there is so little information on querying from outside the domain.



Solution 1:[1]

You can try this...I use it to connect to an OpenLDAP instance and it works well. Works against AD also so it should fit your needs. You'll need to update the $basedn variable and the host/username ones.

$hostname = ''
$username = ''

$Null = [System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols")
#Connects to LDAP
$LDAPConnect = New-Object System.DirectoryServices.Protocols.LdapConnection "$HostName"

#Set session options (SSL + LDAP V3)
$LDAPConnect.SessionOptions.SecureSocketLayer = $true
$LDAPConnect.SessionOptions.ProtocolVersion = 3

# Pick Authentication type:
# Anonymous, Basic, Digest, DPA (Distributed Password Authentication),
# External, Kerberos, Msn, Negotiate, Ntlm, Sicily
$LDAPConnect.AuthType = [System.DirectoryServices.Protocols.AuthType]::Basic

# Gets username and password.
$credentials = new-object "System.Net.NetworkCredential" -ArgumentList $UserName,(Read-Host "Password" -AsSecureString)
# Bind with the network credentials. Depending on the type of server,
# the username will take different forms.
Try {
$ErrorActionPreference = 'Stop'
$LDAPConnect.Bind($credentials)
$ErrorActionPreference = 'Continue'
}
Catch {
Throw "Error binding to ldap  - $($_.Exception.Message)"
}


Write-Verbose "Successfully bound to LDAP!" -Verbose
$basedn = "OU=Users and Groups,DC=TEST,DC=NET"
$scope = [System.DirectoryServices.Protocols.SearchScope]::Subtree
#Null returns all available attributes
$attrlist = $null
$filter = "(objectClass=*)"

$ModelQuery = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList $basedn,$filter,$scope,$attrlist

#$ModelRequest is a System.DirectoryServices.Protocols.SearchResponse
Try {
$ErrorActionPreference = 'Stop'
$ModelRequest = $LDAPConnect.SendRequest($ModelQuery) 
$ErrorActionPreference = 'Continue'
}
Catch {
Throw "Problem looking up model account - $($_.Exception.Message)"
}

$ModelRequest

Credit for most of this goes here..

http://mikemstech.blogspot.com/2013/03/searching-non-microsoft-ldap.html

Solution 2:[2]

This worked for me. Only use this for testing purposes since password is not secured at all.

Add-Type -AssemblyName System.DirectoryServices.Protocols

$server = test.com
$username = "CN=username,OU=users,DC=test,DC=com"
$password = "userpassword"

$Credentials = new-object System.Net.NetworkCredential($username, $password)
$LdapConnection = New-Object System.DirectoryServices.Protocols.LdapConnection $server
# Basic auth, cleartext password using port 389
$LdapConnection.AuthType = [System.DirectoryServices.Protocols.AuthType]::Basic
$LdapConnection.Bind($Credentials)
$LdapConnection.Dispose()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jim Björklund