If you want to change the value of certain attributes for a large number of objects in Active Directory, you can automate this process with PowerShell. While this is fairly straightforward for single values, more effort is required for multivalued attributes.

An update for certain user attributes may be due when the address of the company or a branch changes or when the company is internally reorganized. There are also cases when the existing values of one attribute should be copied onto another. This happens, for example, when you want to have certain phone numbers copied to another field.

Copying displayName to displayNamePrintable

A requirement like this also arises if you want to use different display names for internal and external email in Exchange. Even if you only want selected users to benefit from this feature, you should still make sure that all accounts have a value for the SimpleDisplayName attribute.

One solution would be to copy the contents of displayName to SimpleDisplayName. This could be done as follows:

$users = Get-ADObject -Filter "ObjectCategory -eq 'person'"  -SearchBase 'OU=IT,DC=contoso,DC=com'  `
-Properties DisplayName, DisplayNamePrintable

foreach($user in $users){
    if($user.displayNamePrintable -eq $null){
        $user.displayNamePrintable = $user.displayName
        Set-ADObject -Instance $user 
    }
    else{
        "The displayNamePrintable for " + $user.name + " is already" + $user.displayNamePrintable
        }
}

The script uses Get-ADObject to read all user accounts from the organizational unit (OU) "IT" and checks each of them to see whether it already has a value for displayNamePrintable. If it doesn't, then it writes the contents of displayName into this attribute.

For all users of the OU IT copy the value from displayName to displayNamePrintable if it is still empty

For all users of the OU IT copy the value from displayName to displayNamePrintable if it is still empty

Attribute as parameter name of Set-ADUser

Unlike displayNamePrintable, you can resort to a simpler solution for many other attributes. The Set-ADUser cmdlet provides parameters with the names of the attributes, such as StreetAddress in the following example:

Get-ADUser -Filter "StreetAddress -eq 'My Street 3'"|
Set-ADUser -StreetAddress "Other Street 1"

This script would change the street address to "Other Street 1" for all accounts whose value has been "My Street 3" so far.

Editing attributes of the multivalued type

When assigning a value to the attribute displayNamePrintable, you normally ensure that any existing content is not accidentally overwritten. If it's empty, then you update this attribute.

Unlike displayNamePrintable, however, many other attributes accept multiple values. In this case, an assignment such as in the example above would destroy all existing content. For example, if several phone numbers are stored under otherHomePhone, then

$user.otherHomePhone = "+498912345"
Set-ADObject -Instance $user

would overwrite all phone numbers stored there.

So, if you want to add another number to the existing ones, you have to use different means. Both Set-ADUser and Set-ADObject support the parameter Add for this purpose:

$users = Get-ADUser -Filter "name -like '*'" -SearchBase 'OU=IT,DC=contoso,DC=com' -Properties *
foreach($user in $users){
        Set-ADUser -Identity $user.DistinguishedName -Add @{otherHomePhone = $user.homePhone}
    }

In this example, the script copies the value from the homePhone attribute to otherHomePhone. Such a call to Set-ADUser with the Add parameter also works for attributes of the SingleValued type; however, you can have the same result more easily there, as shown above.

AD User and Computer shows that otherHomePhone can store multiple values

AD User and Computer shows that otherHomePhone can store multiple values

In the case of attributes with multiple values, you have to execute all operations such that only those that you actually want to change are affected. This applies to the removal of certain entries, for example.

$users = Get-ADUser -Filter "name -like '*'" -SearchBase 'OU=IT,DC=contoso,DC=de' -Properties *
foreach($user in $users){
Set-ADUser -Identity $user.DistinguishedName -Remove @{otherHomePhone = $user.homePhone}
    }

This script would delete the phone number stored in homePhone from otherHomePhone.

If you want to replace an existing value with a new one, then you could combine Remove with Add. Both parameters are allowed within one command, and Remove is always executed before Add.

In addition, both of the mentioned cmdlets have a Replace parameter. However, its purpose is not to replace individual values, but the entire content of an attribute. For this purpose, a simple hash table is sufficient for a single-valued attribute:

Set-ADUser -Identity $user.DistinguishedName -Replace @{homePhone = "+498967890"}

However, you assign an array to multivalued attributes:

Set-ADUser -Identity $user.DistinguishedName `
-Replace @{otherHomePhone = @("+498967890", $user.HomePhone, "+4991101234")}
To write multiple values to a multi valued attribute simply pass it an array

To write multiple values to a multi valued attribute simply pass it an array

Deleting attribute values

If you don't want to write a value in an attribute, but delete its content, you can do so using the Clear parameter of Set-ADObject:

$users = Get-ADUser -Filter "name -like '*'" -SearchBase 'OU=IT,DC=contoso,DC=com' `
-Properties DisplayNamePrintable

foreach($user in $users){
    if($user.displayNamePrintable -ne $null){
        Set-ADObject -Identity $user.DistinguishedName -clear displayNamePrintable
    }
}

This example shows the procedure for a single-valued attribute, but also works for those that store multiple values.

How to determine attribute type

Since single- and multivalued attributes require different operations for removing, adding, and replacing values, the question arises as to how to recognize the two types. However, this cannot be done by simply querying a PowerShell object property.

Microsoft's TechNet provides a script that lists all attributes of an AD object and tells you whether it can contain single or multiple values. Here, you change the assignment in the first line to use one of the objects you want to edit later.

Subscribe to 4sysops newsletter!

# Bind to the Active Directory object specified
$ObjectDN = "cn=Jack Ma,ou=Sales,dc=contoso,dc=com"
$ADObject = [ADSI]"LDAP://$ObjectDN"

# Determine the object class.
$Schema = [DirectoryServices.ActiveDirectory.ActiveDirectorySchema]::GetCurrentSchema()
$Class = $ADObject.objectClass.ToString().Split(" ")[-1]

# Retrieve attributes for this class from the Schema.
$ManAttributes = $Schema.FindClass("$Class").MandatoryProperties | Out-GridView
$OptAttributes = $Schema.FindClass("$Class").OptionalProperties | Out-GridView
The script shows which attributes are single valued for a given object

The script shows which attributes are single valued for a given object

If executed successfully, it opens two windows with Out-GridView in which the IsSingleValued column provides information about the attribute's type.

avataravatar
0 Comments

Leave a reply

Please enclose code in pre tags

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account