Archives / 2008 / April
  • PowerShell: Threading Enhancements FTW!

    To build on the threading library I mentioned here, I've added some functionality to make it easier to communicate with the seperate thread. Still, keep in mind that PowerShell will only allow one pipeline to be executing in a runspace at any given time. So, these new functions can only be used while the thread is inactive. But, they provide power into setting up the thread to be run and communicating with the original runspace.

    The new functions are as follows:

    Get-ThreadVariable - Accesses available variables from within the thread.
    Set-ThreadVariable - Sets a variable for use within the thread.
    Invoke-ThreadExpression - Allows synchronous execution of a script block within the thread.

    I also updated the Join-Thread function to include an optional -timeout parameter so that you could return control back if the thread didn't complete in the desired time. I also updated the Running property to IsRunning and changed it so that it will only return true while the asynchronous invoke command is executing.

    With this new example you can do even more now, as shown here.

    $thread = New-Thread
    Invoke-ThreadExpression $thread { function foo($bar) { echo "$bar!" } }
    Set-ThreadVariable $thread "name" "PowerShell Rocks"
    Start-Thread -thread $thread { $value = foo $name } | Out-Null
    Join-Thread $thread
    Get-ThreadVariable $thread "value"

    This should return "PowerShell Rocks!" when Get-ThreadVariable is called. I've already used this script to multi-thread our Exchange backup from a single script. It is working quite nicely (nice as in have cut our 8 hour backup down to 4 hours) and I can already imagine several other wonderful places it will be used.


  • PowerShell: Threading for PowerShell v1.0

    Ok, so this solution really isn't threading, but a neat way to get async scripts to run! The important thing to remember is that each "thread" is actually a PowerShell "runspace". Meaning, scripts run within the thread don't have access to objects or functions defined outside the thread. The script is composed of the following commands:

    New-Thread: Creates a new instance of a thread
    Start-Thread: Invokes an async execution of a script block
    Stop-Thread: Stops a thread from running if it is still executing
    Read-Thread: Reads all errors and output to the current runspace
    Join-Thread: Waits for the thread to complete and reads off the errors and output to the current runspace

    A simple example of how to use this is as follows.

    $thread = Start-Thread {
        foreach ($i in (1..5)) {
            echo "Sleeping for $i seconds..."
            Start-Sleep $i
    # ... do some work here or spawn other threads
    Join-Thread $thread

    I have some other ideas around injecting "variables" and being able to run script blocks within the new "thread" but I'll save that for a later post ...