Binding to a different active directory ldap instance in Powershell
Asked Answered
Z

2

8

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.

Zingale answered 27/8, 2014 at 1:35 Comment(0)
I
7

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

Immaterialism answered 10/10, 2014 at 14:31 Comment(3)
Sorry I haven't had a chance to test this yet. Things have gotten hectic. Will definitely get back to you.Zingale
Thanks and sorry for the delay. I haven't managed to get it working but at this point I think its an LDAP daemon config problem rather than a protocol issue. Your bind works great.Zingale
I could not make this function with this set to true.... are there any thoughts on changes that might have or need to be implemented over the last couple of years? $LDAPConnect.SessionOptions.SecureSocketLayer = $trueAutotype
A
0

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()

This also seems to work:

$username = "username"
$password = "****"

# $ldapPath = "LDAP://dc-dns-name/OU=userOU,DC=test,DC=com"

$directoryEntry = New-Object System.DirectoryServices.DirectoryEntry($ldapPath, $username, $password)

try {
    $directoryEntry.RefreshCache()
    Write-Host "ok"
}
catch {
    Write-Host "failed"
}
Assured answered 6/4, 2022 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.