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