Can anyone point me in the correct direction regarding binding to an
LDAP-compliant directory that is not Active Directory while using
PowerShell? I've read the docs on DirectorySearcher and DirectoryEntry and
they seem only able to connect to AD. Basically, I have a VBScript that I'd
like to port to PowerShell. The VBScript uses the OpenDSObject method, which
I cannot seem to figure out how to use in PowerShell. The line from the
VBScript is:
Set dso = GetObject("LDAP:")
Set objGroup =
dso.OpenDSObject("LDAP://myserver.mycompany.com/cn=users,o=MyCompany,c=US")
Is it possible to create a DSO object in PowerShell using the new-object
cmdlet, and if so how? If it's not possible to create a DSO object, does
anyone know another way to connect to the directory via PowerShell?
Tom G.
$root = [ADSI]"LDAP://myserver/dc=mycompany,dc=com" #OR
$root = [ADSI]"LDAP://myserver/OU=People,dc=mycompany,dc=com" #OR
$root = [ADSI]"LDAP://OU=standard,OU=People,dc=mycompany,dc=com"
then, if I want to search
$searchAD = new-object
System.DirectoryServices.DirectorySearcher($root)
$searchAD.PageSize = 10000
$searchAD.Filter = "(`&(objectClass=computer)(cn=pc1))"
$searchResults = $searchAD.FindAll()
if there is only a result, and I want to have it as an DirectoryEntry
$DirEntry = $($searchAD.FindAll()).getDirectoryEntry() #OR
foreach ($result in $searchResults){
$temp = $result.getDirectoryEntry()
}
if I want to connect directly to an object:
$dn = [ADSI]"LDAP://cn=pc1,ou=computers,dc=mycompany,dc=com"
$DirEntry = new-object DirectoryServices.DirectoryEntry($dn)
Hope it can help you a bit.
Jorge Mestre
"Tom G." <Tom.Gl...@Sanford.com> wrote in message
news:ONC3dLUH...@TK2MSFTNGP06.phx.gbl...
You can do this with Netcmdlets get-ldap and set-ldap cmdlets. If
interested you can check out the beta at
http://www.nsoftware.com/powershell/. Keep in mind that it is a beta
and we are making some changes to the syntax of the cmdlets, the output
objects, as well as adding some new functionality like -changepwd. If
you have questions let me know and I can help.
I don't know of a general LDAP server that I can test against, but there are
2 possible ways to approach this. The following is based on the assumption
that .NET's System.DirectoryServices namespace does not support easy "pure"
LDAP server access.
(1) Use inline VBScript with the script control.
This will allow you to directly retrieve an object instance. I can't test
the OpenDSObject statement, but the following form _should_ work with a
usable URL. (Bruce Payette talks about in-lining ActiveScript languages such
as VBScript within PowerShell to do tasks that .NET's COM wrappers won't
handle).
Here's an example:
$sc = New-Object -ComObject MSScriptControl.ScriptControl
$sc.Language = "VBScript"
$sc.AddCode('set ldap = GetObject("LDAP:")')
#next line wraps
$sc.AddCode('url =
"LDAP://myserver.mycompany.com/cn=users,o=MyCompany,c=US"')
$dso = $sc.Eval('ldap.OpenDSObject(url)')
Warning: this may not work very well for getting back something functional
due to how nasty .NET gets about COM objects it doesn't understand. For
example, if I try to do this:
$ldap = $sc.Eval('ldap')
$ldap | gm
I get the dreaded "Get-Member : No object has been specified to get-member"
error that shows up a lot in COM interop.
IF you want to use method 1 and it gives you this error when you look at
$dso (as I suspect it will) you'll need to get the data you need within
VBScript code and turn it into something you can return.
A variation of this is to load the Microsoft.VisualBasic assembly and use
VB.NET's GetObject from PowerShell instead. This has the same problems with
COM objects, so I recommend you use another alternative.
(2) Possibly use Novell's generic LDAP server library for .NET
See the following pages:
http://www.novell.com/coolsolutions/feature/11204.html
http://forge.novell.com/modules/xfcontent/downloads.php/ldapcsharp/ldapcsharp/CsharpLDAP-v2.1.7/
This looks like it should provide working direct access to any LDAP-standard
server. Since it is also open code (MIT license) it has some promise for
longterm support. If you want to try this yourself and can't find a binary
or compile the source, holler. :)
Tom G.
"Alex K. Angelopoulos [MVP]" <a...@online.mvps.org> wrote in message
news:OIC38FhH...@TK2MSFTNGP04.phx.gbl...
The NetCmdlets are pretty cool. However, I'm having some trouble
authenticating. I need to pass in a username in the format of
"cn=userid,o=orgname,c=US". The credential parameter in get-ldap doesn't
seem to support this. Any suggestions?
Tom G.
"Lance" <lmro...@gmail.com> wrote in message
news:1165942782.2...@j44g2000cwa.googlegroups.com...
set-variable "ADS_SCOPE_BASE" 0 -op Constant
set-variable "ADS_SCOPE_ONELEVEL" 1 -op Constant
set-variable "ADS_SCOPE_SUBTREE" 2 -op Constant
[reflection.assembly]::LoadWithPartialName("system.directoryservices.protocols") | out-null
$li = new-object
directoryservices.protocols.ldapdirectoryidentifier("server-address")
$lc = new-object directoryservices.protocols.ldapconnection($li,$null,0)
[string[]]$attr = "cn","mail" # -- attributes to be returned
$dn = "o=your.search.base" # -- distinguished name (search base)
$filter = "(uid=aname)" # -- what to look for
$scope = $ADS_SCOPE_SUBTREE # -- search sub-tree
$sr = new-object
directoryservices.protocols.searchrequest($dn,$filter,$scope,$attr)
$sr.typesonly = $false
$sr.sizelimit = 10
$resp = [directoryservices.protocols.searchresponse]$lc.sendrequest($sr)
$e = $resp.entries
Write-host "Name:" ($e[0].attributes["cn"])[0]
Write-host "E-mail:" ($e[0].attributes["mail"])[0]
Took me a while to figure this out, but it seems to work.
// Ted Brewster
--- Computing Services - Binghamton University ---
FYI for anyone else playing with LDAP, Wikipedia seems to have a _lot_ of
useful resource links:
http://en.wikipedia.org/wiki/LDAP
"Tom G." <Tom.Gl...@Sanford.com> wrote in message
news:Onj4TDkH...@TK2MSFTNGP06.phx.gbl...
[Reflection.Assembly]::LoadFile("C:\dump\CsharpLDAP-v2.1.7\lib-v2.1.7\Novell.Directory.Ldap.dll")
| out-null
$ldap = new-object Novell.Directory.Ldap.LdapConnection
$version = [Novell.Directory.Ldap.LdapConnection]::Ldap_V3
$port = [Novell.Directory.Ldap.LdapConnection]::Default_Port
$scope = [Novell.Directory.Ldap.LdapConnection]::Scope_One
$filter = "(objectclass=*)"
$attrs = [Novell.Directory.Ldap.LdapConnection]::All_User_Attrs
$ldap.connect("servername.domain.com", $port)
$ldap.bind($version, "cn=user,o=orgname,c=US", "password")
$results = $ldap.Search("o=orgname,c=US", $scope, $filter, $attrs, $true)
while ($results.hasMore())
{
$results.next()
}
$ldap.Disconnect()
$ldap = $null
Tom G.
"Alex K. Angelopoulos [MVP]" <a...@online.mvps.org> wrote in message
news:OG590u4...@TK2MSFTNGP06.phx.gbl...
Just for the benefit of anyone else who was trying this: Tom and I
have exchanged emails, but for the benefit of anyone else who was
interested:
get-ldap and set-ldap allow you to provide authentication info to the
cmdlet in two ways: 1: through dn and password parameters, or 2:
through a credential parameter that takes a standard PSCredential
object.
The problem with using the credential method was that if you were a non
Active Directory user, and you didn't have an alias like MyDomain\Lance
to authenticate with - get-credentials pop-up dialog wouldn't accept
your full DN as valid input.
Tom pointed out the "ConsolePrompting" registry string value ("True")
in HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\, which tells
get-credentials to take its input from the console instead of the
pop-up dialog. Doing it this way allows you to specify a full DN as
the username.
To bind to the directory server:
PS> $mycred = get-credential -credential "cn=Lance,ou=Employees,dc=NS"
...
...
...
PS> get-ldap -server testboy -cred $mycred
To bind and then search for a user (BillyBob) in the Employees
organizational unit:
PS> get-ldap -server testboy -cred $mycred -dn "ou=Employees,dc=NS"
-search "cn=BillyBob"
To bind, perform the same search, and return all attributes of the
user:
PS> get-ldap -server testboy -cred $mycred -dn "ou=Employees,dc=NS"
-search "cn=BillyBob" -attr