How can I use Regex to pull just the CN from a Distinguished Name with PowerShell

19,259

Solution 1

$s = "CN=Group Name I Want,OU=Group Container,DC=corp,DC=test,DC=local"
$s -replace "(CN=)(.*?),.*",'$2'

Solution 2

An even shorter variation on jon Z's answer:

$s = "CN=Group Name I Want,OU=Group Container,DC=corp,DC=test,DC=local"
$s = $s -replace '^CN=|,.*$'

The ^ and $ are the string beginning and end anchors. The | is an "or".

The matches are the CN= at the beginning of the line or a string that starts with a comma and goes to the end of the line (i.e. everything after the CN). The replace is replacing with nothing, so you're discarding all the matches and leaving just the CN itself.

That obviously does not work if you have a comma in your CN (ugh).

Assuming such a comma is followed by a space, this will work and be fine for the previous examples (\S - non whitespace char):

$s = $s -replace '^CN=|,\S.*$'

I tested to see if jon Z's or this variation was faster to execute. With 1,470,000 DNs, the first took 36.87s to execute and the one here took 34.75. Not really a lot in it.

That was reading the DNs out of a file. Bizarrely, "slurping" the file into an array and executing over that took both regexes a minute longer. The PC was not memory-bound - the file was only 100MB. Can't be bothered getting to the bottom of that one right now!

Share:
19,259
Andy Schneider
Author by

Andy Schneider

A Systems Engineer in the Greater Seattle Area. I am big fan of PowerShell. Follow me on Twitter, @andyschneider

Updated on June 18, 2022

Comments

  • Andy Schneider
    Andy Schneider almost 2 years

    I have a bunch of strings that are DN's of groups from AD. I need to pull out the Common Name. An example string is "CN=Group Name I Want,OU=Group Container,DC=corp,DC=test,DC=local"

    What I am looking for is some PowerShell Code that will pull "Group Name I Want" out of that string and discard the rest.

    I can rip of the CN with this

    $s = "CN=Group Name I Want,OU=Group Container,DC=corp,DC=test,DC=local"
    $s = $s.Remove(0,3) 
    

    But after that, I don't have a good way to rip off everthing starting at ",OU"

    I am sure there is some regex that will do this but I need some help figuring it out.

  • Andy Schneider
    Andy Schneider over 12 years
    much cleaner than -split method
  • Goyuix
    Goyuix over 12 years
    You should account for a CN that has a comma in the name - e.g. "CN=Surname\, First,OU=Group,DC=corp" - something like '(CN=)(.*?)(?<!\),.*','$2' would do the correct negative lookbehind to filter out commas with a leading slash.
  • Terry Gardner
    Terry Gardner over 12 years
    I am not sure I can agree with this methodology. LDAP data is not strings, DNs in particular are of distinguishedName syntax. Language substitutions, comparisons, and ordering operators should not, in general, be used with data retrieved from a directory server, unless those operators support the use of ordering and matching rules, in this case to figure out substitutions.
  • txyoji
    txyoji about 6 years
    for the php folks out there that's: preg_replace('/(CN=)(.*?),.*/','$2',$dn);