Powershell - Getting started pulling LDAP data from eDirectory

2 Likes

Below is a working example of getting started pulling LDAP values in a readable format. Change your filter to make sense for the query you need.

 

Here is the script below. I can't take credit for the majority of the code, I had to take pieces from a few places. Feel free to use and improve.

function Expand-Collection {
# Simple helper function to expand a collection into a PowerShell array.
# The advantage to this is that if it's a collection with a single element,
# PowerShell will automatically parse that as a single entry.
[CmdletBinding()]
param(
[Parameter(Mandatory,
Position = 0,
ValueFromPipeline,
ValueFromRemainingArguments)]
[ValidateNotNull()]
[Object[]] $InputObject
)

process {
foreach ($i in $InputObject) {
ForEach-Object -InputObject $i -Process { Write-Output $_ }
}
}
}

# Parameters to be set
$ServerName = "x.x.x.x"
$basedn = "ou=users,o=data"
$SSLPort = 636
$attrlist = ,'*'
$filter = "(&(cn=mjones)(objectClass=inetOrgPerson))"
$scope = [System.DirectoryServices.Protocols.SearchScope]::Subtree

# Start of Program
$ErrorActionPreference = 'Stop'
$UserName = Read-Host "User login via LDAP context"
$Password = Read-Host "Enter Password" -AsSecureString

# Requiring SSL and LDAP Auth
$ActivateSSL = $True
$LDAP_Auth = $True
$c = New-Object System.DirectoryServices.Protocols.LdapConnection ("$ServerName" ":" "$SSLPort")
$c.SessionOptions.SecureSocketLayer = $True
$c.SessionOptions.VerifyServerCertificate = { $True }
$c.SessionOptions.ProtocolVersion = 3
$c.AuthType = [System.DirectoryServices.Protocols.AuthType]::Basic
$credentials = new-object "System.Net.NetworkCredential" -ArgumentList $UserName,$Password

Try {
if ($credentials -eq $null) { $c.Bind() }
else {
Write-Host "ready to bind: "
$c.Bind($credentials)
}
Write-Host "Connection Successful"
}
Catch {
Throw "A Problem during connection to LDAP - $($_.Exception.Message)"
}

$attrType = [string]

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

Try {
$ModelRequest = $c.SendRequest($ModelQuery)
}
Catch {
$ModelRequest = $null
Throw "Problem looking up model account - $($_.Exception.Message)"
}
$ModelRequest.Entries[0].Attributes

Write-Output("Total Entries found: " $ModelRequest.Entries.Count)

Write-Output "Get-LdapObject Sending LDAP request"

if (-not $ModelRequest) {
Write-Verbose "No response was returned from the LDAP server."
return
}

if ($ModelRequest.ResultCode -eq 'Success') {
if ($Raw) {
Write-Output ($ModelRequest.Entries)
}
else {
# Convert results to a PSCustomObject.
foreach ($e in $ModelRequest.Entries) {
$hash = @{
PSTypeName = 'LdapObject'
DistinguishedName = $e.DistinguishedName
# Controls = $e.Controls # Not actually sure what this is
}

# Attributes are returned as an instance of the class
# System.DirectoryServices.Protocols.DirectoryAttribute.
# Translate that to a more PowerShell-friendly format here.
foreach ($a in $e.Attributes.Keys | Sort-Object) {
Write-Output "Get-LdapObject Adding type [$a]"
$hash[$a] = $e.Attributes[$a].GetValues($attrType) | Expand-Collection
}

Write-Output ([PSCustomObject] $hash)
#([PSCustomObject] $hash) | Export-Csv -Path .\Processes.csv -Delimiter '|' -NoTypeInformation Get-Content -Path .\Processes.csv
#write out current object value stored in $hash.<attribute>
Write-Output $hash.jobcode
}
return
}
}

 

Comment List
  • Couple changes:  Insert the below two lines after # Start of Program... This was missing

    [System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols") | Out-Null
    [System.Reflection.Assembly]::LoadWithPartialName("System.Net") | Out-Null

     

    Also, the client timeout setting has some default, not sure what it is, I'm guessing less than 60 seconds. To set the client timeout setting use the following logic:

    $changeTimeOut = New-TimeSpan -Seconds 600

    Try {
    $ModelRequest = $c.SendRequest($ModelQuery, $changeTimeOut)

     

     

     

Related
Recommended