Using ADSI to clear an attribute

I have many scripts that write information into Active Directory. Sometimes I need to do the opposite — remove or blank out an attribute.

All of the following examples will require a distinguishedName value in AD, so I will set a common variable here. You will need a valid distinguishedName defined in a varible like this if you want to follow along.

$distinguishedName = "CN=Brian Wuchner,OU=Test Users,DC=bwuch,DC=local"

The first test we will do is to update the displayName of the user. This is easy…we don’t care what the existing value is, we are just going to set it to whatever string value we want. We will do this by creating an object representing the Directory Entry of my user, updating the displayName attribute of that object and finally updating/committing that change back to the directory as follows.

1
2
3
$objUser = New-Object DirectoryServices.DirectoryEntry "LDAP://$distinguishedName"
$objUser.displayName="Wuchner, Brian"
$objUser.SetInfo()

That is a rather straight forward process. However, it becomes slightly more complex if we want to clear the attribute and make it null. One would think you could simply think you could set the displayName equal to $null using something like this:

1
2
$objUser = New-Object DirectoryServices.DirectoryEntry "LDAP://$distinguishedName"
$objUser.displayName=$null

However, if you try that you will most likely get a chance to see the following error message:

Exception setting "displayName": "Value cannot be null.

As a follow up, you might think “I’ll just set the attribute to an empty string” like this:

1
2
3
$objUser = New-Object DirectoryServices.DirectoryEntry "LDAP://$distinguishedName"
$objUser.displayName=""
$objUser.SetInfo()

The only problem with that…setinfo will fail with the following error.

setinfo : Exception calling "setinfo" with "0" argument(s): "The attribute syntax specified to the directory service is invalid.

Does that mean its time to give up? Are we just going to have to live with bad data in AD? Never!

There are at least two ways to clean this up. The first way is my favorite (I’ve been using it since vbscript). You simply need to refer to the Microsoft article HOW TO: Use ADSI to Set LDAP Directory Attributes and you’ll realize this can be accomplished with PutEx.

1
2
3
$objUser = New-Object DirectoryServices.DirectoryEntry "LDAP://$distinguishedName"
$objUser.PutEx(1, 'displayName', 0)
$objUser.SetInfo()

In the above example, we use the constant ADS_PROPERTY_CLEAR by placing a ‘1’ as the first argument in our method, then specifying the displayName as the attribute we want to clear, and finishing up by providing the desired value. Since we want the value to be clear, and we’ve already specified the ‘1’ to clear, we just need to specify something so the method has enough parameters. I use 0 just for fun.

Another option is to call the Remove method and specify the value we want to remove. The downside is the attribute MUST have a value or you get an error when trying to clear it. We can overcome that with a simple if statement like this:

1
2
3
4
5
$objUser = New-Object DirectoryServices.DirectoryEntry "LDAP://$distinguishedName"
if ($objUser.displayName) {
  $objUser.displayName.Remove("$($objUser.displayName)")
  $objUser.SetInfo()
}

It doesn’t matter which of the options I use, the end result is the same — a clear attribute. I hope this post helps if you ever need to clear out an attribute.

2 comments

  1. andreas engkvist says:

    Thanks for a greate article.
    Started to lose hope in powershell and AD, and than i found the light.

    Thanks for sharing.

  2. chandrashekar S says:

    Thanks i implemented this using powershell and it worked perfectly.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Notify me of followup comments via e-mail. You can also subscribe without commenting.