4

I am trying to call\create runspace within a class that derived from PSCmdlet. Since PSCmdlet includes a default session state that contains shared data I want to reuse in the runspace, I am wondering if there is a programmatically way to convert the current sessionState into the runspace's InitialSessionState ?

If there is no such way, I am not really understand why such session state info cannot be shared within different runspace. This looks like running a remote runspace to me. Can anyone explain?

For example,

namespace CustomCmdlet.Test
{
    [Cmdlet("Get", "Test1")]
    public class GetTest1 : PSCmdlet
    {
        protected override void ProcessRecord()
        { WriteObject("1"); }
    }

    [Cmdlet("Get", "Test2")]
    public class GetTest2 : PSCmdlet
    {
        protected override void ProcessRecord()
        {
         // instead of import the module dll using Runspace
         // InitialSessionState.ImportModule(new string[] {"CustomCmdlet.Test.dll"});
         // Runspace runspace = RunspaceFactory.CreateRunspace(InitialSessionState)

         // is it any way to import the PSCmdlet.SessionState into the InitialSessionState?
        }
    }

We are using PowerShell 4.0, if this is relevant.

2 Answers 2

4

Session state definitely can't be shared across runspaces, it holds session specific data like variables.

The InitialSessionState that was used to create a runspace is a property of the runspace. You can access the current runspace via thread local storage using the Runspace.DefaultRunspace property: http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspace.defaultrunspace(v=vs.85).aspx

That said, you may want to look at RunspacePool - the pool of runspaces will all be created from the same InitialSessionState. This way you avoid creating more runspaces than necessary, instead just reusing a runspace from the pool.

Sign up to request clarification or add additional context in comments.

2 Comments

To extend from your answer, why is the session states not able to be shared across runspaces? session states has private\public property and can be used by other sessions, and I think runspace is simulating a session?
Session state is like a scope or stack frame. It doesn't use any sort of locking, so state shared across runspaces can easily be corrupted.
0

I know this is years late, but

$maxThreads = 17;
            $iss = [system.management.automation.runspaces.initialsessionstate]::CreateDefault();
            [void]$iss.ImportPSModule($exchangeModule.Path)
            $runspacePool = [runspacefactory]::CreateRunspacePool(1, $maxThreads, $iss, $host)
            $runspacePool.Open() > $null;
            
        #EndRegion Initial sessionstate

        
        #Region Run threads and collect data

            $threads = New-Object System.Collections.ArrayList;
            foreach ($server in $servers)
            {
                if (!($server.ToString().Contains("unreachable")))
                {
                    $powerShell = [powershell]::Create($iss);
                    $powerShell.RunspacePool = $runspacePool;
                    
                    
                    [void]$powerShell.AddScript({       
                        Param ($server)     
                        [pscustomobject]@{

                            server = $server

                        } | Out-Null
                        
                        $global:ProgressPreference = 'SilentlyContinue';
                        $returnVal = Get-Queue -Server $server; # | where {$_.MessageCount -gt 1};
                        $customObject = New-Object -TypeName psobject;
                        $customObject | Add-Member -MemberType NoteProperty -Name ServerName -Value $server;
                        $customObject | Add-Member -MemberType NoteProperty -Name MessageCountObject -Value $returnVal;
                        #Write-Host "Object return value is is: " $messageCountObject;
                        return $customObject;

                    }) # end of powershell.Add script
                    $powerShell.AddParameter('server', $server) | Out-Null; 
                    $returnVal = $PowerShell.BeginInvoke();
                    $temp = "" | Select PowerShell,returnVal;
                    $temp.PowerShell = $PowerShell;
                    $temp.returnVal = $returnVal;
                    $threads.Add($Temp) | Out-Null;
                }
                else
                {
                    $threads.Add($server) | Out-Null;
                }
            } #foreach server

        #EndRegion Run threads and collect data

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.