2023-10-19 16:57:15 -04:00
2023-10-19 16:54:29 -04:00
2023-10-19 16:53:12 -04:00
2023-10-19 16:53:31 -04:00
2023-10-19 16:57:15 -04:00

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.
S
Description
Enables the ability to leverage multithreading within powershell whilst reducing the complexity to get started.
Readme GPL-2.0 85 KiB
Languages
PowerShell 100%