Question:
I know, that with the Parameter $using:foo
I can use a Variable from a different runspace while running ForEach-Object -Parallel
in Powershell 7 and up.
But how can I add the result back to a Variable? The common parameters +=
and $using:
will not work.
For instance:
1 2 3 4 5 6 7 8 9 10 |
$AllSubs = Get-AzSubscription $Date = (Get-Date).AddDays(-2).ToString("yyyy-MM-dd") $Costs = @() $AllSubs | Sort-Object -Property Name | ForEach-Object -Parallel { Set-AzContext $_.Name | Out-Null Write-Output "Fetching Costs from '$($_.Name)' ..." $using:Costs += Get-AzConsumptionUsageDetail -StartDate $using:Date -EndDate $using:Date -IncludeAdditionalProperties -IncludeMeterDetails -ErrorAction SilentlyContinue } |
Output:
1 2 3 |
The assignment expression is not valid. The input to an assignment operator must be an object that is | able to accept assignments, such as a variable or a property. |
Answer:
You will have to split the operation into two and assign the reference you get from $using:Costs
to a local variable, and you will have to use a different data type than PowerShell’s resizable array – preferably a concurrent (or thread-safe) type:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$AllSubs = Get-AzSubscription $Date = (Get-Date).AddDays(-2).ToString("yyyy-MM-dd") # Create thread-safe collection to receive output $Costs = [System.Collections.Concurrent.ConcurrentBag[psobject]]::new() $AllSubs | Sort-Object -Property Name | ForEach-Object -Parallel { Set-AzContext $_.Name | Out-Null Write-Output "Fetching Costs from '$($_.Name)' ..." # Obtain reference to the bag with `using` modifier $localCostsVariable = $using:Costs # Add to bag $localCostsVariable.Add($(Get-AzConsumptionUsageDetail -StartDate $using:Date -EndDate $using:Date -IncludeAdditionalProperties -IncludeMeterDetails -ErrorAction SilentlyContinue)) } |