I am asking this question mainly to ask if there is a better way to do what I have working. I would also like to know if anyone sees any issues with getting this information this way.
I am trying to get the top level OU that a user is in, and any lower level OUs. The main problem is that we have multiple sites, some of which have multiple layers of OUs for user accounts (ou=doctors,ou=Users,ou=Site,dc=example,dc=com
), and some sites that just have a single OU (ou=Users,ou=Site,dc=example,dc=com
). I used the script below to get the DN path, split it, and rebuild it backwards with the last three pieces. Can anyone see any issues with doing it this way. Something about it just feels wrong....
$user = Get-ADUser CKnutson
$user.DistinguishedName
# Returns: CN=Cory Knutson,OU=IT,OU=Users,OU=Site,DC=example,DC=com
$split = $user.DistinguishedName.Split(',')
$path = "$($split[-3]),$($split[-2]),$($split[-1])"
Write-Host $path
# Returns: OU=Site,DC=example,DC=com
Just to state, the end goal was for me to get the path to the "Disabled" OU that we have just inside of each of the "Site" OUs. So my scripting could move the object when disabling the account to the proper place, in that site's top level OU (OU=Disabled,OU=Site,DC=example,DC=com
).
Yes, I see two immediate problems that might arise from your current approach.
1. Escaped commas
Consider an OU with a comma in its name, like:
OU=Users\, Admin,DC=corp,DC=example
Your use of
string.Split()
won't care about the escape sequence and you end up with:Use the
-split
regex operator with a lookbehind to make sure you ignore escaped commas:2. Portability
Your code assumes that the NC part of the DN (eg.
DC=example,DC=com
), will always be just 2 labels wide. This means your code will fail if you use it in scripts you might want to reuse in other domains/environments.I would grab each part, from right-to-left until I find one without the
DC
RDN prefix:In my opinion it is simpler to use Pathname COM object and simply ask for the parent of the DN. You can put this in a
while
loop to get the hierarchy of the object. Example using my ADName module:Example output:
So you're after the DN of the path to the account? You can do that with a regular expression that uses the (?) ungreedy qualifier. There is no split, so escaped commas are not an issue.
Edit
I was unclear from the phrase
the top level OU that a user is in, and any lower level OUs.
You can also do this: