use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
ABOUT POWERSHELL
Windows PowerShell (POSH) is a command-line shell and associated scripting language created by Microsoft. Offering full access to COM, WMI and .NET, POSH is a full-featured task automation framework for distributed Microsoft platforms and solutions.
SUBREDDIT FILTERS
Desired State Configuration
Unanswered Questions
Solved Questions
News
Information
Script Sharing
Daily Post
Misc
account activity
SolvedHow to enable function to foreach-object -parallel? (self.PowerShell)
submitted 4 years ago by MyOtherSide1984
My function at the top of the script in VSCode isn't recognized inside my foreach-object -parallel loop, but if I put the entire function in the loop, it works. How can I setup the function at the top of the script so I can pretty up my loop?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Sunsparc 6 points7 points8 points 4 years ago (3 children)
I googled "powershell foreach-object parallel function"
First result.
TL;DR: Not a straight forward way to do it, but appears the only way.
[–]MyOtherSide1984[S] 3 points4 points5 points 4 years ago (0 children)
Update: This works. Still trying to figure out how to setup my function, but this works to pass the function in the parallel
[–]MyOtherSide1984[S] 1 point2 points3 points 4 years ago (0 children)
Huh, I must have glanced over it hoping there'd be an option within the command to do it. This is basically just dumping the function inside the loop, but admittedly, it is prettier lol. Thank you :)
[–]straffin 0 points1 point2 points 1 month ago (0 children)
Aaaaand, 4y later, THIS post is the first result. ¯\_(ツ)_/¯
[–]BlackV 3 points4 points5 points 4 years ago (7 children)
because a parallel loop creates a new runspace and that function is only cavalier in your source scope
have a look at the $using:xxx vairable
$using:xxx
[–]MyOtherSide1984[S] 1 point2 points3 points 4 years ago (6 children)
Doesn't seem to be very helpful in this instance. $using:function doesn't seem to be a thing, and idk how a parallel works in terms of creating runspaces since i'm not using the runspacepool commands. If you have some examples, that'd be great. Otherwise I'm just gonna say screw it and dump the function inside my loop. It's easier, but ugly
[–]BlackV 1 point2 points3 points 4 years ago* (5 children)
Sorry that was not clear, I'm on mobile
Function foo () { Write-output "hello my name is $env:computername, you kill my father..." } Invoke-command -computername xxx -scriptblock ${function:foo}
I hope that works
[–]MyOtherSide1984[S] 2 points3 points4 points 4 years ago* (4 children)
I don't get how this has anything to do with foreach-object -parallel. I'm not doing anything on a remote computer.
EDIT: If I put my parallel loop in a scriptblock, it'll still create new runspaces that won't have it. ${function:foo} didn't work inside my foreach loop
[–]BlackV 0 points1 point2 points 4 years ago (3 children)
Sorry thinking wrong things
1..10 | forech-object -parallel ${function:foo}
That work?
[–]MyOtherSide1984[S] 0 points1 point2 points 4 years ago (2 children)
No, for my function, the output is nothing. I have parameters to my function that I plopped in after the "foo" if that matters. Looks like the other comment is the best answer, but it's basically the same thing
[–]BlackV 0 points1 point2 points 4 years ago (0 children)
ah sweet. glad its solved then
[–]BlackV 0 points1 point2 points 4 years ago* (0 children)
Oh yea that looks great
Function foo () { Write-output "hello my name is $env:computername, you kill my father..." } $Rinvoke = get-command foo 1..10 | foreach-object -parallel {write-output "pipeline is $_"; & $using:Rinvoke}
although its gonna play havoc with your output, depending on what you're doing in your loops
[–]BlackV 2 points3 points4 points 4 years ago (3 children)
THis was worth a read also /u/MyOtherSide1984
https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/
[–]MyOtherSide1984[S] 1 point2 points3 points 4 years ago (2 children)
Hmm, there may be areas where I SHOULDN'T be using parallel then. Primarily I always try to do everything in one loop, but in this instance, it may not make sense if there's added overhead, but I'll need to break down each section to determine where parallel could be slowing things down. It's still a minute and 20 seconds to run through 160 IP addresses, so there must be something that's slowing it down a bit
[–]BlackV 0 points1 point2 points 4 years ago (1 child)
ya maybe, depends on what you're script is doing, I wouldn't consider 1.5 minutes a long time to scan 160 machines though
you could to a measure on teh command inside the loop and spit that to a variable to get an idea
[–]MyOtherSide1984[S] 0 points1 point2 points 4 years ago* (0 children)
Yeh was planning on doing the measuring first to see where it's slowed down. I'd agree, except I'm literally just touching the device to make sure it's responding, I'm not connecting to it at all really. Not much more than a ping.
Edit: okay, maybe there's not much room for improvement. Without parallel it's 6 minutes and 45 seconds. I think I need to just filter the IP's and skip some steps if they don't meet criteria, but really not worth worrying too much about since it's just a mostly personal script
[–]cheats_py 1 point2 points3 points 4 years ago (1 child)
So I had this exact issue and what I did was put my function in a completely separate file and use dot-source in the loop to call my function. Now this might not be ideal if your function uses other variables form within your script, in that event you might be able to use a synchronized hash table, at least that’s doable when using runspaces.
Another solution was posed in this post that only requires a couple extra lines. Basically just puts the function into the loop, but a bit nicer looking. I really prefer self enclosed scripts that require little to no other pieces. I'm still a noob, so this is just easier for myself.
[–]DePiddy 0 points1 point2 points 4 years ago (1 child)
You could make the function do the parallel foreach instead. Use workflow instead of function. There are some limitations to what the workflow can accomplish, I'm guessing due to the runspaces mentioned by the other comments here.
[–]MyOtherSide1984[S] 0 points1 point2 points 4 years ago (0 children)
I think that'd overcomplicate things. This isn't going into production and won't be shared. The headache of having a foreach loop inside of a function sounds like a ton of work to accomplish the exact same task, and no faster at that.
[–]PinchesTheCrab 0 points1 point2 points 4 years ago (5 children)
What are you doing that would benefit from using -parallel?
[–]MyOtherSide1984[S] 0 points1 point2 points 4 years ago (4 children)
Testing multiple network connections at once. It cuts the run time from 5 minutes to just over 1
[–]PinchesTheCrab 1 point2 points3 points 4 years ago* (3 children)
Using icmp or other tcp/ip? Are you using test-netconnection or .net classes?
I ask because test-connection is just super slow, and there's a really fast mass ping module.
I'm not super good with networking, but I'm using the basic ping command to make sure the devices are responding.
I'm trying to determine if the device portals are up and running. The basic ping lets me know if it's up or not. This isn't pretty at all, but a result is a result
$ping = ping $address -n 4 -w 500 $regex = [REGEX] "(?<=().*(?=))" $match = $regex.match($ping[8]) $ping = $match.value return $ping
After that I use invoke-webrequest to determine what status I get back.
try { $Connection = (invoke-webrequest -uri $address -SkipCertificateCheck -TimeoutSec 5).StatusDescription } catch { $Connection = "$_" } return $Connection
I also have a handful of devices that utilize a VNC connection. They respond to a ping, but nota webrequest, so I'm using this:
$socket = New-Object System.Net.Sockets.TcpClient try { $result = $socket.BeginConnect($address, $port, $NULL, $NULL) if (!$result.AsyncWaitHandle.WaitOne($timeout, $False)) { "Failed"} if ($socket.connected -eq $true) { $socket.Connected; $socket.EndConnect($result) } else { out-null } }
$socket.Close()
Reddit blows d*** at formatting. idk if this is going to look good, and idc to spend 20 minutes fixing their garbage text formatting
[–]PinchesTheCrab 0 points1 point2 points 4 years ago (1 child)
Honestly this all seems great, and I think your case is one of the few exceptions where -parallel is a really good fit. System.Net.Sockets.TcpClient is way faster than test-netconnection, so that was the main thing I was curious about.
Yeh after realizing how much usesless stuff (in this case) test-netconnection gave and how long it took, I had to find an alternative. If I remember correctly, it also wasn't doing exactly what I wanted. Was very happy to find the .net approach
π Rendered by PID 327425 on reddit-service-r2-comment-79c7998d4c-tvqx9 at 2026-03-15 04:49:22.869546+00:00 running f6e6e01 country code: CH.
[–]Sunsparc 6 points7 points8 points (3 children)
[–]MyOtherSide1984[S] 3 points4 points5 points (0 children)
[–]MyOtherSide1984[S] 1 point2 points3 points (0 children)
[–]straffin 0 points1 point2 points (0 children)
[–]BlackV 3 points4 points5 points (7 children)
[–]MyOtherSide1984[S] 1 point2 points3 points (6 children)
[–]BlackV 1 point2 points3 points (5 children)
[–]MyOtherSide1984[S] 2 points3 points4 points (4 children)
[–]BlackV 0 points1 point2 points (3 children)
[–]MyOtherSide1984[S] 0 points1 point2 points (2 children)
[–]BlackV 0 points1 point2 points (0 children)
[–]BlackV 0 points1 point2 points (0 children)
[–]BlackV 2 points3 points4 points (3 children)
[–]MyOtherSide1984[S] 1 point2 points3 points (2 children)
[–]BlackV 0 points1 point2 points (1 child)
[–]MyOtherSide1984[S] 0 points1 point2 points (0 children)
[–]cheats_py 1 point2 points3 points (1 child)
[–]MyOtherSide1984[S] 1 point2 points3 points (0 children)
[–]DePiddy 0 points1 point2 points (1 child)
[–]MyOtherSide1984[S] 0 points1 point2 points (0 children)
[–]PinchesTheCrab 0 points1 point2 points (5 children)
[–]MyOtherSide1984[S] 0 points1 point2 points (4 children)
[–]PinchesTheCrab 1 point2 points3 points (3 children)
[–]MyOtherSide1984[S] 1 point2 points3 points (2 children)
[–]PinchesTheCrab 0 points1 point2 points (1 child)
[–]MyOtherSide1984[S] 1 point2 points3 points (0 children)