Created
September 30, 2023 06:12
-
-
Save JohnLBevan/80c5005a2bd0becb929da68e7bf9cf8e to your computer and use it in GitHub Desktop.
Powershell parallel foreach reference demo code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# some function we want available in our parallel runspace | |
function Get-DummyItem { | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory)] | |
[string]$Name | |
) | |
$myIp = Invoke-WebRequest -Method Get -Uri 'https://api.my-ip.io/ip' | |
"[$Name] was processed by [$myIp]" | |
} | |
# ... | |
#some sample data to iterate over | |
$testData = 1..100 | %{[PSCustomObject]@{ID=$_;Name="Someone Number $_"}} | |
# a variable outside our parallel runspace | |
$appendString = 'Hello' | |
# get the definition of any functions created in current scope so we can make them available in our parallel thread's runspace | |
$getDummyItemParallel = ${function:Get-DummyItem}.ToString() | |
# Do the loop... here I'm assigining the output to a variable so that later we can amend the order of the output from all threads before returning | |
[pscustomobject[]]$output = $testData | ForEach-Object -ThrottleLimit 15 -Parallel { | |
# bug work around https://github.com/PowerShell/PowerShell/issues/13816 | |
# for any preference variables ensure they're the same in our runspace as the caller's (note: this isn't a complete list; e.g. things like ShouldProcess aren't covered - see the github issue for a better example) | |
$DebugPreference = $using:DebugPreference | |
$VerbosePreference = $using:VerbosePreference | |
$InformationPreference = $using:InformationPreference | |
# end of bug workaround | |
# create our custom function within our runspace (note the using; more on that below) | |
${function:Get-DummyItem} = $using:getDummyItemParallel | |
# our pipeline variable is available as normal... here I add it to another variable so it's accessible when we delve into lower loops | |
$currentItem = $_ | |
# do some processing. Note the use of `using:` to access variables defined outside of our runspace. These must be readonly within this runspace. | |
$ipInfo = Get-DummyItem -Name $currentItem.Name | |
$currentItem | Add-Member -Name 'Demo' -MemberType NoteProperty -Value "$using:appendString $ipInfo" | |
} | |
$output | Sort-Object Id | |
#... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment