Finding Domain Trusts in an Active Directory Forest using Microsoft PowerShell

April 21, 2014

Active Directory, PowerShell

For my Active Directory (AD) documentation script, I needed to enumerate all Trusts for a Domain. I found a script on TechNet but it had issues. I fixed the issues but I cannot post it as a solution on TechNet because my script is longer than 2000 characters.

I found the original script here.

My issues with the original script are:

No error checking
Did not handle singletons
Did not use its $DomainDNS variable in the Get-ADObject call to specify which domain to restrict the trusts
The $TrustAttributesNumber variable used decimal values instead of hexadecimal values (i.e. 20 instead of 32)
The $TrustAttributesNumber variable did not have a value for Inter-Forest trusts (hex 64)
The Switch statements did not use Default but used an If statement after the Switch statement to set the Default value

Here is my version of the script.

#http://gallery.technet.microsoft.com/scriptcenter/Enumerate-Domain-Trusts-25ecb802#content
Import-module ActiveDirectory
$Domains = (Get-ADForest).Domains

If($? -and $Domains -ne $Null)
{
	ForEach($Domain in $Domains)
	{ 
		Write-output "Get list of AD Domain Trusts in $Domain `r" 
		$ADDomainTrusts = Get-ADObject -Filter {ObjectClass -eq "trustedDomain"} -Server $Domain -Properties * -EA 0

		If($? -and $ADDomainTrusts -ne $Null)
		{
			If($ADDomainTrusts -is [array])
			{
				[int]$ADDomainTrustsCount = $ADDomainTrusts.Count 
			}
			Else
			{
				[int]$ADDomainTrustsCount = 1
			}
			
			Write-Output "Discovered $ADDomainTrustsCount trusts in $Domain" 
			
			ForEach($Trust in $ADDomainTrusts) 
			{ 
				$TrustName = $Trust.Name 
				$TrustDescription = $Trust.Description 
				$TrustCreated = $Trust.Created 
				$TrustModified = $Trust.Modified 
				$TrustDirectionNumber = $Trust.TrustDirection
				$TrustTypeNumber = $Trust.TrustType
				$TrustAttributesNumber = $Trust.TrustAttributes

				#http://msdn.microsoft.com/en-us/library/cc220955.aspx
				#no values are defined at the above link
				Switch ($TrustTypeNumber) 
				{ 
					1 { $TrustType = "Downlevel (Windows NT domain external)"} 
					2 { $TrustType = "Uplevel (Active Directory domain - parent-child, root domain, shortcut, external, or forest)"} 
					3 { $TrustType = "MIT (non-Windows) Kerberos version 5 realm"} 
					4 { $TrustType = "DCE (Theoretical trust type - DCE refers to Open Group's Distributed Computing Environment specification)"} 
					Default { $TrustType = $TrustTypeNumber }
				} 

				#http://msdn.microsoft.com/en-us/library/cc223779.aspx
				Switch ($TrustAttributesNumber) 
				{ 
					1 { $TrustAttributes = "Non-Transitive"} 
					2 { $TrustAttributes = "Uplevel clients only (Windows 2000 or newer"} 
					4 { $TrustAttributes = "Quarantined Domain (External)"} 
					8 { $TrustAttributes = "Forest Trust"} 
					16 { $TrustAttributes = "Cross-Organizational Trust (Selective Authentication)"} 
					32 { $TrustAttributes = "Intra-Forest Trust (trust within the forest)"} 
					64 { $TrustAttributes = "Inter-Forest Trust (trust with another forest)"} 
					Default { $TrustAttributes = $TrustAttributesNumber }
				} 
				 
				#http://msdn.microsoft.com/en-us/library/cc223768.aspx
				Switch ($TrustDirectionNumber) 
				{ 
					0 { $TrustDirection = "Disabled (The trust relationship exists but has been disabled)"} 
					1 { $TrustDirection = "Inbound (TrustING domain)"} 
					2 { $TrustDirection = "Outbound (TrustED domain)"} 
					3 { $TrustDirection = "Bidirectional (two-way trust)"} 
					Default { $TrustDirection = $TrustDirectionNumber }
				}
					   
				Write-output "`tTrust Name: $TrustName `r " 
				Write-output "`tTrust Description: $TrustDescription `r " 
				Write-output "`tTrust Created: $TrustCreated `r " 
				Write-output "`tTrust Modified: $TrustModified  `r " 
				Write-output "`tTrust Direction: $TrustDirection `r " 
				Write-output "`tTrust Type: $TrustType `r " 
				Write-output "`tTrust Attributes: $TrustAttributes `r " 
				Write-output " `r " 
			}
		}
		ElseIf(!$?)
		{
			#error retrieving domain trusts
			Write-output "Error retrieving domain trusts for $Domain"
		}
		Else
		{
			#no domain trust data
			Write-output "No domain trust data for $Domain"
		}
	} 
}
ElseIf(!$?)
{
	#error retrieving domains
	Write-output "Error retrieving domains"
}
Else
{
	#no domain data
	Write-output "No domain data"
}

The original script only processed the domain in which the user was running the script. I changed it to process all domains in the forest.

I am using Write-Output as that is what the original script uses. I will update this code to work in my script using my normal output routines.

Thanks

Webster

, , ,

About Carl Webster

Webster is an independent consultant in the Nashville, TN area and specializes in Citrix, Active Directory and Technical Documentation. Webster has been working with Citrix products for many years starting with Multi-User OS/2 in 1990.

View all posts by Carl Webster

3 Responses to “Finding Domain Trusts in an Active Directory Forest using Microsoft PowerShell”

  1. Rejone Says:

    Hi Jeremy;

    Great info. We have an issue with a child domain. We recently deployed Citrix VDI and all of our virtual machines are not able to ping our child domain controllers. Have you seen this issue before? Any help would be appreciated.

    Rejone

    Reply

    • Jeremy Saunders Says:

      Hi Rejone,

      Not sure if your question was for Webster or myself.

      I would expect this to be a host (Windows) firewall issue, but we would need more information from you before concluding that this is the issue:
      – Are the VMs also in the child domain?
      – Can the VMs communicate with the child domain controllers on other ports, such as LDAP, browse to the SYSVOL, etc?

      As this question is unrelated to Webster’s script it’s probably a question that would be better posed on a forum so that others can join in the discussion to assist you.

      Cheers,
      Jeremy

      Reply

  2. Jeremy Saunders Says:

    Nice work Webster. I found the same issue with that script, but haven’t had the time to re-write it.

    You may also want to report whether or not the trust supports AES encryption by examining the value of the msDS-SupportedEncryptionTypes attribute. If enabled the value is typically 24 (8 = AES 128 bit key length, 16 = AES 256 bit key length)

    If it’s a forest trust, you’ll want to to get the Name Suffix Routing from the msDS-TrustForestTrustInfo attribute, which you can only do by examining the output of the “netdom trust” command.
    - http://blogs.msdn.com/b/spatdsg/archive/2008/08/21/kerberos-domain-routing.aspx
    - http://xitnotes.wordpress.com/2012/03/29/kerberos-in-an-active-directory-forest-trust-vs-external-trust/

    Cheers,
    Jeremy

    Reply

Leave a Reply

Current ye@r *