AD CS: DumpADObj.ps1 Script for Cross-forest Certificate Enrollment

Applies To: Windows Server 2008 R2, Windows Server 2008 R2 with SP1

Use DumpADObj.ps1 to display attribute values of an object in the specified Active Directory Domain Services (AD DS) forest.

In cross-forest Active Directory Certificate Services (AD CS) deployments, use DumpADObj.ps1 to troubleshoot certificate enrollment or PKI object synchronization problems.

The program LDIFDE.EXE is required for DumpADObj.ps1 to access objects in AD DS.

Saving DumpADObj.ps1

To save DumpADObj.ps1 to a file

  1. Click Copy Code at the top of the code section.

  2. Start Notepad.

  3. On the Edit menu, click Paste.

  4. On the File menu, click Save.

  5. Type a path for the file, type the file name DumpADObj.ps1, and click Save.

# This script dumps certificate template/CA information using ldifde.exe

# Command line arguments
$ForestName = ""
$DCName = ""
$ObjectType = ""
$ObjectName = ""
$OutFile = ""

function ParseCommandLine()
{
    if (10 -gt $Script:args.Count)
    {
        write-warning "Not enough arguments"
        Usage 
        exit 87
    }
    
    for($i = 0; $i -lt $Script:args.Count; $i++)
    {
        switch($Script:args[$i].ToLower())
        {
            -forest 
            {
                $i++
                $Script:ForestName = $Script:args[$i]
            }
            -dc 
            {
                $i++
                $Script:DCName = $Script:args[$i]
            }
            -type 
            {
                $i++
                $Script:ObjectType = $Script:args[$i]
            }
            -cn 
            {
                $i++
                $Script:ObjectName = $Script:args[$i]
            }
            -file 
            {
                $i++
                $Script:OutFile = $Script:args[$i]
            }
            default 
            {
                write-warning ("Unknown parameter: " + $Script:args[$i])
                Usage
                exit 87
            }
        }
    }
}

function Usage()
{
    write-host ""
    write-host "Script to display attribute values of certificate template or CA object in AD"
    write-host ""
    write-host "dumpadobj.ps1 -forest <DNS name> -dc <DC name> -type <template|CA> -cn <Name> -file <output file>"
    write-host ""
    write-host "-forest           -- DNS of the forest to process object from"
    write-host "-dc               -- DNS or NetBios name of the DC to target"
    write-host "-type             -- Template or CA"
    write-host "-cn               -- Template or CA name"
    write-host "-file             -- Output file"
    write-host ""
}

#########################################################
# Main script code
#########################################################

# All errors are fatal by default unless there is anoter 'trap' with 'continue'
trap
{
    write-error "The script has encountered a fatal error. Terminating script."
    break
}

ParseCommandLine

write-host ""
write-host "Effective settings:"
write-host ""
write-host "  Forest: $ForestName"
write-host "      DC: $DCName"
write-host "    Type: $ObjectType"
write-host "    Name: $ObjectName"
write-host "    File: $OutFile"
write-host ""

# Set type specific variables
switch($ObjectType.ToLower())
{
    "template"
    {
        $ObjectContainerCN = ",CN=Certificate Templates"
        $ObjectSchema = "pKICertificateTemplate"
    }
    "ca"
    {
        $ObjectContainerCN = ",CN=Enrollment Services"
        $ObjectSchema = "pKIEnrollmentService"
    }
    default
    {
        write-warning ("Unknown object type: " + $ObjectType)
        Usage
        exit 87
    }
}

# Build full DN for the object
$ForestDN = "DC=" + $ForestName.Replace(".", ",DC=")
$ObjectFullDN = "CN=" + $ObjectName + $ObjectContainerCN + ",CN=Public Key Services,CN=Services,CN=Configuration," + $ForestDN

# Build list of attributes to display
$ForestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext Forest, $ForestName
$SchemaDE = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass]::FindByName($ForestContext, $ObjectSchema).GetDirectoryEntry()
$AttrList = $SchemaDE.systemMayContain

if($null -ne $SchemaDE.mayContain)
{
    $MayContain = $SchemaDE.mayContain
    foreach($attr in $MayContain)
    {
        [void]$AttrList.Add($attr)
    }
}

if (-1 -eq $AttrList.IndexOf("displayName"))
{
    [void]$AttrList.Add("displayName")
}

if (-1 -eq $AttrList.IndexOf("flags"))
{
    [void]$AttrList.Add("flags")
}

if ($ObjectType.ToLower().Equals("template") -and -1 -eq $AttrList.IndexOf("revision"))
{
    [void]$AttrList.Add("revision")
}

$SB = New-Object System.Text.StringBuilder
for($i = 0; $i -lt $AttrList.Count; $i++)
{
    [void]$SB.Append($AttrList[$i])
    if($i -lt ($AttrList.Count - 1))
    {
        [void]$SB.Append(",")
    }
}
$AttrListString = $SB.ToString()

# Build command line and execute
$CommandLine = "-d """ + $ObjectFullDN + """ -p Base -l """ + $AttrListString + """ -f """ + $OutFile + """ -s " + $DCName
Invoke-Expression "ldifde.exe $CommandLine" > ldifde.out.txt
type "$OutFile"

AD CS: Cross-forest Certificate Enrollment with Windows Server 2008 R2

AD CS: Deploying Cross-forest Certificate Enrollment

AD CS: Managing Cross-forest Certificate Enrollment

AD CS: Troubleshooting Cross-forest Certificate Enrollment

AD CS: PKISync.ps1 Script for Cross-forest Certificate Enrollment