Add a Parent OU Path to Your Active Directory Objects

One question I have seen quite often in Powershell forums is “How do I find the parent OU of a user/computer?” Turns out this isn’t immediately available for your objects. I typically use a string replace to infer the OU path from the distinguishedname of the object like this:

This works just fine, but what if you need this data outside of your scripts? It might be useful for this to always be included in your active directory queries.

Powershell’s Extensible Type System

Powershell’s type system is nothing if not flexible. Known as ETS, the Extensible Type System, it allows you to modify the data types that are output on the fly and create new structures that fit your needs better than what is provided. Prior to Powershell version 3.0 this was only possible using XML files, but now we can extend our data types using native Powershell cmdlets.

There are 3 cmdlets included with Powershell version 3.0 and up that work with the ETS: Get-TypeData, Update-TypeData and Remove-TypeData. For our purposes we are going to focus on Update-TypeData which will allow us to add new properties and methods into our Powershell objects.

How it Works

First we need to define what it is that we want to add to our objects. In this case we want a Path property to be available whenever we use cmdlets like Get-ADUser or Get-ADComputer. Next we need to define what data types are involved. We can use the GetType method to see what types are returned by a cmdlet:

Notice the Name field is ADUser. While this is a valid type this would only cover users and we want to add a Path parameter to both users and computers. In the output above we can see that the ADUser type is derived from the ADAccount base type. Let’s see if computers are the same:

Looks like a winner! You can see that computer objects are derived from the same .NET base type.

Now let’s take a look at how we can use Update-TypeData to add our Path parameter:

Note: I used splatting here to pass parameters to the cmdlet. This was done to improve readability of the code on this page and you can provide the parameters to explicitly to the cmdlet if you prefer. If you aren’t familiar with splatting, read more about it here.

Now when you run Get-ADUser or Get-ADComputer, the output will include your Path property:

 Making it Stick

The only problem with this approach is that the new type data is dynamic – it only exists in the current Powershell session. The help for Update-TypeData states this:

The Update-TypeData cmdlet updates the extended type data in the session by reloading the Types.ps1xml files into memory and adding new extended type data.

When it says “into memory,” you can interpret that to mean “temporary.” So how do we make this work for us whenever we use Powershell to get information on our Active Directory objects? You’ll have to add to add the command into your Powershell profile. You can find more info on setting up your profile here. Another approach to this would be to add the Update-TypeData cmdlet to a custom module so that any time the module is imported your object data will be updated with your custom property.

Hopefully this has been a useful introduction to Powershell’s Extensible Type System. I’m sure you can think of many more uses for this trick that will help you get your work done more easily!

Thoughts on Powershell Parameter Naming Conventions

If you haven’t seen the Microsoft Virtual Academy series on Active Directory and Powershell yet, you should check it out here. Hosted by Ashley Mcglone and Jason Helmick, it has tons of information on how to get started using Powershell to manage Active Directory and there is some great supplemental material that you can download and work through on your own.

Anyway, I was thinking about one of Jason’s comments in the series regarding Powershell parameter naming conventions. Specifically he says that the -Properties parameter of Get-Aduser should be -Property instead. According to MSDN, Powershell cmdlet parameter names should always be singular unless they only take multiple values as an argument. Since -Properties accepts either a single value or an array of values, it should instead be -Property.

First off, -Property is a valid alias for this parameter so if you type it this way instead it will still work. However tab completion will always fill out the plural version of the parameter. I think that this particular practice in general is flawed and I’ll tell you why – because it doesn’t help anyone.

The practice I prefer is to always use singular names for parameters that can only accept single values, and always use plural names for any parameter that can accept multiple values. The reasoning is simple – you can tell just by looking at the parameter name whether it accepts multiple values or not. You don’t need to run get-help at all in order to see that Get-ADUser -Properties Title,Department will work. Also, I don’t know of many cmdlet parameters that only accept multiple values. I am sure some exist, but it’s far more common to have parameters that will accept an array with only one element.

As always, comments and criticism are welcome.