m4xh
m4xh

Reputation: 33

How to replace/update the Value of an Attribute in LDAP Directory using PowerShell?

The entries in our companys Non-AD LDAP Server look like this:

uid = e145871
sn = Smith
givenName = John
department = Research & Development
department = Human Resource

And so on...

I've developed a PowerShell script to add specific attributes and values which is working just fine. Now I need to replace specific values but the issue is the identical attribute name. (In this case it's "department")

My goal is to replace "Research & Development" with "Something Else". If I run the following script it gets replaced but Human Resource is deleted as well. Is it possible to replace only one value without touching/deleting the other?

$r = New-Object -TypeName System.DirectoryServices.Protocols.ModifyRequest
$r.DistinguishedName = "uid=e145871,ou=identities,ou=users,o=items,dc=company,dc=domain,dc=com"

$DirectoryRequest_value = New-Object "System.DirectoryServices.Protocols.DirectoryAttributeModification"
$DirectoryRequest_value.Name = "department"
$DirectoryRequest_value.Contains("Research & Development")
$DirectoryRequest_value.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Replace
$DirectoryRequest_value.Add("SomethingElse")

$r.Modifications.Add($DirectoryRequest_value)

$result = $connection.SendRequest($r)

Thanks!

Upvotes: 0

Views: 2702

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174720

The LDAP Replace operation replaces (or overwrites) the entire value of the attribute, including any existing values that might exist as part of a multi-valued attribute.

From RFC4511 §4.6 - "Modify Operation":

-  operation: Used to specify the type of modification being
   performed.  Each operation type acts on the following
   modification.  The values of this field have the following
   semantics, respectively:

   [...]

       replace: replace all existing values of the modification
       attribute with the new values listed, creating the attribute
       if it did not already exist.  A replace with no value will
       delete the entire attribute if it exists, and it is ignored
       if the attribute does not exist.

Instead, add two separate modifications to the request - one to add "SomethingElse" and one to remove "Research & Development":

$targetObject = 'uid=e145871,ou=identities,ou=users,o=items,dc=company,dc=domain,dc=com'
$attributeName = 'department'
$oldValue = 'Research & Development'
$newValue = 'SomethingElse'

$request = [System.DirectoryServices.Protocols.ModifyRequest]::new()
$request.DistinguishedName = $targetObject

# This modification will add the new value "SomethingElse"
$addNewDepartment = @{
    Name = $attributeName
    Operation = 'Add'
} -as [System.DirectoryServices.Protocols.DirectoryAttributeModification]
$addNewDepartment.Add($newValue) |Out-Null

$request.Modifications.Add($addNewDepartment) |Out-Null

# This modification will remove the old value "Research & Development"
$removeOldDepartment = @{
    Name = $attributeName
    Operation = 'Delete'
} -as [System.DirectoryServices.Protocols.DirectoryAttributeModification]
$removeOldDepartment.Add($oldValue) |Out-Null

$request.Modifications.Add($removeOldDepartment) |Out-Null

$result = $connection.SendRequest($request)

Upvotes: 2

Related Questions