Dynamic Variables and Runspaces

Hi All, this is my first post and i’m a hack, so please be gentle.

I’ve created a bunch of runspaces manually each with their own variable names etc,

I’d like to make a template script or function to tidy up my code

I assume this would require the use of New-Variable to dynamically generate the variable names,

but I cant work out then how to access the runspace properties assigned to that dynamic variable

Help please

I’ve included working and test code below:

##
#example of working code to create a runspace and run script in new runspace
##
    
#Create a synchronised hashtable to share variables between runspaces if required
If($sync.count -lt 1){$sync = [hashtable]::Synchronized(@{})}
    
$myScriptMyRunspace =[runspacefactory]::CreateRunspace()
$myScriptMyRunspace.ApartmentState = "STA"
$myScriptMyRunspace.ThreadOptions = "ReuseThread"   
$myScriptMyRunspace.name = "myScriptMyRunspace"   
$myScriptMyRunspace.Open()
$myScriptMyRunspace.SessionStateProxy.SetVariable("sync",$sync)

$myScriptCmd = [PowerShell]::Create().AddScript({
    #some code here
})

#run script in new runspace
$myScriptCmd.Runspace = $myScriptMyRunspace
$myScriptGUI = $myScriptCmd.BeginInvoke(),"Background"

######################################################################################

##
#Attempting to do this same thing with dynamic naming of the variables, to create a function for creating runspaces
##

$shortName = "myScript"
$runspaceName = $shortName + "MyRunspace"
$scriptCmd = $shortName + "Cmd"
$scriptGUI = $shortName + "GUI"

#create dynamic variable names and assign to runspace
New-Variable $runspaceName -Force
New-Variable $scriptCmd -Force
New-Variable $scriptGUI -Force

#Create Runspace
Set-Variable $runspaceName -Value ([runspacefactory]::CreateRunspace())
(Set-Variable $runspaceName).ApartmentState = "STA"
(Set-Variable $runspaceName).ThreadOptions = "ReuseThread"   
(Set-Variable $runspaceName).name = "myScriptMyRunspace"   
(Set-Variable $runspaceName).Open()
(Set-Variable $runspaceName).SessionStateProxy.SetVariable("sync",$sync)

Set-Variable $scriptCmd -Value ([PowerShell]::Create().AddScript({
    #some code here
    })
)

#run script in new runspace
(Set-Variable $ScriptCmd).Runspace = (Get-Variable $runspaceName)
Set-Variable $scriptGUI -Value ($ScriptCmd.BeginInvoke(),"Background")

 

You need to provide a string to New-Variable, not a variable, so remove the dollar sign. Here’s an example of how to create, capture, and manipulate dynamic variables.


# Create variables, capturing them in another variable to easily reference
$variables = 1..6 | foreach {
    New-Variable -Name UniqueName$_ -Value @{Number=$_;Date=Get-Date;Script="Write-Host $_ -foreground cyan"} -PassThru
}

# Use the variables
$variables | foreach {
    "This variable is named {0} and its number is {1}" -f $_.name,$_.value.number
}

# Use one like a normal variable
$UniqueName1

# Get the variables if not already captured
$variables = 1..6 | foreach {Get-Variable -Name UniqueName$_}

# Get all the values of the variables
1..6 | foreach {Get-Variable -Name UniqueName$_ -ValueOnly}

# Use the properties
$variables.value | foreach {& $([scriptblock]::create($_.script))}

# Remove the variables
$variables | Remove-Variable

# or 
1..6 | foreach {
    Remove-Variable -Name "UniqueName$_"
}

Hope it helps

Hi Doug, Thanks for replying

I need to access the dynamically generated variable name directly rather than through an assigned variable name as you’ve done ($variable),

This code let’s me do that, but how to I edit one of the properties, such as set “ThreadOptions = “ReuseThread””, or change the Runspace Name?

thanks

james

 

 #name of runspace set manually or obtained from code

$shortName = "activeUsers"

New-Variable -Name runspace$shortName -PassThru -Force -Value ([runspacefactory]::CreateRunspace())

(Get-Variable -Name runspace$shortName -ValueOnly) 

###########################
console output

Name Value

---- -----

runspaceactiveUsers System.Management.Automation.Runspaces.LocalRunspace

Events :

ThreadOptions : Default

JobManager :

Debugger :

RunspaceConfiguration : System.Management.Automation.Runspaces.RunspaceConfigForSingleShell

InitialSessionState :

Version : 5.1.18362.752

RunspaceStateInfo : BeforeOpen

RunspaceAvailability : None

ConnectionInfo :

OriginalConnectionInfo :

LanguageMode :

ApartmentState : Unknown

RunspaceIsRemote : False

InstanceId : 8a205646-e78d-4dc0-8318-f2e1691811ac

DisconnectedOn :

ExpiresOn :

Name : Runspace44

Id : 44

SessionStateProxy : System.Management.Automation.Runspaces.SessionStateProxy

 

Ahhh, I worked it out

 

#name of runspace set manually or obtained from code

$shortName = "activeUsers1"

$runspaceName = $shortName + "CPRunspace"

New-Variable -Name $runspaceName -PassThru -Force -Value ([runspacefactory]::CreateRunspace())

(Get-Variable -Name $runspaceName -ValueOnly).ThreadOptions = "ReuseThread"

(Get-Variable -Name $runspaceName -ValueOnly).Name = "$runspaceName"

(Get-Variable -Name $runspaceName -ValueOnly).open() 

I see your variable turned into a string,

my mistake. :slight_smile:

It seems the ideas have helped nonetheless.

Glad you got it working!

thanks mate, much appreciated