PowerShell - Convert a .NET Type’s static methods into a Module

Updated 2012/9/24: $type.Name -> $type.FullName (otherwise only types directly in System namespace are found... oops!)

Here’s something I just knocked up recently to have a nice and simple way to import groups of functions temporarily from a .NET Type as a module. When you’re done with them, you can unload at any time using Remove-Module. As the inline help mentions, you must pipe the output of this function into Import-Module to make the functions available. You have to be somewhat familiar with the methods you’re converting in order to know what order to pass parameters. Some are obvious in that they only take one argument (like Sin, Cos or Tan) but others you’ll have to double check yourself. It would have been nice to convert .NET parameters and overloads into parameter sets, but the differences between how PowerShell and the .NET compilers resolve ambiguities can be very different and would only work for mostly simple cases. Here’s how I like to quickly check method syntax:

PS C:\projects> [math]::Log

OverloadDefinitions
-------------------
static double Log(double d)
static double Log(double a, double newBase)

Here's the function itself ( also available on poshcode (updated) )

function ConvertTo-Module {
<#
    .SYNOPSIS
    Quickly convert a .NET type's static methods into functions

    .DESCRIPTION
    Quickly convert a .NET type's static methods into functions.
    
    This function returns a PSModuleInfo, so you should pipe its
    output to Import-Module to use the exported functions.

    .PARAMETER Type
    The type from which to import static methods. 

    .INPUTS
    System.String, System.Type

    .OUTPUTS
    PSModuleInfo

    .EXAMPLE
    ConvertTo-Module System.Math | Import-Module -Verbose

    .EXAMPLE
    [math] | ConvertTo-Module | Import-Module -Verbose

#>
    [outputtype([psmoduleinfo])]
    param(
        [parameter(
            position=0,
            valuefrompipeline=$true,
            mandatory=$true)]
        [validatenotnull()]
        [type]$Type
    )

    new-module {
        param($type)
         
        ($exports = $type.getmethods("static,public").Name | sort -uniq) | `
            % {
                $func = $_
                new-item "function:script:$($_)" `
                    -Value {
                        # look mom! no [scriptblock]::create!
                        ($type.FullName -as [type])::$func.invoke($args)

                    }.GetNewClosure() # capture the value of $func
            }
        export-modulemember -function $exports
    } -name $type.Name -ArgumentList $type
}

Have fun!

blog comments powered by Disqus

About the author

Irish, PowerShell MVP, .NET/ASP.NET/SharePoint Developer, Budding Architect. Developer. Montrealer. Opinionated. Montreal, Quebec.

Month List

Page List