functions/Get-TypeMember.ps1

<#
This is an alternative function you can use in-place of Get-Member.
#>


class ResolveType : System.Management.Automation.ArgumentTransformationAttribute {
    #define a class method that returns an object
    [object]Transform([System.Management.Automation.EngineIntrinsics]$engineIntrinsics, [object]$inputData) {
        [regex]$rx = '(?<=\[).*(?=\])'
        if ($rx.IsMatch($inputData)) {
            #This will be the new parameter value
            #write-host "converting to type" -ForegroundColor Magenta
            return ($rx.Match($inputData).Value -as [Type])
        }
        else {
            #write-host "no change" -ForegroundColor cyan
            return $inputData
        }
    }
}

#Get-MemberMethod is a private function and not exported
function Get-MemberMethod {
    [cmdletbinding()]
    [OutputType('string')]
    [alias('gmm')]
    param(
        [Parameter(
            Position = 0,
            Mandatory,
            ValueFromPipelineByPropertyName,
            HelpMessage = 'Specify the typename like System.Diagnostics.Process'
        )]
        [ValidateNotNullOrEmpty()]
        [ResolveType()]
        [alias('Type')]
        [type]$TypeName,
        [Parameter(
            Position = 1,
            Mandatory,
            ValueFromPipelineByPropertyName,
            HelpMessage = 'Specify the method name. The method name is case-sensitive'
        )]
        [alias('Name')]
        [string]$MethodName
    )

    begin {
        #tags are used for categorizing the command
        #cmdTags = scripting
        Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)"
        Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)"
    } #begin

    process {
        Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing method $MethodName from $($TypeName.Name)"

        $methods = $TypeName.GetMember($MethodName).Where({ $_.MemberType -eq 'method' })
        Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $($methods.count) overloads"
        foreach ($method in $methods) {
            $rType = $method.ReturnType.Name
            $params = foreach ($param in $method.GetParameters()) {
                '[{0}]{1}' -f $param.ParameterType.Name, $param.name
            }
            # This will include the return type
            # '{0} {1}({2})' -f $rType, $method.Name, ($params -join ',')
            '$obj.{0}({1})' -f $method.Name, ($params -join ',')
        }
    } #process

    end {
        Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
    } #end

} #close Get-MemberMethod

function Get-TypeMember {
    [cmdletbinding(DefaultParameterSetName = 'member')]
    [OutputType('psTypeMember')]
    [Alias('gtm')]
    param(
        [Parameter(
            Position = 0,
            Mandatory,
            HelpMessage = 'Specify a .NET type name like DateTime'
        )]
        [ValidateNotNullOrEmpty()]
        [ResolveType()]
        [type]$TypeName,
        [Parameter(ParameterSetName = 'static', HelpMessage = 'Get only static members.')]
        [switch]$StaticOnly,
        [Parameter(ParameterSetName = 'enum', HelpMessage = 'Get only enum members.')]
        [switch]$EnumOnly,
        [Parameter(ParameterSetName = 'member', HelpMessage = 'Filter for a specific member type.')]
        [ValidateSet('Property', 'Method', 'Event', 'Field')]
        [string]$MemberType,
        [Parameter(
            Mandatory,
            HelpMessage = 'Specify a member name',
            ParameterSetName = 'name'
        )]
        [SupportsWildCards()]
        [alias('Name')]
        [string]$MemberName
    )

    begin {
        #tags are used for categorizing the command
        #cmdTags = scripting

        Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)"

        #define the appropriate filter
        if ($MemberName) {
            Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Filtering by member name $MemberName"
            $filter = { (-not $_.IsSpecialName) -and ($_.Name -like $MemberName) }
        }
        elseif ($StaticOnly) {
            Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Filtering for Static methods"
            $filter = { -not $_.IsSpecialName -and $_.IsStatic }
        }
        elseif ($MemberType) {
            Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Filtering for $MemberType methods"
            $filter = { -not $_.IsSpecialName -and $_.MemberType -eq $MemberType }
        }
        elseif ($EnumOnly) {
            Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Filtering for Enum properties"
            $filter = { -not $_.IsSpecialName -and $_.propertyType.IsEnum }
        }
        elseif ($force) {

        }
        else {
            Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Filtering for all non-special members"
            $filter = { -not $_.IsSpecialName -and -not $_.IsVirtual }
        }
    } #begin
    process {
        Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing $($typename.name)"
        #Create the output
        $typeName.GetMembers() | Where-Object $filter |
        Select-Object -Property Name, MemberType, FieldType, PropertyType, ReturnType, IsStatic -Unique |
        Sort-Object -Property MemberType, Name |
        ForEach-Object {
            [PSCustomObject]@{
                PSTypeName   = 'psTypeMember'
                Type         = $typeName.FullName
                Name         = $_.Name
                MemberType   = $_.MemberType
                PropertyType = $_.PropertyType
                ReturnType   = $_.ReturnType
                FieldType    = $_.FieldType
                IsStatic     = $_.IsStatic
                IsEnum       = $_.PropertyType.IsEnum
                Syntax       = Get-MemberMethod -Type $typename.FullName -MethodName $_.Name
            }
        } #Foreach-Object
    } #process
    end {
        Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
    } #end
} #close function

function Get-TypeConstructor {
    [cmdletbinding(DefaultParameterSetName = 'member')]
    [OutputType('psTypeMemberConstructor')]
    [alias('ctor')]
    param (
        [Parameter(
            Position = 0,
            Mandatory,
            HelpMessage = 'Specify a .NET type name like DateTime'
        )]
        [ValidateNotNullOrEmpty()]
        [ResolveType()]
        [Type]$TypeName
    )

    begin {
        #tags are used for categorizing the command
        #cmdTags = scripting

        Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)"
        Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)"
    } #begin

    process {
        Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing $($typename.name)"
        $Constructors = $typename.GetConstructors()
        if ($Constructors) {
            Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $($Constructors.count) constructors"
            foreach ($c in $Constructors) {
                $cParams = $c.GetParameters()
                if ($cParams) {
                    $newParams = $cParams | Select-Object ParameterType,
                    @{Name = 'ParameterName'; Expression = { $_.Name } }
                }
                else {
                    $newParams = @()
                }

                [PSCustomObject]@{
                    PSTypeName = 'psTypeMemberConstructor'
                    Type       = $typename.FullName
                    Parameters = $newParams
                }
            } #foreach c
        } #if Constructors found
        else {
            Write-Warning "No constructors found for [$($typename.FullName)]. This may be a static class or an [Enum]."
        }
    } #process

    end {
        Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
    } #end
} #close function

#EOF