Goatee PFE

Blog of Microsoft Premier Field Engineer Ashley McGlone featuring PowerShell scripts for Active Directory.

How to copy AD user attributes to another field with PowerShell

How to copy AD user attributes to another field with PowerShell

  • Comments 8
  • Likes

TechMentor

Last week I spent some time working on my presentation for the TechMentor conference coming up in August.  It's not too late to get in on the action, and this year it's going to be in the heart of Microsoft country.  I hope to see you there.

Tapioca

Tapioca Goodness

I love tapioca pudding.  What does that have to do with Active Directory and PowerShell?!  Keep reading.

Duplicate Data Dosey Doh!

Have you ever needed to copy data between attributes in Active Directory? Maybe you need to copy an ExtensionAttribute value into a different ExtensionAttribute. Maybe you need to copy email, UPN, or SIP addresses. You may even want to move the EmployeeNumber value into the EmployeeID attribute instead. What if you needed to create a new Description based on a combination from other attributes?

Today’s post is a simple one-liner that could get you into a lot of trouble. Really. But hey, that could be said with any PowerShell code if not tested in a lab first. It could get you in trouble if you mass update the wrong attributes, so I’m warning you up front to keep the safety switch in the “on” position.

The Code

Get-ADUser is a rather handy cmdlet capable of retrieving precisely the target user population you wish to manipulate. For the exact syntax go look at Get-Help Get-ADUser. Also check out Get-Help about_ActiveDirectory_Filter. You can’t hurt too much with simple queries. Again, do this in your lab to craft the right combination of Filter (or LDAPFilter) and SearchBase. The same can be said of Get-ADObject if you want to manipulate any other AD object, so don’t limit yourself to just users here.

Import-Module ActiveDirectory            
            
# Find all accounts with a Department            
# Copy that value into Description            
Get-ADUser -LDAPFilter '(Department=*)' -Properties Description, Department |            
 Select-Object * -First 5 |            
 ForEach-Object {Set-ADObject -Identity $_.DistinguishedName ` 
  -Replace @{Description=$($_.Department)}}

Our one-liner takes the output from Get-ADUser and pipes it to Set-ADObject. This is where we use the two properties we specified with the parameter “-Properties”. Since we are changing a value, we use the “-Replace” switch to copy the value from one attribute to the other. In this case we are copying the Department over to the Description attribute. It’s pretty straight forward.  Note the generous use of $_ , indicating each user object coming through the PowerShell pipeline.

The Safety

Notice how I inserted “Select-Object * -First 5” into the middle of the pipe. That is the safety switch to make sure we only update five users as a test. Remove this part when it comes time for production implementation.

Calculated Values

But what if we want to combine a couple other attributes into a new one? Our second example copies the First Name, Last Name, and Department over into the Description attribute. Notice that we enclose each reference inside $(). This makes sure that the dotted property names get referenced correctly inside the new string value.

# Find all accounts with a Department            
# Copy that value along with the GivenName and SurName into Description            
Get-ADUser -LDAPFilter '(Department=*)' -Properties Description, Department |            
 Select-Object * -First 5 |            
 ForEach-Object {Set-ADObject -Identity $_.DistinguishedName ` 
  -Replace @{Description="$($_.GivenName) $($_.SurName) $($_.Department)"}}            

Seeing Double Yet?

Finally we wrap up with a simple query line to display the results of our effort. If the results don’t look right, then go back and fix your code. Make sure that you include all of the attribute names after the “-Properties” parameter of Get-ADUser. That is an easy one to miss.  Using the code samples above you can change the property names around to meet your needs.

# View the results            
Get-ADUser -LDAPFilter '(Department=*)' -Properties Description, Department |            
 Select-Object * -First 5 |            
 Format-Table Name, Description, Department

And Now A Word From The Soap Box

On a side note let me take this opportunity to explain why you should rarely use * after “-Properties”. If you did this:

Get-ADUser -Filter * -Properties *

Your domain controller would have to grab every single property of every single user. That is terribly inefficient and costly in a production environment with thousands of users. That is like going to the grocery store, buying every flavor of pudding, and then only eating the tapioca when you get home. Don’t buy the vanilla and chocolate if you’re not going to eat it. In other words don’t query every single attribute known to mankind if you’re not going to use them in your code. It’s just not cool. Don’t do it. Really. Just don’t.

There is an art to crafting the correct filter and property parameters. You can learn it.  I would start with Get-Help about_ActiveDirectory_Filter.  Dive into the help and learn how to write LDAP query strings. You can also use the query feature in AD Users & Computers to develop your LDAP query strings in the GUI.

image

The End

Be careful out there. Don't update the wrong attributes. Test in a safe place first.  Make sure you've got a good backup before you turn this loose.

So now you know what tapioca pudding has to do with Active Directory… GoateePFE likes both of them.  Now I'm headed to the refrigerator to get some.  Yum!  What's your favorite pudding?

Can you help me?  Yes!

If you would like to have me or another Microsoft PFE visit your company and assist with the ideas presented in this blog post, then contact your Microsoft Premier Technical Account Manager (TAM) for booking information.

For more information about becoming a Microsoft Premier customer email PremSale@microsoft.com.  Tell them GoateePFE sent you.

Sharing Links
Comments
  • Thanks!  I've been looking all over for this...

  • @{Description=$($_.Department)}}

    I prefer in this way:

    @{Description=$_.Department}}

    I don't know why your code is not working for me, so I changed a little bit. It's working now

  • I had a project where I had to copy the SamAccountName attribute to the EmployeeNumber attribute. This is what it looked like when I was done. This page was a great help. Get-ADUser -LDAPFilter '(SamAccountName=*)' -Properties SamAccountName, EmployeeNumber | Select-Object * -First 10|ForEach-Object {Set-ADObject -Identity $_.DistinguishedName ` -replace @{EmployeeNumber="$($_.SamAccountName)"}}

  • This code is not working for me.. Here's what I'm doing:

    get-aduser -searchbase "ou=distributors,ou=people,dc=difc,dc=root01,dc=org" -ldapfilter '(Description=*)' | foreach-object {set-aduser -identity $_.DistinguishedName -replace @{Company="$($_.Description)"}}

    The error I get is:

    set-aduser : replace
    At line:1 char:125
    + get-aduser -searchbase "ou=distributors,ou=people,dc=difc,dc=root01,dc=org" -lda ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (CN=Craig Brunet...C=root01,DC=org:ADUser) [Set-ADUser], ADInvalidOperationException
    + FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.SetADUser

  • Hi Ben,
    Try changing the last bit as follows:
    @{Company=$_.Description}}
    Let me know if that works.

    In the future if I were you I would edit sample output so as not to expose private company data. Now everyone reading this post knows that Craig Brunet works at DIFC. Cool for hackers. Not cool for you or Craig. Would you like me to delete the comment to protect your data, or did you already make these changes before you posted it?
    Ashley
    @GoateePFE

  • I'm looking for a powershell script to add a value to extensionattribute for all users in a certain OU. Any suggestions?

  • Awesome scripting! I'm a novice with Powershell, so any advice on the preferred way to output it to a log file? Especially errors such as when copying from/to an attribute that has a 15 character limit? We have another app that creates accounts with the real employee ID as the sAMAccountName.
    So my script is such:

    Get-ADUser -searchbase "OU=corporate,DC=domain,DC=local" -LDAPFilter '(sAMAccountName=*)' -Properties sAMAccountName, employeeID | Select-Object * | ForEach-Object {Set-ADObject -Identity $_.DistinguishedName -replace @{employeeID="$($_.sAMAccountName)"}}

    I want to run this daily and log any output. Can you help please?

  • @Tech, On the Get-ADUser example above you can use the -SearchBase parameter to target your OU. Then specify the name of the extension attribute name in the -Replace parameter of the Set-ADObject cmdlets. Your value can either be a static string or reference another attribute as above.

    @DeaconZ, For logging errors I would recommend using the -ErrorVariable parameter with the Set-ADObject cmdlet. You can put all your errors specific to the action in a single variable, then dump the error object at the end of your script to your desired reporting format. See "help about_CommonParameters" for more information. For logging successful actions trying using the -Verbose switch on Set-ADObject. If you are using PowerShell v3 or above you can then use this redirector at the end of the command line to send all output from all streams to a text file like this: [pipeline commands here] *> output.txt

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment