Share FunctionInfo and execute it with $using when using `ForEach-Object -Parallel` causes session state corruption
See original GitHub issuePrerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest released version
- Search the existing issues.
- Refer to the FAQ.
- Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
This is reported by internal MSFT folks. Quote the emails content below:
Write-Host
sometimes undefined with ForEach-Object -Parallel
.
Due to networking issues, I can’t grab my actual code, but I wrote code along the lines of:
function f1
{
param([string]$i)
if (Test-Path $i) { return $i }
# do something
if ($i-eq "bad")
{
Write-Host "something is wrong!"
return $null
}
return $i
}
function get-inputs
{
return @("foo", "bar", "bad", "good")
}
function invoke-processInputs
{
$inputs = get-inputs
$f1Func = Get-Command -Name "f1"
$job = $inputs | ForEach-Object -AsJob -ThrottleLimit 2 -Parallel {
$output = & $using:f1Func $_
if ($output -eq $null)
{
# do something
}
}
#do some status reporting on the job...
while ($job.State -eq "Running") { write-host "running..." ; start-sleep 1 }
Wait-Job -Id $job.Id
Remove-Job -Id $job.Id
}
My actual input set has 100+ entries and some of them essentially trigger the bad case (through a bunch of network stuff). What’s super confusing is that I both see the actual output (the “something is wrong” in this example) as well as “The term ‘Write-Host’ is not recognized as the name of a cmdlet…” error too. I’ve also seen the Test-Path give the same error. Those both seem… wrong
I expect there’s something about the parallel foreach that I’m messing up, but I’m not sure what here.
Expected behavior
Write-Host should work fine
Actual behavior
Run into error:
The term 'Write-Host' is not recognized as the name of a cmdlet…
Error details
Not available
Environment data
This is all on pwsh 7.2 (GA, nothing internal)
Name Value
---- -----
PSVersion 7.2.0
PSEdition Core
GitCommitId 7.2.0
OS Microsoft Windows 10.0.19043
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Visuals
N/A
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (4 by maintainers)
Top Results From Across the Web
How to pass a custom function inside a ForEach-Object
$funcDef variable and trying to redefine the function with ${function:Get-Custom} = ${using:function:Get-Custom} fails, because ${function:Get- ...
Read more >PowerShell ForEach-Object Parallel Feature
The new ForEach-Object -Parallel parameter set uses existing PowerShell APIs for running script blocks in parallel. These APIs have been around ...
Read more >LispWorks® User Guide and Reference Manual
The user guide section of this manual describes the main language-level features and tools available in LispWorks, and how to use them.
Read more >ForEach-Object -Parallel (Parallelism in PowerShell) - YouTube
I will show you where - Parallel is good idea to use and also where it would be a bad idea and cause...
Read more >Programming in Lua, Fourth Edition
We can use the -i option to instruct Lua to start an interactive session after running a given chunk: % lua -i prog....
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I fear that if that’s done automatically it will lead to a lot of confusion about why the function can’t access the state it previously could. While the error isn’t great UX, it happens at design time and is instantly clear what is wrong. Plus the work around makes it a lot easier to understand that it won’t work exactly the same.
If it is an unambiguous match we could do it automatically. Simply banning these constructs is bad UX. It would be much easier for users to use intuitive explicit constructs and the Engine would convert this into the correct implementation.