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!
Comments
Anonymous
January 01, 2003
Planning an Exchange Server 2007 migration Using ColdFusion 8 with Microsoft Exchange Server Full circleAnonymous
January 01, 2003
Very cool Evan. Thx for sharing...was looking for something like this.Anonymous
January 01, 2003
tr - the other key downside is that using an external exe like dsquery means you don't own the output. In my simple script all I'm doing is cracking the DirectoryEntry objects and outputting the results as text/string. But I could do lots more if I had some requirement -- filtering, reformatting, output to XML or HTML, etc. These are all things that are easy once you've got a PSObject with the results... and not as easy once you've got text-on-the-host from DSquery!Anonymous
January 01, 2003
tr - sure, you could get roughly the same output with a syntax like: Get-Mailbox mb1 | % { dsquery * $($_.DistinguishedName) - attr * } But, of course that isn't using PowerShell!Anonymous
March 19, 2008
can't you get the same result with a dsquery -attr * command? trAnonymous
March 21, 2008
The comment has been removed