mirror of
https://github.com/freedbygrace/Invoke-PSThread.git
synced 2026-07-26 11:28:14 +00:00
247 lines
13 KiB
Markdown
247 lines
13 KiB
Markdown
# Invoke-PSThread
|
|
.SYNOPSIS
|
|
Enables the ability to leverage multithreading within powershell whilst reducing the complexity to get started.
|
|
|
|
.DESCRIPTION
|
|
This function aims to remove the enormous complexity out of multithreading within powershell. See the fully working examples below.
|
|
|
|
.PARAMETER Runspace
|
|
Your parameter description
|
|
|
|
.PARAMETER RunspacePool
|
|
Your parameter description
|
|
|
|
.PARAMETER Await
|
|
Your parameter description
|
|
|
|
.PARAMETER RunspaceDefinition
|
|
Your parameter description
|
|
|
|
.PARAMETER RunspaceParameters
|
|
Your parameter description
|
|
|
|
.PARAMETER InputObjectList
|
|
Your parameter description
|
|
|
|
.PARAMETER SynchronizedHashtable
|
|
Your parameter description
|
|
|
|
.PARAMETER AssemblyList
|
|
Your parameter description
|
|
|
|
.PARAMETER FunctionList
|
|
Your parameter description
|
|
|
|
.PARAMETER ModuleList
|
|
Your parameter description
|
|
|
|
.PARAMETER VariableList
|
|
Your parameter description
|
|
|
|
.PARAMETER ThreadList
|
|
Your parameter description
|
|
|
|
.PARAMETER LoopTimeout
|
|
Your parameter description
|
|
|
|
.PARAMETER LoopDuration
|
|
Your parameter description
|
|
|
|
.PARAMETER WaitForAvailableRunspace
|
|
Your parameter description
|
|
|
|
.PARAMETER ContinueOnError
|
|
Your parameter description
|
|
|
|
.EXAMPLE
|
|
Create a runspace
|
|
|
|
[ScriptBlock]$RunspaceDefinition = {
|
|
Param
|
|
(
|
|
$SynchronizedHashtable,
|
|
$Title,
|
|
$Message
|
|
)
|
|
|
|
$Null = Add-Type -AssemblyName 'System.Windows.Forms'
|
|
$Null = Add-Type -AssemblyName 'System.Drawing'
|
|
|
|
$Form = New-Object -TypeName 'System.Windows.Forms.Form'
|
|
$Form.Size = New-Object -TypeName 'System.Drawing.Size' -ArgumentList @(300,150)
|
|
|
|
$TextBox = New-Object -TypeName 'System.Windows.Forms.RichTextBox'
|
|
$TextBox.Location = New-Object -TypeName 'System.Drawing.Point' -ArgumentList @(110,50)
|
|
$TextBox.BorderStyle = 0
|
|
$TextBox.BackColor = $Form.BackColor
|
|
|
|
$TextBox.Text = $Message
|
|
|
|
$Null = $Form.Controls.Add($TextBox)
|
|
|
|
$Null = $Form.ShowDialog()
|
|
}
|
|
|
|
$SynchronizedHashtable = [System.Collections.Hashtable]::Synchronized(@{})
|
|
$SynchronizedHashtable.ThreadIDList = New-Object -TypeName 'System.Collections.Generic.List[System.String]'
|
|
|
|
$InvokePSThreadParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$InvokePSThreadParameters.Runspace = $True
|
|
$InvokePSThreadParameters.RunspaceDefinition = $RunspaceDefinition
|
|
$InvokePSThreadParameters.RunspaceParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$InvokePSThreadParameters.RunspaceParameters.Title = "This is my UI title"
|
|
$InvokePSThreadParameters.RunspaceParameters.Message = "This is my UI message.`r`nThis is the second line of my UI message.`r`nThis is the third line of my UI message."
|
|
$InvokePSThreadParameters.SynchronizedHashtable = Get-Variable -Name 'SynchronizedHashtable' -ErrorAction SilentlyContinue
|
|
$InvokePSThreadParameters.FunctionList = Get-ChildItem -Path 'Function:' | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.ModuleList = Get-Module | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.VariableList = Get-Variable | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.ContinueOnError = $False
|
|
$InvokePSThreadParameters.Verbose = $True
|
|
|
|
$InvokePSThreadResult = Invoke-PSThread @InvokePSThreadParameters
|
|
|
|
Write-Output -InputObject ($InvokePSThreadResult)
|
|
|
|
.EXAMPLE
|
|
Create a runspace pool, submit all jobs to the pool, and the pool will manage their execution.
|
|
|
|
[ScriptBlock]$RunspaceDefinition = {
|
|
Param
|
|
(
|
|
$InputObjectListItem,
|
|
$SynchronizedHashtable,
|
|
$AdditionalParameter1,
|
|
$AdditionalParameter2
|
|
)
|
|
|
|
#Set thread priority
|
|
[System.Threading.Thread]::CurrentThread.Priority = [System.Threading.ThreadPriority]::Lowest
|
|
|
|
$ThreadInfo = [System.Threading.Thread]::CurrentThread
|
|
|
|
$ThreadID = [System.AppDomain]::GetCurrentThreadId()
|
|
|
|
$SynchronizedHashtable.ThreadIDList.Add($ThreadID)
|
|
|
|
Write-Verbose -Message "Attempting to begin thread ID `"$($ThreadID)`". Please Wait..." -Verbose
|
|
|
|
$SynchronizedHashtable.Add("Thread$($ThreadID)", (Get-Date))
|
|
|
|
Write-Output -InputObject ($InputObjectListItem)
|
|
|
|
Write-Output -InputObject ($AdditionalParameter1)
|
|
|
|
Write-Output -InputObject ($AdditionalParameter2)
|
|
|
|
$Null = Start-Sleep -Seconds (Get-Random -Minimum 10 -Maximum 25)
|
|
}
|
|
|
|
$SynchronizedHashtable = [System.Collections.Hashtable]::Synchronized(@{})
|
|
$SynchronizedHashtable.ThreadIDList = New-Object -TypeName 'System.Collections.Generic.List[System.String]'
|
|
|
|
$InvokePSThreadParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$InvokePSThreadParameters.RunspacePool = $True
|
|
$InvokePSThreadParameters.InputObjectList = 1..15
|
|
$InvokePSThreadParameters.RunspaceDefinition = $RunspaceDefinition
|
|
$InvokePSThreadParameters.RunspaceParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$InvokePSThreadParameters.RunspaceParameters.AdditionalParameter1 = Get-Random -Minimum 0 -Maximum 10000
|
|
$InvokePSThreadParameters.RunspaceParameters.AdditionalParameter2 = Get-Random -Minimum 0 -Maximum 10000
|
|
$InvokePSThreadParameters.SynchronizedHashtable = Get-Variable -Name 'SynchronizedHashtable' -ErrorAction SilentlyContinue
|
|
$InvokePSThreadParameters.FunctionList = Get-ChildItem -Path 'Function:' | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.ModuleList = Get-Module | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.VariableList = Get-Variable | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.ContinueOnError = $False
|
|
$InvokePSThreadParameters.Verbose = $True
|
|
|
|
$InvokePSThreadResult = Invoke-PSThread @InvokePSThreadParameters
|
|
|
|
Write-Output -InputObject ($InvokePSThreadResult)
|
|
|
|
.EXAMPLE
|
|
Create a runspace pool, submit all jobs to the pool, and the pool will manage their execution. The function will be executed a second time to wait until all jobs have been completed, return their output, and cleanup.
|
|
|
|
[ScriptBlock]$RunspaceDefinition = {
|
|
Param
|
|
(
|
|
$InputObjectListItem,
|
|
$SynchronizedHashtable,
|
|
$AdditionalParameter1,
|
|
$AdditionalParameter2
|
|
)
|
|
|
|
#Set thread priority
|
|
[System.Threading.Thread]::CurrentThread.Priority = [System.Threading.ThreadPriority]::Lowest
|
|
|
|
$ThreadInfo = [System.Threading.Thread]::CurrentThread
|
|
|
|
$ThreadID = [System.AppDomain]::GetCurrentThreadId()
|
|
|
|
$SynchronizedHashtable.ThreadIDList.Add($ThreadID)
|
|
|
|
Write-Verbose -Message "Attempting to begin thread ID `"$($ThreadID)`". Please Wait..." -Verbose
|
|
|
|
$SynchronizedHashtable.Add("Thread$($ThreadID)", (Get-Date))
|
|
|
|
Write-Output -InputObject ($InputObjectListItem)
|
|
|
|
Write-Output -InputObject ($AdditionalParameter1)
|
|
|
|
Write-Output -InputObject ($AdditionalParameter2)
|
|
|
|
$Null = Start-Sleep -Seconds (Get-Random -Minimum 10 -Maximum 25)
|
|
}
|
|
|
|
$SynchronizedHashtable = [System.Collections.Hashtable]::Synchronized(@{})
|
|
$SynchronizedHashtable.ThreadIDList = New-Object -TypeName 'System.Collections.Generic.List[System.String]'
|
|
|
|
$InvokePSThreadParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$InvokePSThreadParameters.RunspacePool = $True
|
|
$InvokePSThreadParameters.InputObjectList = Get-Process | Get-Random -Count 15
|
|
$InvokePSThreadParameters.RunspaceDefinition = $RunspaceDefinition
|
|
$InvokePSThreadParameters.RunspaceParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$InvokePSThreadParameters.RunspaceParameters.AdditionalParameter1 = Get-Random -Minimum 0 -Maximum 10000
|
|
$InvokePSThreadParameters.RunspaceParameters.AdditionalParameter2 = Get-Random -Minimum 0 -Maximum 10000
|
|
$InvokePSThreadParameters.SynchronizedHashtable = Get-Variable -Name 'SynchronizedHashtable' -ErrorAction SilentlyContinue
|
|
$InvokePSThreadParameters.FunctionList = Get-ChildItem -Path 'Function:' | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.ModuleList = Get-Module | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.VariableList = Get-Variable | Where-Object {($_.Name -iin @('Test'))}
|
|
$InvokePSThreadParameters.ContinueOnError = $False
|
|
$InvokePSThreadParameters.Verbose = $True
|
|
|
|
$InvokePSThreadResult = Invoke-PSThread @InvokePSThreadParameters
|
|
|
|
#Do some additional code here
|
|
|
|
$InvokePSThreadParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$InvokePSThreadParameters.Await = $True
|
|
$InvokePSThreadParameters.ThreadList = $InvokePSThreadResult
|
|
$InvokePSThreadParameters.LoopTimeout = [System.TimeSpan]::FromHours(1)
|
|
$InvokePSThreadParameters.LoopDuration = [System.TimeSpan]::FromMilliseconds(15000)
|
|
$InvokePSThreadParameters.ContinueOnError = $False
|
|
$InvokePSThreadParameters.Verbose = $True
|
|
|
|
$ThreadAwaitResult = Invoke-PSThread @InvokePSThreadParameters
|
|
|
|
Write-Output -InputObject ($ThreadAwaitResult)
|
|
|
|
.NOTES
|
|
Any useful tidbits
|
|
|
|
.LINK
|
|
https://davewyatt.wordpress.com/2014/04/29/more-potential-use-cases-for-thread-safe-variable-access-in-powershell-events/
|
|
|
|
.LINK
|
|
https://davewyatt.wordpress.com/2014/04/29/more-potential-use-cases-for-thread-safe-variable-access-in-powershell-events/
|
|
|
|
.LINK
|
|
https://www.codeproject.com/Tips/895840/Multi-Threaded-PowerShell-Cookbook
|
|
|
|
.LINK
|
|
https://www.linkedin.com/pulse/multithreading-powershell-scripts-alexey/
|
|
|
|
.LINK
|
|
https://xkln.net/blog/multithreading-in-powershell--running-a-specific-number-of-threads/
|
|
|
|
.LINK
|
|
https://markw.dev/#:~:text=There%20are%20two%20ways%20we,other%20is%20by%20using%20splatting.&text=The%20important%20part%20here%20is,plural)%20instead%20of%20AddParameter()%20.
|