Dynamic binary modules

Dynamic binary modules

  • Comments 2

Using add-type and import-module you can dynamically compile and load an assembly without any intermediate assembly files to cleanup.

For instance, to run a cmdlet on a remote machine you could send over the cmdlet source code, compile, import, and run it all on the fly.

Let’s say you have your cmdlet called Use-MyCmdlet as C# code in the file mycode.cs:

PS> [string] $code = Get-Content mycode.cs
PS> $s = New-PSSession remoteHost
PS> Invoke-Command $s `
{(Add-Type -TypeDefinition $args[0] -PassThru).assembly | Import-Module} `
-ArgumentList $code
PS> Invoke-Command $s {Use-MyCmdlet}
PS> Remove-PSSession $s


This example gets the C# code as a string and starts a remote session.
It then compiles the code in the remote session with Add-Type and passes the resulting assembly object to import-module.
 
The cmdlet Use-MyCmdlet is invoked in the remote session which is then removed, with no need to remove any intermediate files on the remote system.

Nigel Sharples [MSFT]

Leave a Comment
  • Please add 4 and 7 and type the answer here:
  • Post
  • Invoke-Command $s { dir c:\ } # works

    I've tried the code snippet for "dynamic modules" using this code as a test

    http://msdn.microsoft.com/en-us/library/dd901838(VS.85).aspx

    while it compiles fine and loads into my session if I do the following by hand

    csc /target:library ./mycode.cs /reference:'C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll'

    Import-Module -Name .\mycode.dll

    Send-Greeting -Name bob

    The same code fails when I execute the following command

    Invoke-Command $s { (Add-Type -TypeDefinition $args[0] -PassThru).Assembly `

    | Import-Module } -ArgumentList $code

    I've tried both

    [string]$code = gc mycode.cs

    and

    [string]$code = gc mycode.cs -encoding ascii

    but get the same error

    WARNING: The generated type is not public.

    Cannot bind argument to parameter 'Name' because it is null.

       + CategoryInfo          : InvalidData: (:) [Import-Module], ParameterBindingValidationException

       + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ImportModul

      eCommand

    does this make any sense to you?

  • Try this to get mycode.cs as a string to preserve the newlines:

    [string]$code = gc mycode.cs | out-string

Page 1 of 1 (2 items)