Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
April 25, 2024

More PowerShell Runspace Fun

In the last article, we began to explore how to use custom runspaces in our PowerShell scripting. Is still believe that using cmdlets like `Start-Job` and `Invoke-Command` are preferred. Let PowerShell do the work. But, there may be situations where advanced scripters want to have more granular control over the process. Last time, we looked at using runspaces sequentially. Like a background job, the results remain in the runspace, and you may want to keep things separate. You can also easily re-run the code in the runspace. Here's a simple script.

#MeasureFolder.ps1

Param([string]$Path = '.')

$stat = Get-ChildItem -Path $Path -Recurse -File | Measure-Object -Property Length -Sum -Average

[PSCustomObject]@{

    PSTypeName   = 'folderInfo'

    Path         = Convert-Path $Path

    Files        = $stat.Count

    Size         = $stat.Sum

    Average      = $stat.Average

    Computername = [System.Environment]::MachineName

    Date         = Get-Date

}
I can create a set of runspaces for multiple paths to test.
$paths = "c:\scripts","c:\work",$Home

$c = Get-Content .\MeasureFolder.ps1 -Raw

#create a collection to hold the runspaces

$run = [System.Collections.Generic.List[System.Management.Automation.PowerShell]]::new()

#create a collection to hold the results

$out = [System.Collections.Generic.List[PSObject]]::new()

foreach ($path in $paths) {

    $rs = [powershell]::create()

    [void]$rs.AddScript($c)

    [void]$rs.AddArgument($Path)

    $run.Add($rs)

    $out.Add($rs.Invoke())

}
The initial output is saved to `$out`.
PS C:\> $out | format-Table

Path          Files          Size   Average Computername Date

----          -----          ----   ------- ------------ ----

C:\scripts    10559  669527455.00  63408.23 PROSPERO     4/24/2024 4:09:59 PM

C:\work         619  270597236.00 437152.24 PROSPERO     4/24/2024 4:09:59 PM

C:\Users\Jeff 36602 4735498377.00 129378.13 PROSPERO     4/24/2024 4:10:01 PM
But, as long as I have the collection of runspaces, I can re-run code.
PS C:\> $run.invoke() | format-table

Path          Files          Size   Average Computername Date

----          -----          ----   ------- ------------ ----

C:\scripts    10559  669527455.00  63408.23 PROSPERO     4/24/2024 4:30:44 PM

C:\work         619  270597236.00 437152.24 PROSPERO     4/24/2024 4:30:44 PM

C:\Users\Jeff 36602 4735498377.00 129378.13 PROSPERO     4/24/2024 4:30:46 PM
There's no real performance benefit to this approach as each folder is processed sequentially. But, let's see what else we can do.
Get a premium subscription for full article and archive access

In the last article, we began to explore how to use custom runspaces in our PowerShell scripting. Is still believe that using cmdlets like Start-Job and Invoke-Command are preferred. Let PowerShell do the work. But, there may be situations where advanced scripters want to have more granular control over the process.

Last time, we looked at using runspaces sequentially. Like a background job, the results remain in the runspace, and you may want to keep things separate. You can also easily re-run the code in the runspace.

Here's a simple script.

Want to read the full issue?
GitHub Bluesky LinkedIn About Jeff
Powered by Buttondown, the easiest way to start and grow your newsletter.