Only display OU without CN

I am running the below script and have been trying for several hours to get only the OU structure of a computer object, but without the CN:

$OUin=@('jelly','eggs','carrots')
$OUex='cheese|yogurt|bananas'

foreach ($OU in $OUin) {Get-ADOrganizationalUnit -Filter * |Select-Object -ExpandProperty DistinguishedName | Where-Object {$_ -match $OU -and $_ -notmatch ($OUex)}|`
ForEach-Object {Get-ADComputer -SearchBase $_ -SearchScope Onelevel -Filter {Enabled -eq $true} 

I’ve tries various split operators and split-path cmdlet, but I just can’t seem to get the information I want. Can someone help me out? Thanks.

So, everything up to the “cn=” but not including that? Or just the OUs (not the DCs?)

A problem is that a computer can belong to more than one OU (through nesting), and also to a container (which is a cn=, not an ou=, like the built-in Computers container).

I should also point out that you’re repeatedly querying all the OUs from AD, which isn’t very efficient and could load the domain controller. It’d perhaps be better to query the OUs one time, and then enumerate them to look for matches against your list.

A one-liner isn’t going to be the most efficient or easy-to-write way to do this - rather than chaining commands, it might be better to write a more formal script.

If you could outline the business goal here, it might be easier for me to understand what you’re trying to do, and to offer a useful suggestion?

I am supposed to query our AD structure to find specific OU’s with a given name. Based on the DN of that search, I do not want to see certain OU’s with another set of names. Then I want to get a count of all the computer objects in the OU’s based on the previous results. I was gonna use the Group-Object cmdlet to do this. When I group it, I see the CN’s of the DN’s. I just want to see the OU path.

OK. So, with a path like:

Dc=mydomain,dc=com,ou=Sales,ou=West,cn=client43

What would you want to see?

The output is in reverse when I get the results:

CN=client43,OU=West,OU=Sales,DC=mydomain,DC=com
I just want to drop client43, and keep OU=West,OU=Sales,DC=mydomain,DC=com

While probably not the most elegant solution I’ve used the below for your specific situation:

get-adcomputer $($env:computername) |
Select-Object @{
Name = "Parent"; `
Expression = {($_.distinguishedname.split(","))[1 .. $(($_.distinguishedname.split(",") | measure-object).count - 1)] -join ","`
	}
}

Translating that into your code:

Get-ADComputer -SearchBase $_ -SearchScope Onelevel -Filter {Enabled -eq $true} | 
Select-Object @{ Name = "ParentOU";`
Expression = { ($_.distinguishedname.split(","))[1 .. $(($_.distinguishedname.split(",") | measure-object).count - 1)] -join ","`
} }

EDIT:
I should also point out that this will only work for computer accounts. While at work I don’t have access to my old jobs repo of stuff I wrote - I know I got something in there that would handle user accounts as well but that would have to wait until after work but if your only looking for computer you should be fine.

Thanks Paul. That’s exactly what I needed. I’m reading about regex, so I can understand what you did.

What Paul provided was not RegEx, although it could be done with RegEx similar to the following

Get-ADComputer -SearchBase $_ -SearchScope Onelevel -Filter {Enabled -eq $true} | 
Select-Object @{ Name = "ParentOU";`
Expression = {[regex]::Match($_.distinguishedname,",(.*)").Groups[1].Value}}}

For dealing with User OUs, I found a regex that handles the occasional comma in the user name:

$ou = "CN=Smith\, John,OU=Users,OU=TEST OU,DC=nowhere,DC=com"

$ou -replace '^.+?(?<!\\),', '' 

should give you “OU=Users,OU=TEST OU,DC=nowhere,DC=com”