GetAllMethods.psm1

Function Get-Method {
    <#
    .SYNOPSIS
    Gets methods of objects, even private methods.
    .DESCRIPTION
    Get-Method retrieves methods of objects, even private methods.
 
    The object sent to Get-Method is a Type object representing the class of objects to retrieve methods from. Binding flags are used to differentiate between public and private, and static and instance using either the switch parameters or an array of flags to the BindingFlags parameter.
 
    It must be noted that when using flags, one of either public or private, and one of either static or instance must both be used.
    .PARAMETER Type
    The type to retrieve methods from.
    .PARAMETER Name
    The name of the method to retrieve. Accepts wildcards.
    .PARAMETER BindingFlags
    The binding flags to be used when retrieving methods. The default is to retrieve public instance methods.
    .PARAMETER Public
    Specifies the Public binding flag.
    .PARAMETER NonPublic
    Specifies the NonPublic binding flag, i.e. private.
    .PARAMETER Static
    Specifies the Static binding flag.
    .PARAMETER Instance
    Specifies the Instance binding flag.
    .INPUTS
    System.Type
 
 
    You can pipe System.Type objects to Get-Method.
    .OUTPUTS
    System.Reflection.MethodInfo
 
 
    Get-Method returns a MethodInfo object for each method retrieved.
    .EXAMPLE
    [System.Windows.Controls.Button] | Get-Method
 
    This command will get the public instance methods (by default) for the WPF Button class. This is especially useful for finding the available event methods on WPF elements like add_Click which Get-Member does not return.
    .EXAMPLE
    [Array] | Get-Method -NonPublic -Static
 
    This command will get the private static methods for the Array class.
    .EXAMPLE
    [String] | Get-Method -BindingFlags 'Public','NonPublic','Static','Instance'
 
    This command will get all the methods available to the String class.
    .EXAMPLE
    [System.Windows.Controls.Button] | Get-Method -Name add_Click
 
    This command will get the method add_Click for the WPF Button class.
    .EXAMPLE
    [System.Windows.Controls.Button] | Get-Method -Name add_*
 
    This command will get all methods that start with add_ for the WPF Button class.
    .NOTES
    I created this originally to easily find the event methods used for WPF elements like add_Click on buttons. It has since been updated for a more universal role.
 
    Author: Chris Carter
    Version: 1.0
    #>


    #Requires -Version 3.0
    [CmdletBinding(DefaultParameterSetName="Flags")]

    Param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [Alias("IO")]
            [Type]$Type,

        [Parameter(Position=0)]
            [String]$Name,

        [Parameter(Position=1,ParameterSetName="Flags")]
            [Alias("BF")]
            [System.Reflection.BindingFlags]$BindingFlags=@('public','instance'),

        [Parameter(ParameterSetName="Switches")]
            [Alias("P")]
            [Switch]$Public,

        [Parameter(ParameterSetName="Switches")]
            [Alias("NP")]
            [Switch]$NonPublic,

        [Parameter(ParameterSetName="Switches")]
            [Alias("S")]
            [Switch]$Static,

        [Parameter(ParameterSetName="Switches")]
            [Alias("I")]
            [Switch]$Instance
    )

    Begin {
        Function Test-Flag ($Enum, [System.Reflection.BindingFlags]$Flag, [System.Reflection.BindingFlags]$RequiredFlag1, [System.Reflection.BindingFlags]$RequiredFlag2) {
            if ($Enum.HasFlag($Flag)) {
                if (-not ($Enum.HasFlag($RequiredFlag1) -or $Enum.HasFlag($RequiredFlag2))) {
                    throw "When using the binding flag $Flag, you must include either $RequiredFlag1 or $RequiredFlag2."
                }
            }
        }

        Function New-MethodDefinition ([Parameter(ValueFromPipeline=$true)]$Method) {
            Process {
                foreach ($m in $Method) {
                    $Definition = ''
                    $strParams = @()
                    if ($m) {
                        switch ($m) {
                            {$_.IsPublic}  {$Definition += "public "}
                            {$_.IsPrivate} {$Definition += "private "}
                            {$_.IsStatic}  {$Definition += "static "}
                        }

                        $Definition += "$($m.ReturnType) $($m.Name)("

                        $parms = $m.GetParameters() | Sort-Object -Property Position

                        foreach ($p in $parms) {
                            $strParams += "$($p.ParameterType) $($p.Name)"
                        }

                        $Definition += ($strParams -join ', ') + ')'

                        $m | Add-Member -NotePropertyName Definition -NotePropertyValue $Definition -PassThru -Force
                    }
                }
            }
        }

        if ($PSCmdlet.ParameterSetName -eq "Switches") {
            $BindingFlags = New-Object System.Reflection.BindingFlags

            foreach ($flag in $PSBoundParameters.Keys | Where-Object {$_ -in 'Public','NonPublic','Static','Instance'}) {
                $BindingFlags = $BindingFlags -bxor $flag
            }
        }

        switch ('Public','NonPublic','Static','Instance') {
            { $_ -eq 'Public' -or $_ -eq 'NonPublic' } { Test-Flag -Enum $BindingFlags -Flag $_ -RequiredFlag1 Static -RequiredFlag2 Instance }
            { $_ -eq 'Static' -or $_ -eq 'Instance' }  { Test-Flag -Enum $BindingFlags -Flag $_ -RequiredFlag1 Public -RequiredFlag2 NonPublic }
        }
        Write-Verbose "Binding Flags being used: $BindingFlags"
    }

    Process {
        foreach ($t in $Type) {
            if ($Name) {
                $t.GetMethods($BindingFlags) | Where-Object Name -Like $Name | New-MethodDefinition | Sort-Object -Property Name
            }
            else {
                $t.GetMethods($BindingFlags) | New-MethodDefinition | Sort-Object -Property Name
            }
        }
    }
}

Function Get-MethodParameter {
    <#
    .SYNOPSIS
    Gets parameters of methods.
    .DESCRIPTION
    Get-MethodParameter gets the parameters of a method supplied as a MethodInfo object.
    .PARAMETER Method
    The method to get parameters from.
    .PARAMETER Name
    The name of the parameter to retrieve. Accepts wildcards.
    .INPUTS
    System.Reflection.MethodInfo
 
 
    You can pipe MethodInfo objects to Get-MethodParameter.
    .OUTPUTS
 
 
    System.Reflection.ParameterInfo
    Get-Method returns a Parameter object for each parameter retrieved.
    .EXAMPLE
    [String] | Get-Method -Name CreateTrimmedString -NonPublic -Instance | Get-MethodParameter
 
    This command will get the parameters of the private instance method CreateTrimmedString of the String class.
    .EXAMPLE
    [String] | Get-Method -Name CreateTrimmedString -NonPublic -Instance | Get-MethodParameter -Name start
 
    This command will get the parameter start of the private instance method CreateTrimmedString of the String class.
    .NOTES
    This is a companion to the Get-Method command in this module.
 
    Author: Chris Carter
    Version: 1.0
    #>


    #Requires -Version 3.0
    [CmdletBinding()]

    Param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [System.Reflection.MethodInfo]$Method,

        [Parameter(Position=0)]
            [String]$Name
    )

    Process {
        foreach ($m in $Method) {
            if ($Name) {
                $m.GetParameters() | Where-Object Name -Like $Name | Sort-Object -Property Position
            }
            else { $m.GetParameters() | Sort-Object -Property Position }
        }
    }
}

Function Invoke-Method {
    <#
    .SYNOPSIS
    Invokes the method given.
    .DESCRIPTION
    Invokes the method given to the Method parameter. The object to invoke the method on is supplied to the Object parameter, and any arguments to the method's parameters are given to the ArgumentList parameter.
 
    The arguments in the ArgumentList must be of the type and in the correct order required by the method. If no arguments are required, the default is Null.
 
    In the case of static methods, a value of Null is provided to the Object parameter by default.
    .PARAMETER Method
    The method to invoke.
    .PARAMETER Object
    The object to invoke the method on. Default value is Null, provided to static methods.
    .PARAMETER ArgumentList
    The list of arguments to provide to the method's parameters. Default value is Null, when no arguments are required.
    .INPUTS
    System.Reflection.MethodInfo
 
 
    You can pipe MethodInfo objects to Invoke-Method.
    .OUTPUTS
    System.Object
 
 
    The output is determined by the return value of the invoked method.
    .EXAMPLE
    [String] | Get-Method -Name Copy -BF 'Public','Static' | Invoke-Method -ArgumentList "Test String"
 
    This command will invoke the public static Copy method on the string "Test String". Since it is a static method, no object is provided to the Object parameter.
    .EXAMPLE
    [String] | Get-Method -Name CreateTrimmedString -NonPublic -Instance | Invoke-Method -Object "Test String" -ArgumentList 0,5
 
    This command will invoke the private CreateTrimmedString method on the string "Test String" supplying the arguments 0 and 5 to the start and end parameters.
    .NOTES
    This command is intended for use with private methods, since public ones can be called using more standard means, i.e. $obj.Method() or [Object]::Method().
 
    It will work on public methods, such as the first example.
 
    Author: Chris Carter
    Version: 1.0
    #>


    #Requires -Version 3.0
    [CmdletBinding()]

    Param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [System.Reflection.MethodInfo]$Method,

        [Parameter(Position=0)]
            [Object]$Object=$null,

        [Parameter(Position=1)]
            [Alias("Args")]
            [Object[]]$ArgumentList=$null
    )

    Begin {
        Function Test-Parameter ([System.Reflection.MethodInfo]$Method, [Object[]]$ArgsList) {
            Write-Verbose "Testing parameters supplied to ArgumentList for correctness of number and type."
            $params = $Method.GetParameters() | Sort-Object -Property Position

            if ($ArgsList.Count -ne $params.Count) {
                Write-Error "The parameters supplied to the ArgumentList do not match the number ($($ArgsList.Count)) needed by the method ($($params.Count)). Check that the correct overload is being invoked."
                $false
            }
            else {
                Write-Verbose "The number of parameters supplied to ArgumentList are correct." 
                for ($i = 0; $i -lt $ArgsList.Count; $i++) {
                    if ($ArgsList[$i] -isnot $params[$i].ParameterType) {
                        Write-Error "The parameter supplied to position $i is not of the type $($params[$i].ParameterType.FullName) required by the method. Check that the correct overload is being invoked."
                        $false
                        break
                    }
                    else { Write-Verbose "The parameter at position $i is the correct type: $($params[$i].ParameterType.FullName)."; $true }
                }
            }
        }
    }

    Process {
        foreach ($m in $Method) {
            if (Test-Parameter -Method $m -ArgsList $ArgumentList) {
                Write-Verbose "Invoking the method $($m.Name)."
                $m.Invoke($Object, $ArgumentList)
            }
        }
    }
}

New-Alias -Name gmth -Value Get-Method
New-Alias -Name gmpm -Value Get-MethodParameter
New-Alias -Name imth -Value Invoke-Method