AWOL attributes in a hashtable of user objects

here’s a little surprise I came across today when I was comparing  two groups with each other.

I discovered that when I add a user object to a hash table that some of the attributes appear to be stripped off.

The attribute that went AWOL was the employeeID attribute but I’m sure there are others.  Try this, create an empty hash table ready to store your user information:

$users = @{}

Hashtables are like vbscript dictionary objects by the way and you store two bit’s of information, a unique key used to find the information and a value.  You add information to a hash table using $users.add(<key>,<value>). See this link for more information on hash tables:

now we have the hash table ready, get the user objects using any method you like, i.e. using get-qadgroupmember or get-qadusers – and for good measure you can explicitly tell the cmdlet that you want the employeeID attribute.

$members = Get-QADGroupMember "CN=GroupImInterestedIN,DC=AD,DC=COM" -proxy -includedproperties employeeID

Then add these users to the hash table like this:

ForEach ( $member in $members ) {
 if ( ! ( $users.ContainsKey($member.employeeID) ) ) {
  write-debug "Adding User: $($member.NTAccountName) - employeeID : $($member.employeeID)"
  write-debug "Added user : $($($users.item($member.employeeID)).samaccountName) - employeeID : $($($users.item($member.employeeID)).employeeID) "

I know you could do this using the pipeline – which is great if you are actually working at the command line so I could have done something like this:

Get-QADGroupMember "CN=GroupImInterestedIN,DC=AD,DC=COM" -proxy -includedproperties | ForEach-Object { if ( ! ( $users.ContainsKey($_.employeeID) ) ) {  $users.add($_.employeeID,$_) } }

Personally if I’m not at the commandline and I’m working within an ISE like powergui then I prefer not to use the $_ object as this can sometimes get confusing, especially in large loops and if you have nested loops then in each loop $_ is actually a different value.  Add to that what happens if there is an error and you get yet another invocation of $_.  Trust me, it’s cleaner not to use the ForEach-Object on the other side of a pipe and just use the ForEach construct so you can give the object a meaningful name.

I also like to use Write-debug rather than write-host when writing my code – this allows you to show debug messages when you need and have the script run silently if you don’t need them.  You can also make use of the write-verbose cmdlet to show different levels of debug messages in a large script but if you really want this then you should really be writing information to a log file.  I’ll post my current write-log function in another post but for any production script that you are going to run all the time writing to a log file is essential.

Trying not to go off on too much of a tangent here, which is not so easy.  To enable the debug messages type this at the cmdline

$DebugPreference = "Continue"

and to turn them off type

$DebugPreference = "SilentlyContinue"

Back to the script then, and more importantly the issue!  If you ran the code above you probably discovered that the first write-debug listed the users sAMAccountName and employeeID but the second didn’t.

So where did the employeeID attribute go?

Well the attribute is not stripped off, it’s still there.  I assume this is just a powershell querk.  Like it or not, when you print stuff to screen, often PowerShell guesses at what you want to see and formats it appropriately.  PowerShell will convert object properties on the fly to a suitable format for displaying on your screen and this isn’t always what you want and can be misleading too.  It seems something similar is happening here.  Before you add the $member object to the hash table the employeeID attribute can be got at directly from the object by typing this $member.employeeID.  Once it’s in the hashtable of $users, you have to reference it using the DirectoryOBject like this.

write-debug "Added user : $($($users.item($member.employeeID)).samaccountName) - employeeID : $($($users.item($member.employeeID)).DirectoryEntry.employeeID) "

So the data is still there you just have to access it differently.

One thought on “AWOL attributes in a hashtable of user objects

  1. […] AWOL attributes in a hashtable of user objects ( […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.