Skip to content

Instantly share code, notes, and snippets.

@sasqwatch
Forked from Cirzen/InterfaceTree.psm1
Created March 15, 2019 21:04
Show Gist options
  • Save sasqwatch/1feb598b40815f26de13551112dd25ff to your computer and use it in GitHub Desktop.
Save sasqwatch/1feb598b40815f26de13551112dd25ff to your computer and use it in GitHub Desktop.
Get InterfaceTree module
function Get-InterfaceTree
{
<#
.SYNOPSIS
Displays a tree of interfaces for a given type
.DESCRIPTION
Recursively runs the "GetInterfaces() method on a type and its interfaces to build a picture of all the interfaces that are applied to a type"
.EXAMPLE
PS C:\> Get-InterfaceTree hashtable
Hashtable
IDictionary
ICollection
IEnumerable
IEnumerable
ICollection
IEnumerable
IEnumerable
ISerializable
IDeserializationCallback
ICloneable
.Example
PS C:\>Get-InterfaceTree ([System.Collections.Generic.ICollection[string]]) -ShowFullTypeName
System.Collections.Generic.ICollection`1[[System.String]]
System.Collections.Generic.IEnumerable`1[[System.String]]
System.Collections.IEnumerable
System.Collections.IEnumerable
This example shows use of the ShowFullTypeName switch parameter to show all types including namespaces
.Example
PS C:\>Get-InterfaceTree ([System.Collections.Generic.IEnumerable[string]]) -ShowFullTypeName -NoTrimGenericTypeNames
System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
System.Collections.IEnumerable
This example shows use of the "NoTrimGenericTypeNames" switch parameter when querying a generic type to show the full type details.
This parameter will only have an effect when used with the "ShowFullTypeName" switch parameter.
.Parameter Type
The type, or name of a type on which to get the interface tree. If a string is supplied, the text will be attempted to be matched to a type name. e.g. "hashtab" would resolve to [hashtable]
.Parameter ShowFullTypeName
Forces the output to include the full type name in place of the standard type name, e.g. System.Collections.IDictionary instead of "IDictionary"
.Parameter NoTrimGenericTypeNames
By default, this function will trim full generic type information ( e.g. [System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089] will become [System.Type] )
Specify this switch parameter to show the full details on generics.
.INPUTS
A type object or string representation of a type
.OUTPUTS
A collection of strings representing the interface name and nesting position within the tree
.NOTES
Author: David Johnson
To pass a type to the -Type parameter, enclose the type name in parentheses, e.g. "-Type ([string])"
#>
[cmdletBinding()]
Param(
[Parameter(Position = 0, Mandatory, ValueFromPipeline)]
[ValidateScript( {$_ -is [type] -or $_ -is [string]})]
$Type,
[switch]
$NoTrimGenericTypeNames,
[switch]
$ShowFullTypeName,
[int]
$Indent = 0
)
Begin
{
#$xlr = [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")
function CleanTypeString
{
Param(
# The string on which to do the work
[Parameter(Mandatory, ValueFromPipeline)]
[string]$String,
# Skip processing
[switch]$DoNothing
)
if ($DoNothing)
{
return $String
}
$StringArray = $String -split '\['
$regex = '([\w.\[\]]+?), (.+?), (Version=\d+\.\d+\.\d+\.\d+), (Culture=.+?), (PublicKeyToken=[0-9a-f]+)\]'
If ($string -notmatch $regex)
{
return $String
}
for ($i = 0; $i -lt $Stringarray.Count; $i++)
{
while ($StringArray[$i] -match $regex)
{
$StringArray[$i] = ($StringArray[$i] -replace $regex, '$1]')
}
}
return (CleanTypeString ($StringArray -join '['))
}
}
Process
{
$Name = "Name"
If ($ShowFullTypeName)
{
$Name = "FullName"
}
If ($Type -is [String])
{
# Attempt to translate the string to a type object
try
{
$type = [type]$Type
}
catch
{
$InnerException = $_.Exception
try
{
$ThrowOnError = $true
$IgnoreCase = $true
$GuessType = CompleteTypeName -TypeString $Type
$type = [type]::GetType($Guesstype, $ThrowOnError, $IgnoreCase)
}
catch [System.Management.Automation.MethodInvocationException]
{
throw [System.Management.Automation.MethodInvocationException]::new($_.Exception.Message, $InnerException)
}
catch
{
Throw $InnerException
}
}
}
If ($Indent -eq 0)
{
$Type.$Name | CleanTypeString -DoNothing:$NoTrimGenericTypeNames
return Get-InterfaceTree -Type $Type -ShowFullTypeName:$ShowFullTypeName -NoTrimGenericTypeNames:$NoTrimGenericTypeNames -Indent 1
}
$Interfaces = $Type.GetInterfaces()
If (@($Interfaces).Count -eq 0)
{
return
}
forEach ($Interface in $Interfaces)
{
Write-Output (CleanTypeString ((" " * $Indent) + $Interface.$Name) -DoNothing:$NoTrimGenericTypeNames)
Get-InterfaceTree -Type $InterFace -Indent ($Indent + 1) -ShowFullTypeName:$ShowFullTypeName -NoTrimGenericTypeNames:$NoTrimGenericTypeNames
}
}
}
Export-ModuleMember -Function "*-*"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment