Listing parent of AD object in PowerShell

Recently, I wanted to provide a client with a list of groups that related to some work he was doing. I wanted the group names as well as their location with AD. Although I often use the ds* commands or excellent ADfind tool for this type of task, I had been working in PowerShell on another project, so I decided to use the PowerShell ActiveDirectory module.

The Get-ADGroup Cmdlet pulled out the groups easily enough, but the there wasn’t a property representing the group object’s parent, nor is there an LDAP property that I could request (AFAIK). The object’s parent is contained within the DistinguishedName (DN) property, though.

For a group with the following DN:

CN=FOO-FileServices Administrators,OU=FOO,OU=Departments,DC=uvm,...

I just need to strip off the CN. I could split the DN on commas, remove the first element, and then reassemble what’s left to get the parent. I also needed to avoid splitting on an LDAP-escaped comma where a value actually contains a comma (e.g., CN=).

PS> $dn -split '(?<![\\]),'

I’ve used a regular expression construct called a zero-width negative look-behind assertion to match commas only where the aren’t preceeded by a slash.

I put together a small function to break up the DN on non-escaped commas, and then used -join operator to construct the DN of the parent.

function Get-ADParent ([string] $dn) {
     $parts = $dn -split '(?<![\\]),'
     $parts[1..$($parts.Count-1)] -join ','
}

FYI: In my function, I used $parts.Count-5 in the array slice to trim the ‘DC=’ domain components, which of course are the same for every object in my domain.

With that function, I then used a calculated property to include the parent in an output pipeline. For each object in the pipeline, I need to call Get-ADParent with the object’s DistinguishedName property. I like to store calculated properties in a variable:

PS> $parent = @{Name='Parent'; Expression={ Get-ADParent $_ } }

This works because the ToString() method for AD objects returns the DN. I could also have been specific in the Expression like so:

PS> $parent = @{Name='Parent'; Expression={ Get-ADParent $_.DistinguishedName } } 

Now, I can create a PowerShell-ish pipeline to create the info that I want:

PS> Get-ADGroup -filter {cn -like 'Foo*'} | sort Name | ft Name,$parent -A 

which returns results like this:

Name                               Parent
----                               ------
FOO-FileServices Administrators   OU=FOO,OU=Departments,...
FOO-FileServices-BrowseTop        OU=FOO,OU=Departments,...
FOO-FileServices-HR               OU=FOO,OU=Departments,...
FOO-FileServices-Marketing        OU=FOO,OU=Departments,...
FOO-FileServices-THAC0            OU=FOO,OU=Departments,...
FOO-GroupAdmins                   OU=OU Admins,OU=Groups,...

This function and calculated property should work with any AD objects that have a DistinguishedName property; users, computers, OUs, anything.

I hope you have found this helpful.

Geoff
Sr. System Administrator at the University of Vermont

2 Comments

  1. I used this technique again, and wanted to show the location relative to the domain root, and using abbreviated notation like a filesystem path. I came up with the following modification:

    function Get-ADParent ( [string] $dn) {
    # get rid of ‘OU=’
    $parts = $dn.Replace(‘OU=’,”) -split ‘(?

Leave a Comment

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