All Active Directory (AD) administrators have to deal with paths to objects in AD. Usually, these paths are distinguished names (DNs) of objects in the directory (e.g., "CN=Ken Dyer,CN=Users,DC=fabrikam,DC=com"). For various reasons, it's useful to retrieve parts of these names. For example, string parsing is often used to retrieve the parent container of a named AD object. One way of doing this is to find the first comma in the DN and retrieve the rest of the string after it, as Figure 1 shows.

Figure 1: Parsing a String to Retrieve the Parent Container of a Named AD Object

However, simple string parsing has its limitations. For example, a comma isn't an illegal character inside a DN, but it needs to be escaped using a backslash character. That is, suppose the user object's name is "Dyer, Ken" instead of "Ken Dyer". In this case, the DN is "CN=Dyer\, Ken,CN=Users,DC=fabrikam,DC=com." The string parsing technique illustrated in Figure 1 will output " Ken,CN=Users,DC=fabrikam,DC=com" (including the leading space) because of the comma in the first element of the DN ("CN=Dyer\, Ken").

Commas aren't the only characters that require escaping. You also need to escape the forward slash (/) when specifying a DN for use with Active Directory Service Interfaces (ADSI). For example, consider the command:

$user = [ADSI] "LDAP://CN=HRUser,OU=H/R,DC=fabrikam,DC=com"

This command will fail because the forward slash in the organizational unit's (OU's) name ("CN=Jeff Smith,OU=H/R,DC=fabrikam,DC=com") isn't escaped. To make the command work, you need to escape the forward slash with a backslash, as follows:

$user = [ADSI] "LDAP://CN=HRUser,OU=H\/R,DC=fabrikam,DC=com"

If none of your AD objects' names contain commas, forward slashes, or other characters that require escaping, string parsing will work (until you run into an object in AD that contains an unexpected character). However, the effectiveness of your scripts shouldn't depend on specific naming conventions in AD. Scripts should work with any valid AD names, regardless of whether characters need escaping.

Because properly escaping AD paths is more complicated than it seems at first, Microsoft provided the Pathname COM object. The Pathname object provides a way to specify an AD path and retrieve it (or parts of it) in a number of different formats. It also provides automatic escaping if needed. The Pathname object is relatively straightforward to use in a VBScript script, but it's more awkward and difficult to use in Windows PowerShell because it lacks a type library. The NameTranslate COM object has the same type of problem, as I describe in my article "Translating Active Directory Object Names Between Formats." You have to use the same kind of code to interact with the Pathname object as you do with the NameTranslate object. Specifically, you need to call the InvokeMember method of the Pathname object's base object.

Introducing Get-ADPathname.ps1

Rather than continually deal with the awkward syntax of the InvokeMember method, I wrote a PowerShell script, Get-ADPathname.ps1, that provides a more straightforward way to interact with the Pathname object. The script can perform seven kinds of actions based on the parameters you specify. These action parameters are listed in Table 1. All the action parameters in Table 1 (except for -GetEscapedElement) also require the -Path parameter, which specifies the AD paths you want to parse.

Action Parameter Description
Table 1: Get-ADPathname.ps1 Action Parameters
-Retrieve Retrieves AD paths. This is the default parameter.
-AddLeafElement Adds elements to an AD path.
-RemoveLeafElement Removes the final element from an AD path.
-Split Splits an AD path and outputs the individual elements as a list.
-GetElement Outputs an AD path's element based on its index number. The leftmost element's index number is zero.
-GetNumElements* Outputs the number of elements in the AD path.
-GetEscapedElement** Outputs an element with the correct escape characters inserted.
* -GetNumElements isn't strictly necessary because -Split outputs this number of elements.        ** -GetEscapedElement doesn't use any of the modifier parameters listed in Table 2.

In addition to the action parameters listed in Table 1, there's a set of modifier parameters that affect the script's input (-Path and -Type) and its output (-Format, -EscapedMode, and -ValuesOnly). These parameters are listed in Table 2. Each action parameter in Table 1 (except for -GetEscapedElement) use one or more of the modifier parameters in Table 2.

Modifier Parameter* Description
Table 2: Get-ADPathname.ps1 Modifier Parameters
-Path Specifies the AD paths. This parameter supports pipeline input if using the -Retrieve parameter. This parameter is required unless you pipe input to the script. This parameter is assumed to be first, so the parameter name (-Path) is optional.
-Type Specifies the type of the AD paths (either DN or Full) given to the -Path parameter. The Full type includes the path's provider (usually LDAP) and an optional server name. The DN type is the default value for this parameter.
-Format Specifies the format in which to output the AD paths or path elements. This must be one of the values listed in Table 3. X500DN is the default value for this parameter.
-EscapedMode Specifies the escape mode when outputting the AD paths or path elements. This must be one of the following values: Default, On, Off, or OffEx. Default is the default value for this parameter. Table 3 lists the default escape mode when this parameter is set to Default.
-ValuesOnly Specifies how to output the elements in the AD paths. If this parameter is absent, the script outputs path elements using both attributes and values (e.g., CN=Ken Dyer). If this parameter is present, the script outputs path elements using values only (e.g., Ken Dyer).
* The -GetEscapedElement parameter doesn't use any of these parameters.

The -Format parameter listed in Table 2 has nine possible values that tell Get-ADPathname.ps1 how to output the AD paths. These values are listed in Table 3.

Value Description Default Escape Mode*
Table 3: Possible Values for the -Format Parameter
Windows Full path in Windows format (Example: LDAP://servername/DC=com/DC=fabrikam/CN=Users/CN=Ken Dyer) On
WindowsNoServer Windows format without server (Example: LDAP://DC=com/DC=fabrikam/CN=Users/CN=Ken Dyer) On
WindowsDN Windows format, DN only (Example: DC=com/DC=fabrikam/CN=Users/CN=Ken Dyer) Off
WindowsParent Windows format, parent only (Example: DC=com/DC=fabrikam/CN=Users) Off
X500 Full path in X.500 format (Example: LDAP://servername/CN=Ken Dyer,CN=Users,DC=fabrikam,DC=com) On
X500DN X.500 format, DN only (Example: CN=Ken Dyer,CN=Users,DC=fabrikam,DC=com) Off
Server** Server name (Example: servername) N/A
Provider Provider name (Example: LDAP) N/A
Leaf The name of the leaf (Example: CN=Ken Dyer) On
* The Default Escape Mode column specifies whether the output contains escape characters when the -EscapedMode parameter is set to Default.
** The -Format Server parameter only works when the -Type parameter is set to Full and the -Path parameter includes the server names.

Now that you know about the parameters and values that are available, I'll show you how to use them. The best way to do this is to demonstrate how to use each of the seven action parameters listed Table 1. (You can download the Get-ADPathname.ps1 script by clicking the Download the Code button near the top of the page.)

Using the -Retrieve Parameter

The -Retrieve parameter retrieves AD paths in various formats. It's the default action parameter. Its syntax is:

Get-ADPathname.ps1 [-Path <String[]>] [-Type <String>]
  [-Retrieve] [-Format <String>] [-EscapedMode <String>]
  [-ValuesOnly]

The -Retrieve parameter name is optional, but you can include it for clarity. Similarly, the -Path parameter name is optional. In the commands I present here, I sometimes include the -Path parameter name while other times I don't include it so that you can get used to it both ways. Besides a string, the -Path parameter also accepts pipeline input.

Retrieving AD paths is useful in several scenarios. For example, suppose you have a list of DNs and you want to pass each DN to the [ADSI] type accelerator. If the DNs are in a file named DNs.txt, you can use a command such as:

Get-Content DNs.txt | Get-ADPathname -Type DN -Retrieve `
  -Format X500 -EscapedMode On | ForEach-Object {
    ([ADSI] $_).displayName)
}

The [ADSI] type accelerator requires the full LDAP path for each DN in the list (-Format X500) and requires proper escaping (-EscapedMode On). The result of this command is to output the displayName attribute for each DN in the DNs.txt file. Note that I could have omitted -Type DN, -Retrieve, and -Format X500 from this command because those parameters are all defaults, but I included them for clarity.

Here's another example: Suppose you have a list of full LDAP paths (i.e., LDAP://...) that include escape characters in a file named FullPaths.txt. From this list of LDAP paths, you want to create a list of DNs that don't include the escape characters. To do this, you can use a command such as:

Get-Content FullPaths.txt |
  Get-ADPathname -Type Full -Retrieve -Format X500DN `
  -EscapedMode Off

The -Type parameter's argument (Full) tells Get-ADPathname.ps1 that each input path (i.e., each line in FullPaths.txt) is a full LDAP path. In this case, the -Format and -EscapedMode parameters are optional because -Format X500DN and -EscapedMode Off are the default settings, but I included them for clarity.

Finally, here's an example of a command that retrieves the name of an object:

Get-ADPathname "CN=Ken Dyer,CN=Users,DC=fabrikam,DC=com" `
  -Type DN -Retrieve -Format Leaf -ValuesOnly

This command outputs the string "Ken Dyer" (without the quotes). If you omit the -ValuesOnly parameter from this command, it will output the string "CN=Ken Dyer" (without the quotes) instead.

Using the -AddLeafElement Parameter

The -AddLeafElement parameter adds leaf elements to an AD path. The syntax is:

Get-ADPathname.ps1 [-Path] <String> [-Type <String>]
  -AddLeafElement <String[]> [-Format <String>]
  [-EscapedMode <String>] [-ValuesOnly]

For example, here's how to use -AddLeafElement to add two leaf elements to an AD path:

Get-ADPathname "CN=Users,DC=fabrikam,DC=com" `
  -AddLeafElement "CN=Ken Dyer","CN=Jeff Smith"

Figure 2 shows the results. The -AddLeafElement parameter isn't that useful in most cases because you can do the same thing using string concatenation in PowerShell, but I included it for completeness.

Figure 2: Using the -AddLeafElement Parameter

Using the -RemoveLeafElement Parameter

The -RemoveLeafElement parameter removes a leaf element from one or more AD paths—that is, it outputs the parent paths of named AD objects. The syntax is:

Get-ADPathname.ps1 [-Path] <String[]> [-Type <String>]
  -RemoveLeafElement [-Format <String>]
  [-EscapedMode <String>] [-ValuesOnly]

Here's an example of how to use the -RemoveLeafElement parameter to output the names of the parent containers of two AD paths, with escaping enabled:

Get-ADPathname "CN=Ken Dyer,CN=Users,DC=fabrikam,DC=com",
  "CN=Jeff Smith,OU=H/R,DC=fabrikam,DC=com" `
  -RemoveLeafElement -EscapedMode On

Figure 3 shows the results. Notice the second OU in the output.

Figure 3: Using the -RemoveLeafElement Parameter

Using the -Split Parameter

The -Split parameter splits an AD path and outputs the individual elements of the path as a list. The syntax is:

Get-ADPathname.ps1 [-Path] <String> -Split
  [-EscapedMode <String>] [-ValuesOnly]

Here's an example of the -Split parameter in action:

$userDN = "CN=Jeff Smith,OU=H/R,DC=fabrikam,DC=com"
$pathElements = Get-ADPathname $userDN -Split -ValuesOnly
"Object name: $($pathElements[0])"
"Container name: $($pathElements[1])"

In this code, the -ValuesOnly parameter omits the CN= and OU= parts of the names. Figure 4 shows the results.

Figure 4: Using the -Split Parameter

Using the -GetEscapedElement Parameter

The -GetEscapedElement parameter outputs an AD path element with escape characters included. This parameter is useful because you don't need to look up which characters need to be escaped. Its syntax is:

Get-ADPathname.ps1 -GetEscapedElement <String[]>

Take, for example, the command:

Get-ADPathname -GetEscapedElement "CN=Dyer, Ken"

This command outputs the string "CN=Dyer\, Ken" (without the quotes).

Using the -GetElement Parameter

The -GetElement parameter outputs a specific element from one or more AD paths. Its syntax is:

Get-ADPathname.ps1 [-Path] <String[]> [-Type <String>]
  [-EscapedMode <String>] [-ValuesOnly]

The leftmost element in the AD path is numbered 0, the next element is numbered 1, and so forth. This parameter is useful when you want to retrieve a specific path element. Take, for example, the command:

Get-ADPathname -Path `
  "CN=Ken Dyer,CN=Users,DC=fabrikam,DC=com" -GetElement 1

This command outputs the second element in the path: "CN=Users" (without the quotes).

Using the -GetNumElements Parameter

The -GetNumElements parameter outputs the number of elements in one or more AD paths. Its syntax is:

Get-ADPathname.ps1 [-Path] <String[]> [-Type <String>]
  -GetNumElements

Here's an example of how to use the -GetNumElements parameter:

Get-ADPathname -Path `
  "CN=Ken Dyer,CN=Users,DC=fabrikam,DC=com" -GetNumElements

This command outputs the number 4 because the AD path contains 4 elements ("CN=Ken Dyer," "CN=Users," "DC=fabrikam," and "DC=com"). This parameter isn't strictly necessary because the -Split parameter will output this number of elements, but I included it for completeness.

Stop Parsing AD Paths Manually

Microsoft provided the Pathname object to parse AD paths, but it's hard to use from PowerShell. The Get-ADPathname.ps1 removes the difficulties and makes it easy to interact with the Pathname object. Add the Get-ADPathname.ps1 script to your script toolbox and stop writing unnecessary code to parse AD paths.