powershellclassrunspace

Powershell Add custom class to InitialSessionState of runspacepool


I can add a function to my runspacepool using initialsessionstate like this:

$initialSessionState = [InitialSessionState]::CreateDefault()
$definition = Get-Content Function:\Icmp-Ping -ErrorAction Stop   
$addMessageSessionStateFunction = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList 'Icmp-Ping', $definition
$initialSessionState.Commands.Add($addMessageSessionStateFunction)

Now u want u add a simple class definition in the same manner:

I tried to use add-type with no success, i also read about type tables, but cant find a matching example for runspacepools. The classes type is unknown to the script in the runspace. At this point I wonder if what i want is possible at all. On the other hand if I can introduce functions and sessionstatevariables like this why not classes?


Solution

  • For an external assembly you could add using a SessionStateAssemblyEntry:

    $iss = [InitialSessionState]::CreateDefault()
    $iss.Assemblies.Add([System.Management.Automation.Runspaces.SessionStateAssemblyEntry]::new(
        ...
        ...))
    

    However for PowerShell classes this is not an option as far as I know, the alternatives are either hardcode the class definition in the runspace script itself:

    $ps = [powershell]::Create().AddScript{
        class Test {
            static [string] SayHey() {
                return 'hey there!'
            }
        }
        [Test]::SayHey()
    }
    $ps.Invoke()
    

    Or if you have the definitions in a ps1 file, you can dot source it in the runspace script. For this second option you could for example pass an array of paths to the runspace using a parameter, this is obviously not needed but might be cleaner than hardcoding the path in the runspace script itself.

    $paths = @(
        'path\to\myTestClass.ps1'
        'path\to\myOtherTestClass.ps1'
    )
    
    $ps = [powershell]::Create().AddScript{
        param([string[]] $ClassesToLoad)
    
        $ClassesToLoad | ForEach-Object { . $_ }
    
        [Test]::SayHey()
    }.AddParameters(@{ ClassesToLoad = $paths })
    $ps.Invoke()