You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Merge pull request #49 from santisq/48-ability-to-import-modules-during-startup-of-powershell-runspace
Adds `-ModuleNames` and `-ModulePaths` parameters to `Invoke-Parallel`:
- Introduce `-ModuleNames` to import system-installed modules via `$env:PSModulePath`.
- Add `-ModulePaths` to load custom modules from specified directories.
- Updates README and docs with examples and usage notes.
- Simplify module integration, removing need for manual `Import-Module` in script blocks.
- Add Pester tests for new parameters.
Copy file name to clipboardExpand all lines: README.md
+20-5Lines changed: 20 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@
10
10
11
11
</div>
12
12
13
-
`PSParallelPipeline` is a PowerShell module featuring the `Invoke-Parallel` cmdlet, designed to process pipeline input objects in parallel using multithreading. It mirrors the capabilities of [`ForEach-Object -Parallel`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object) from PowerShell 7.0+, bringing this functionality to Windows PowerShell 5.1, surpassing the constraints of [`Start-ThreadJob`](https://learn.microsoft.com/en-us/powershell/module/threadjob/start-threadjob?view=powershell-7.4).
13
+
`PSParallelPipeline` is a PowerShell module featuring the `Invoke-Parallel` cmdlet, designed to process pipeline input objects in parallel using multithreading. It mirrors the capabilities of [`ForEach-Object -Parallel`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object) from PowerShell 7.0+, bringing this functionality to Windows PowerShell 5.1, surpassing the constraints of [`Start-ThreadJob`](https://learn.microsoft.com/en-us/powershell/module/threadjob/start-threadjob).
14
14
15
15
# Why Use This Module?
16
16
@@ -33,7 +33,7 @@ Measure-Command {
33
33
34
34
## Common Parameters Support
35
35
36
-
Unlike `ForEach-Object -Parallel` (up to v7.5), `Invoke-Parallel` supports [Common Parameters](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.4), enhancing control and debugging.
36
+
Unlike `ForEach-Object -Parallel` (up to v7.5), `Invoke-Parallel` supports [Common Parameters](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters), enhancing control and debugging.
37
37
38
38
```powershell
39
39
# Stops on first error
@@ -60,7 +60,7 @@ Get a single, friendly timeout message instead of multiple errors:
60
60
# Invoke-Parallel: Timeout has been reached.
61
61
```
62
62
63
-
## [`$using:`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7.4#the-using-scope-modifier) Scope Support
63
+
## [`$using:`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes#the-using-scope-modifier) Scope Support
64
64
65
65
Easily pass variables into parallel scopes with the `$using:` modifier, just like `ForEach-Object -Parallel`:
66
66
@@ -70,7 +70,7 @@ $message = 'world!'
70
70
# hello world!
71
71
```
72
72
73
-
## `-Variables`and `-Functions` Parameters
73
+
## `-Variables`, `-Functions`, `-ModuleNames`, and `-ModulePaths` Parameters
74
74
75
75
-[`-Variables` Parameter](./docs/en-US/Invoke-Parallel.md#-variables): Pass variables directly to parallel runspaces.
76
76
@@ -87,7 +87,22 @@ $message = 'world!'
87
87
# hello world!
88
88
```
89
89
90
-
Both parameters are quality-of-life enhancements, especially `-Functions`, which adds locally defined functions to the runspaces’ [Initial Session State](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.initialsessionstate)—a feature absent in `ForEach-Object -Parallel`. This is a far better option than passing function definitions into the parallel scope.
90
+
- [`-ModuleNames` Parameter](./docs/en-US/Invoke-Parallel.md#-modulenames): Import system-installed modules into parallel runspaces by name, using modules discoverable via `$env:PSModulePath`.
These parameters are a quality-of-life enhancement, especially `-Functions`, which incorporates locally defined functions to the runspaces’ [Initial Session State](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.initialsessionstate)—a feature absent in `ForEach-Object -Parallel` and a far better option than passing function definitions into the parallel scope. The new `-ModuleNames` and `-ModulePaths` parameters simplify module integration by automatically loading system-installed and custom modules, respectively, eliminating the need for manual `Import-Module` calls within the script block.
@@ -15,19 +15,24 @@ Executes parallel processing of pipeline input objects using multithreading.
15
15
16
16
```powershell
17
17
Invoke-Parallel
18
-
-InputObject <Object>
19
18
[-ScriptBlock] <ScriptBlock>
19
+
[-InputObject <Object>]
20
20
[-ThrottleLimit <Int32>]
21
+
[-TimeoutSeconds <Int32>]
21
22
[-Variables <Hashtable>]
22
23
[-Functions <String[]>]
24
+
[-ModuleNames <String[]>]
25
+
[-ModulePaths <String[]>]
23
26
[-UseNewRunspace]
24
-
[-TimeoutSeconds <Int32>]
25
27
[<CommonParameters>]
26
28
```
27
29
28
30
## DESCRIPTION
29
31
30
-
The `Invoke-Parallel` cmdlet enables parallel processing of input objects in PowerShell, including __Windows PowerShell 5.1__, offering functionality similar to `ForEach-Object -Parallel` introduced in PowerShell 7.0. It processes pipeline input across multiple threads, improving performance for tasks that benefit from parallel execution.
32
+
The `Invoke-Parallel` cmdlet enables parallel processing of input objects in PowerShell, including
33
+
__Windows PowerShell 5.1__ and PowerShell 7+, offering functionality similar to `ForEach-Object -Parallel` introduced in
34
+
PowerShell 7.0. It processes pipeline input across multiple threads, improving performance for tasks that benefit from
35
+
parallel execution.
31
36
32
37
## EXAMPLES
33
38
@@ -42,7 +47,10 @@ $message = 'Hello world from '
42
47
}
43
48
```
44
49
45
-
This example demonstrates parallel execution of a script block with a 3-second delay, appending a unique runspace ID to a message. The [`$using:` scope modifier](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7.4#the-using-scope-modifier) is used to pass the local variable `$message` into the parallel scope, a supported method for accessing external variables in `Invoke-Parallel`.
50
+
This example demonstrates parallel execution of a script block with a 3-second delay, appending a unique runspace ID to
51
+
a message. The [`$using:` scope modifier](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes#the-using-scope-modifier)
52
+
is used to pass the local variable `$message` into the parallel scope, a supported method for accessing external
53
+
variables in `Invoke-Parallel`.
46
54
47
55
### Example 2: Demonstrates `-Variables` Parameter
48
56
@@ -55,7 +63,9 @@ $message = 'Hello world from '
55
63
} -Variables @{ message = $message }
56
64
```
57
65
58
-
This example demonstrates the [`-Variables` parameter](#-variables), which passes the local variable `$message` into the parallel scope using a hashtable. The key `message` in the hashtable defines the variable name available within the script block, serving as an alternative to the `$using:` scope modifier.
66
+
This example demonstrates the [`-Variables` parameter](#-variables), which passes the local variable `$message` into
67
+
the parallel scope using a hashtable. The key `message` in the hashtable defines the variable name available within the
68
+
script block, serving as an alternative to the `$using:` scope modifier.
59
69
60
70
### Example 3: Adding to a thread-safe collection with `$using:`
This example imports a local function `Greet` into the parallel scope using [`-Functions` parameter](#-functions), allowing its use within the script block.
99
+
This example imports a local function `Greet` into the parallel scope using [`-Functions` parameter](#-functions),
100
+
allowing its use within the script block.
89
101
90
102
### Example 6: Setting a timeout with `-TimeoutSeconds`
This example imports a custom module from the specified directory using `-ModulePaths`, allowing the `Get-CustomCmdlet`
153
+
function to be used in the parallel script block.
154
+
155
+
> [!NOTE]
156
+
>
157
+
> The path must point to a directory containing a valid PowerShell module.
121
158
122
159
## PARAMETERS
123
160
124
161
### -Functions
125
162
126
-
Specifies an array of function names from the local session to include in the runspaces' [Initial Session State](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.initialsessionstate). This enables their use within the parallel script block.
163
+
Specifies an array of function names from the local session to include in the runspaces’
This enables their use within the parallel script block.
127
166
128
167
> [!TIP]
129
168
>
130
-
> This parameter is the recommended way to make local functions available in the parallel scope. Alternatively, you can retrieve the function definition as a string (e.g., `$def = ${function:Greet}.ToString()`) and use `$using:` to pass it into the script block, defining it there (e.g., `${function:Greet} = $using:def`).
169
+
> This parameter is the recommended way to make local functions available in the parallel scope.
170
+
Alternatively, you can retrieve the function definition as a string (e.g., `$def = ${function:Greet}.ToString()`) and
171
+
use `$using:` to pass it into the script block, defining it there (e.g., `${function:Greet} = $using:def`).
Sets the maximum number of script blocks executed in parallel across multiple threads. Additional input objects wait until the number of running script blocks falls below this limit.
179
-
180
-
> [!NOTE]
181
-
>
182
-
> The default value is `5`.
219
+
Sets the maximum number of script blocks executed in parallel across multiple threads. Additional input objects wait
220
+
until the number of running script blocks falls below this limit. The default value is `5`.
Specifies the maximum time (in seconds) to process all input objects. When the timeout is reached, running script blocks are terminated, and remaining input is discarded.
236
+
Specifies the maximum time (in seconds) to process all input objects. When the timeout is reached, running script blocks
Provides a hashtable of variables to make available in the parallel scope. Keys define the variable names within the script block.
273
+
Provides a hashtable of variables to make available in the parallel scope. Keys define the variable names within the
274
+
script block.
235
275
236
276
> [!TIP]
237
277
>
238
-
> Use this parameter as an alternative to the [`$using:` scope modifier](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7.4#scope-modifiers).
This allows the script block to use cmdlets and functions from the specified modules.
298
+
299
+
> [!TIP]
300
+
>
301
+
> Use this parameter to ensure required modules are available in the parallel scope. Module names must be discoverable
302
+
via the [`$env:PSModulePath`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_psmodulepath)
303
+
environment variable, which lists installed module locations.
304
+
305
+
```yaml
306
+
Type: String[]
307
+
Parameter Sets: (All)
308
+
Aliases: mn
309
+
310
+
Required: False
311
+
Position: Named
312
+
Default value: None
313
+
Accept pipeline input: False
314
+
Accept wildcard characters: False
315
+
```
316
+
317
+
### -ModulePaths
318
+
319
+
Specifies an array of file paths to directories containing PowerShell modules (e.g., `.psm1` or `.psd1` files) to import
320
+
into the runspaces’ [Initial Session State](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.initialsessionstate).
321
+
This enables the script block to use cmdlets and functions from custom or local modules.
322
+
323
+
> [!NOTE]
324
+
>
325
+
> Paths must be absolute or relative to the current working directory and must point to valid directories containing
326
+
PowerShell modules. If an invalid path (e.g., a file or non-existent directory) is provided, a terminating error is
327
+
thrown.
328
+
329
+
```yaml
330
+
Type: String[]
331
+
Parameter Sets: (All)
332
+
Aliases: mp
333
+
334
+
Required: False
335
+
Position: Named
336
+
Default value: None
337
+
Accept pipeline input: False
338
+
Accept wildcard characters: False
339
+
```
340
+
252
341
### CommonParameters
253
342
254
343
This cmdlet supports the common parameters. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
@@ -268,14 +357,19 @@ Returns objects produced by the script block.
268
357
## NOTES
269
358
270
359
- `Invoke-Parallel`uses multithreading, which may introduce overhead. For small datasets, sequential processing might be faster.
271
-
- Ensure variables or collections passed to the parallel scope are thread-safe (e.g., `[System.Collections.Concurrent.ConcurrentDictionary]`), as shown in Examples 3 and 4.
272
-
- By default, runspaces are reused from a pool to optimize resource usage. Using `-UseNewRunspace` increases memory and startup time but ensures isolation.
360
+
- Ensure variables or collections passed to the parallel scope are thread-safe (e.g., use
361
+
[`ConcurrentDictionary<TKey, TValue>`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2) or similar), as shown in
362
+
[__Example #3__](#example-3-adding-to-a-thread-safe-collection-with-using) and
0 commit comments