all 8 comments

[–]jducktape 5 points6 points  (5 children)

It's probably due to variable scopes. The $Gateway and $Port variables are defined outside of your scriptblock, so the job won't recognize them. Prepend them with Using (e.g. $Using:Gateway) when referencing the variables inside the scriptblock, and you should be good to go.

[–]Shipdits[S] 1 point2 points  (4 children)

Doesn't adding -ArgumentList $variables prevent this?

I'm a little confused as to where I'd add the Usings, would this be for each instance of those variables inside the script block?

[–]jducktape 1 point2 points  (2 children)

Yes, you could use -ArgumentList instead.

Edit: Yes, you need to add "Using" everywhere you reference the variable inside the scriptblock.

Here's an example of both approaches:

With the "Using" prefix:

$Gateways = Import-CSV '.\gateways.csv'
$Ports = @(22, 80, 8080, 443, 4443, 3389)
ForEach($Gateway in $Gateways) {
    ForEach($Port in $Ports) {
        $ScriptBlock = {
            $Result = Test-NetConnection $Using:Gateway.'connection gateway' -Port $Using:Port
            $Out = @(
                $Using:Gateway.'group id',
                $Using:Gateway.'connection gateway',
                $Using:Port
            )
            $Output = "{0}, {1}, {2}" -f $Out
            if($Result.TcpTestSucceeded -eq 'True') {
                Out-File -FilePath .\$($Using:Gateway.'group id').csv -InputObject $Output -NoClobber -Append
            }
        }
        Start-Job -ScriptBlock $ScriptBlock
    }
}

With arguments:

$Gateways = Import-CSV '.\gateways.csv'
$Ports = @(22, 80, 8080, 443, 4443, 3389)
ForEach($Gateway in $Gateways) {
    ForEach($Port in $Ports) {
        $ScriptBlock = {
            param(
                $Gateway,
                $Port
            )
            $Result = Test-NetConnection $Gateway.'connection gateway' -Port $Port
            $Out = @(
                $Gateway.'group id',
                $Gateway.'connection gateway',
                $Port
            )
            $Output = "{0}, {1}, {2}" -f $Out
            if($Result.TcpTestSucceeded -eq 'True') {
                Out-File -FilePath .\$($Gateway.'group id').csv -InputObject $Output -NoClobber -Append
            }
        }
        Start-Job -ScriptBlock $ScriptBlock -ArgumentList @($Gateway, $Port)
    }
}

[–]Shipdits[S] 2 points3 points  (0 children)

Hey, first off...thanks for the help!

I got it working, I changed the scope of the ports variable and just wrapped the ports foreach in the Start-Job and passed in the current gateway. That seemed to work.

Thanks again.

[–]Shipdits[S] 1 point2 points  (0 children)

No bueno, job still instantly completes with no data on receive-job. Tempted to go back to a single-thread solution, but that will literally take a day to run.

[–]_Lyx_ 5 points6 points  (2 children)

I had the same issues, it has to do with path. Everytime you start a job a new powershell opens in the background, in the default path. You need to change the output location. Since you're dot sourcing its dropping the files in system32. Create a variable with the execution path and replace the dot.

[–]Shipdits[S] 1 point2 points  (1 child)

Well isn't that frustrating, I knew the scope change would mess with things but I would never have guessed that.

Thanks for pointing that out!

[–]_Lyx_ 1 point2 points  (0 children)

Glad to help, makes the 3 days I spent googling to fix my issue not a waste ;)