-1

I have this module that I import on the local system. When I run a script block using runspace on the local system as well , the function in that module are accessible in the runspace script block.

This module creates global variables. I tested if these global variables are also accessible from the script block running in run space. They all get returned by get-variable -scope global -name But then when I try to access these global from the script block , only some come through.

I could deal with this if all would not show up , or they all would show up. But that they all show up as being present , but then only some come threw as having content.

The goal is to have this module work in both contexts , local system and local system running in runspace.

Steven
  • 6,817
  • 1
  • 14
  • 14
deetle
  • 197
  • 8

1 Answers1

1

In short, everything you want to see in your runspace should be passed into it.

If your values are ValueType, you should pass them by reference explicitly. Otherwise, you should pass them as-is (by reference is default for reverence types).

Here is my templete for parallel processing of finite list of items using PoshRSJob module and custom SomeFunction:

Function SomeFunction
{
    Param(
       [String]$SampleParam
    )
    return $SampleParam.ToUpper()
}

$JobScript = [scriptblock]{
    $inQueue = [System.Collections.Concurrent.ConcurrentQueue[string]]$args[0]
    $outBag = [System.Collections.Concurrent.ConcurrentBag[string]]$args[1]
    $currentItem = $null
    while($inQueue.TryDequeue([ref] $currentItem) -eq $true)
    {
        try
        {
            # Add result to OutBag
            $result = SomeFunction -SampleParam $currentItem -EA Stop
            $outBag.Add( $result )
        }
        catch
        {
            # Catch error
            Write-Output $_.Exception.ToString()
        }
    }
}

$inData = [System.Collections.Concurrent.ConcurrentQueue[string]]::new(
    [String[]](@(1..10000) | % { return [guid]::NewGuid().ToString() }) # Sample strings in lower case
    )

$resultData = [System.Collections.Concurrent.ConcurrentBag[string]]::new()

# Wait for queue to empty
$i_cur = $inData.Count
$i_max = $i_cur

# Start jobs
$jobs = @(1..20) | % { Start-RSJob -ScriptBlock $JobScript -ArgumentList @($inData, $resultData) -FunctionsToImport @('SomeFunction') }

# Wait queue to empty
while($i_cur -gt 0)
{
    Write-Progress -Activity 'Doing job' -Status "$($i_cur) left of $($i_max)" -PercentComplete (100 - ($i_cur / $i_max * 100)) 
    Start-Sleep -Seconds 3 # Update frequency
    $i_cur = $inData.Count
}

# Wait jobs to complete
$logs = $jobs | % { Wait-RSJob -Job $_ } | % { Receive-RSJob -Job $_  } 
$jobs | % { Remove-RSJob -Job $_ }
$Global:resultData = $resultData
$Global:logs = $logs
filimonic
  • 3,988
  • 2
  • 19
  • 26
  • By why do the variables already show up ? all the 5 global variables from my module will show up when get-variable -scope 'global' -name ' – deetle Jun 01 '21 at 21:41
  • I think it's not. `$Global:AAR='YAY!'; Get-Variable -Scope 'Global' | % { "$($_.Name)=$($_.Value)" } | Sort-Object -Property Name | ConvertTo-Json -Depth 20 | Out-File -FilePath 'S:\OutVarsOutsideJob.json.txt' -Confirm:$false -Force; Start-Job -Name TestSync -ScriptBlock { Get-Variable -Scope 'Global' | % { "$($_.Name)=$($_.Value)" } | Sort-Object -Property Name | ConvertTo-Json -Depth 20 | Out-File -FilePath 'S:\OutVarsInsideJob.json.txt' -Confirm:$false -Force } | Out-Null; Get-Job -Name TestSync | Wait-Job | Remove-Job – filimonic Jun 01 '21 at 22:00