Home > Software engineering >  Powershell Start-job something missing here
Powershell Start-job something missing here

Time:11-05

I have about 20 files, each one of them contains IPs. I have a function that uploads the IPs to rules I have in azure. Script will work just fine if running one by one but I need it to be parallel.

$i=1
foreach ($file in  (gci . -name "auto_farm_protection_*") ){
    Start-Job -ScriptBlock {
        [string[]]$ipsarry = Get-Content $file

        az network nsg rule update -g Testim --nsg-name sg-test -n "test_$i" --source-address-prefix $ipsarry 
            
    } -ArgumentList file,i 

    $i   
}

Should read "test_1" and pass it, "test_2" and pass it and so on. For some reason arguments do not pass to the start-job part, but I do use -ArgumentsList.

CodePudding user response:

It's probably faster with start-threadjob from the powershell gallery, or foreach-object -parallel in powershell 7. You'll need the full path of the files you open too, since unfortunately jobs use a default ~\documents directory (threadjobs don't have this problem). I've double quoted the az command as a demo since I don't have it.

# echo 192.168.1.1 > auto_farm_protection_a
# echo 192.168.1.2 > auto_farm_protection_b
# Install-Module -Name ThreadJob

$i=1
$result = foreach ($file in (gci . "auto_farm_protection_*") ){
    Start-ThreadJob -ScriptBlock {
        param($file, $i)
        [string[]]$ipsarry = Get-Content $file.fullname
        "az network nsg rule update -g Testim --nsg-name sg-test -n test_$i --source-address-prefix $ipsarry"
    } -Argumentlist $file,$i 
    $i   
}
$result | receive-job -wait -autoremove


az network nsg rule update -g Testim --nsg-name sg-test -n test_1 --source-address-prefix 192.168.1.1
az network nsg rule update -g Testim --nsg-name sg-test -n test_2 --source-address-prefix 192.168.1.2

CodePudding user response:

There are two errors in your code. The first one is in:

-ArgumentList file,i

You are passing literal strings "file" and "i" as arguments, as you are missing $ in front of the variable names.

The second one is that you are referring to the arguments by name from within the script block without having declared named parameters. This can be fixed by adding a param( $file, $i ) line to the script block.

Complete fix:

$i=1
foreach ($file in  (gci . -name "auto_farm_protection_*") ){
    Start-Job -ScriptBlock {
        param( $file, $i )

        [string[]]$ipsarry = Get-Content $file.FullName

        az network nsg rule update -g Testim --nsg-name sg-test -n "test_$i" --source-address-prefix $ipsarry 
            
    } -ArgumentList $file, $i 

    $i   
}

As you have noticed "using:" scope modifier is much easier to use, as it makes parameters obsolete:

$i=1
foreach ($file in  (gci . -name "auto_farm_protection_*") ){
    Start-Job -ScriptBlock {
        [string[]]$ipsarry = Get-Content $using:file.FullName

        az network nsg rule update -g Testim --nsg-name sg-test -n "test_$using:i" --source-address-prefix $ipsarry 
            
    }

    $i   
}

CodePudding user response:

Had to use $using:varname for some reason

  • Related