Emanuele
Emanuele

Reputation: 359

ForEach-Object -Parallel How to use it

I'm starting to use ForEach-Object -Parallel with PowerShell 7. I'm testing following code:

$MyArr = @()
$MyArr = (
    ('v1ne','rgNE'),`
    ('v1we','rgWE')
)

$MyArr | ForEach-Object -Parallel  { 
    Start-AzVM -Name $MyArr[0]  -ResourceGroupName $MyArr[1]
} -ThrottleLimit 10

To start up some virtual machine on azure in different Resource Groups. My idea is to get variable from array or from Azure automation variables. But I don't know how to pass different Resource Group Names in ForEach-Object -Parallel.

Any help is really appreciate.

Upvotes: 3

Views: 7617

Answers (1)

Santiago Squarzon
Santiago Squarzon

Reputation: 59900

As Mathias explained in comments, when using ForEach-Object -Parallel, you would need to use $_ (also known as $PSItem) to reference the current object from pipeline (same applies for ForEach-Object). If you want to reference a variable that is not coming from pipeline you would use the $using: keyworkd.

Example:

$notFromPipeline = 'Hello'

0..5 | ForEach-Object -Parallel {
    "$using:notFromPipeline $_"
}

As for, how you could approach your script, I think splatting with $_ seems fit for this, suppose you had a CSV with the VM Names and their corresponding Resource Groups, something like:

  • VMs.csv
Name,ResourceGroupName
v1ne,rgNE
v1we,rgwE

You could do something like this, note, below example is using a function (TestSplat) just to show you how the parameters are bound using splatting with a hash table, in your case, you would replace this function for Start-AzVM.

First you can create an array of hash tables like this:

$myParams = Import-Csv ./VMs.csv | ForEach-Object {
    $z = @{}
    foreach($prop in $_.PSObject.Properties) {
        $z[$prop.Name] = $prop.Value
    }
    $z
}

$myParams would be something like this:

Name                           Value
----                           -----
Name                           v1ne
ResourceGroupName              rgNE
Name                           v1we
ResourceGroupName              rgwE

The column names of your CSV must match with the Parameter Names of Start-VM (Name and ResourceGroupName).

Now you can iterate over $myParams using ForEach-Object -Parallel:

$myParams | ForEach-Object -Parallel  {
    function TestSplat {
        param($Name, $ResourceGroupName)
        Write-Host "Name: $Name - ResourceGroup: $ResourceGroupName"
    }

    TestSplat @_
} -ThrottleLimit 10

Which should result in:

Name: v1ne - ResourceGroup: rgNE
Name: v1we - ResourceGroup: rgwE

Upvotes: 3

Related Questions