Use PowerShell to Log Changes to AD DS Attributes

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to log changes made to Active Directory Domain Services attribute values.

Hey, Scripting Guy! Question Hey, Scripting Guy! We are in the process of merging a couple of resource domains, and we need to modify some user accounts prior to the move. I have been tasked with making the changes, and I plan to use Windows PowerShell to perform the actual work. I need to create before and after logs. The before log shows the value of the attributes that I am going to change prior to running the script, and the after log will show the value of the attributes after running the script. Can you show me how I might go about doing this? Thanks, Scripting Guy, you are the best!


Hey, Scripting Guy! Answer Hello CX,

Microsoft Scripting Guy, Ed Wilson, is here. This morning I am sitting on the lanai, and sipping a cup of English Breakfast tea. I put a bit of lemon grass, hibiscus flower, rose hips, spearmint, and a cinnamon stick in the tea. The flowers give it a citrus flavor, and the mint makes it very refreshing. The trick is that I only let it steep for three minutes, and that keeps it from becoming too bitter. It took me several tries to get this one just right. Because it is pretty early, it is not too hot or humid outside yet. I have my Surface RT, and am checking my email.

So, CX, you did not specify how you want your logging to take place, but I decided that exporting to a CSV file would work out well. Then you could import it into Microsoft Excel if you want to do so.

Finding the attribute and values

The first thing to do is to create a little script that will populate an attribute with before values. I am going to populate the Post Office Box attribute, so I need to look it up in ADSI edit. I come up with the following (surprisingly, it is named postOfficeBox):

Image of menu

I write a little script to add values to this attribute. Here is the script:

Import-Module activeDirectory

$ou = “ou=testou,dc=iammred,dc=net”

$i = 1

Get-ADUser -Filter * -SearchBase $ou |

ForEach-Object {

Set-ADUser $_ -POBox “Post Office Box $i”

$i++ }

Now I want to see how many different cities are represented by the users in the organizational unit (OU). I modify my script a bit and use the –Unique parameter from the Select-Object command. This is shown here:

Get-ADUser -Filter * -SearchBase $ou -properties $properties | select l -Unique

The following output tells me that I have three cities:                                                                                                         




Therefore, I need to add a bit of logic to detect the city. If the city is Atlanta, I will set the postOfficeBox attribute to 222; if it is Charlotte, I will set it to 333; and if it is Jacksonville, I will set it to 444.

Making the changes

The first thing I do is use the Get-ADUser cmdlet to return the user name and the postOfficeBox attribute. I use the Select-Object cmdlet to get these two attributes, and I pipe the output to Export-CSV. No problem…until I open the spreadsheet in Excel. Here is the results:

Image of spreadsheet

The issue is that for some reason, the postOfficeBox attribute is a collection. I therefore modify my script a bit, and I select the first PO Box. Here is the script:

Import-Module activeDirectory

$ou = “ou=testou,dc=iammred,dc=net”

$Before = “c:\fso\before.csv”


$properties = “PostOfficeBox”

Get-ADUser -Filter * -SearchBase $ou -properties $properties |

Select name, @{L=’pobox’;E={$_.postofficebox[0]}} |

Export-Csv -Path $before -NoTypeInformation -Force

Now I open the script in Excel, and it appears like I expected:

Image of spreadsheet

So now I use the Get-ADUser cmdlet to retrieve my user objects. I pipe everything to a Foreach-Object cmdlet, and I use a Switch statement inside the Foreach-Object. I read a Switch statement like a series of If statements, for example: If the city matches Atlanta, then I set the POBox variable to 222.

I then use the Set-ADUser cmdlet inside the Foreach-Object cmdlet to make the actual changes. Here is the script:

Import-Module activeDirectory

$ou = “ou=testou,dc=iammred,dc=net”

$properties = “l”,”PostOfficeBox”

Get-ADUser -Filter * -SearchBase $ou -properties $properties |

ForEach-Object {

 Switch ($_.l)

 { “Atlanta” {$pobox = “POBox 222”}

   “Charlotte” {$pobox = “POBox 333”}

   “Jacksonville” {$pobox = “POBox 444”} }

Set-ADUser $_ -POBox $pobox


Now I run my documentation script again and open the Excel spreadsheet. I can see that the changes took place as expected. Cool.

Image of spreadsheet

CX, that is all there is to using Windows PowerShell to make changes to AD DS attribute values and to log the changes. Active Directory Week will continue tomorrow when I will talk about different ways of working with Active Directory.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (2)

  1. Alternate says:

    Heh… Would be nice to see a script, which dumps all attributes of the AD subtree. Later your run this script again and see report with all changes of the day.

Skip to main content