private/Split-LDAPPath.ps1


function Split-LDAPPath {
    <#
    .SYNOPSIS
        SPlits LDAP paths into parent and leaf nodes.
    .DESCRIPTION
        Sometimes it is necessary to resolve the parent of an LDAP path before it exists or can be queried. This uses a pure regex split to accomplish that task.
    .NOTES
        This does not validate schemas or validity of the path. It simply performs a split on the first unescaped comma.
    .LINK
        Specify a URI to a help page, this will show when Get-Help -Online is used.
    .EXAMPLE
    Split-ldappath -distinguishedName "CN=Bob\, the builder,OU=Top,DC=breakwaterlabs,DC=net"
    CN=Bob\, the builder
    OU=Top,DC=breakwaterlabs,DC=net
 
    .EXAMPLE
    Split-ldappath -distinguishedName "CN=Bob\, the builder,OU=Top,DC=breakwaterlabs,DC=net" -leaf
    CN=Bob\, the builder
 
    .EXAMPLE
    Split-ldappath -distinguishedName "CN=Bob\, the builder,OU=Top,DC=breakwaterlabs,DC=net" -parent
    OU=Top,DC=breakwaterlabs,DC=net
 
    .EXAMPLE
    Split-ldappath -distinguishedName "CN=Bob\, the builder,OU=Top,DC=breakwaterlabs,DC=net" -ashashtable
    Name Value
    ---- -----
    Parent OU=Top,DC=breakwaterlabs,DC=net
    Leaf CN=Bob\, the builder
    DistinguishedName CN=Bob\, the builder,OU=Top,DC=breakwaterlabs,DC=net
 
    #>

    [CmdletBinding(DefaultParameterSetName = "None")]
    param (
        # Specifies an LDAP Distinguished Name to split.
        [Parameter(Mandatory,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = "LDAP Path to split.")]
        [ValidateNotNullOrEmpty()]
        [string]
        $DistinguishedName,

        # Only returns leaf node.
        [Parameter(ParameterSetName = "Leaf",
            HelpMessage = "Only return leaf node.")]
        [Switch]
        $Leaf,

        [Parameter(ParameterSetName = "Leaf",
            HelpMessage = "Only return leaf node name without LDAP path type prefix.")]
        [Switch]
        $NodeNameOnly,

        # Only returns Parent Path.
        [Parameter(ParameterSetName = "Parent",
            HelpMessage = "Only return parent path.")]
        [Switch]
        $Parent,

        # Return hashtable of matches.
        [Parameter(ParameterSetName = "Hashtable",
            HelpMessage = "Only return parent path.")]
        [Switch]
        $AsHashtable
    )

    begin {
        $Search = [regex]'^(.+?(?<!\\)),(.*)'
    }

    process {
        $DistinguishedName | foreach-object {
            if ($_ -match $Search) {
                $result = @{
                    DistinguishedName = $matches[0]
                    Leaf              = $matches[1]
                    Parent            = $matches[2]
                }

                if ($result.leaf -match "[a-zA-Z]+=(.*)") {
                    $result.add("LeafName",$matches[1])
                } else {
                    throw "Leaf doesnt seem to match LDAP format!"
                }

                if ([bool]$leaf) {
                    if ([bool]$NodeNameOnly){
                        return $result.leafName
                    } else {
                        return $result.leaf
                    }
                }
                elseif ([bool]$parent) {
                    return $result.parent
                }
                elseif ([bool]$AsHashtable) {
                    return $result
                }
                else {
                    return @(
                        $result.Leaf
                        $result.Parent
                    )
                }
            }
            else {
                write-loghandler -level "warning" -message "Pattern did not match. Is this really an LDAP string? ($DistinguishedName)"
            }
        }
    }

    end {

    }
}