Generating LDP Dumps from PowerShell

Back in my PSS days, it was a common data-gathering/troubleshooting technique to collect "LDP Dumps" (ie - full AD propertyname+value data for a given object) as a way of collecting data for a troubleshooting investigation. If you're a really long-time Exchange administrator, just pretend I said "raw mode dump" and know that it's effectively the same thing, but for an AD object.

Recently, a customer suggested that we (Exchange) should produce a built-in cmdlet which can, given a pipeline input of an Exchange object, connect to the AD and provide this sort of LDP dump data, so that they could replace their use of LDP.exe. The rationale is that this could be pretty useful to collect this data more rapidly (and with fewer clicks) when troubleshooting an issue. I thought about it for a bit, and realized that because of the directory support built into PowerShell (or, rather, .Net) this would be something possible to write with a fairly simple script... no new cmdlet required!

Note that in an effort to keep the output looking roughly like the LDP output, I'm writing out strings rather than objects. This is a little counter to the spirit of PowerShell, of course, but it's also easily overcome with some minor changes to the script below.

Behold, the outcome of this experiment - I hope it's useful to you!

#
# LDPDump.ps1 script
# This script is a PowerShell way to simulate the effects of the old-school "LDP Dump" used by Exchange PSS and other Exchange power-administrators
#  (ie - connecting with LDP.exe, navigating to an object, and double-clicking to get all of the property and value data onto the screen)
#

#
# Discover whether the script is receiving piped input
#
if ( $input.movenext() )
{
    $inputExists = $true
    $input.reset()
}

#   
# There is no piped input - provide some guidance and exit
#
if (!$inputExists )
{
    write-error "You need to pipe in some object!"
    exit
}

# Let's loop on each of the things piped into the script
foreach ($j in $input)
{
    # Grab out the distinguished name (this is a little bit Exchange-centric, but it's also sort of standard-ish)
    $dn=$j.DistinguishedName
    # Did we find a DistinguishedName property? If not, ABORT!
    if($dn -eq $null)
    {
        write-error "THIS OBJECT DOES NOT HAVE A DN: $($j.ToString())"
        write-host ""
    }
    else
    {   
        # OK, we found a DN... let's open a session to AD
        $ldapdn = "[ADSI]'LDAP://$dn'"
        $ldpdump = invoke-expression "$ldapdn"       
        # Print a header for this object
        write-host "$($ldpdump.psbase.path)"
    foreach ($k in $ldpdump.psbase.properties.PropertyNames)
        {
            # Make each count, propertyname and value output look pretty much like LDP does (ie - "#>Name:Value")
            write-host "$($ldpdump.psbase.properties[$k].count)>$($k):$($ldpdump.psbase.properties[$k])"
        }
        write-host ""
    }
}

Thanks to Sebastian Bengochea for help getting at the ProxyCollection data!