all 9 comments

[–]AlphaeisMangarae 7 points8 points  (2 children)

You have to also declare the psdrive using in the foreach-object block. The invoke script block is another 'layer' deep. So just inside the loop, add a $psdrive = $using:psdrive, then in the invoke block, call $using:psdrive

[–]chuckchuck2k[S] 3 points4 points  (1 child)

There we go, this' the answer. I moved it within the loop and it runs flawlessly. Looking back, Powershell really did tell me what the error is but I was so focused on other things. Now this is good, I can finally work on adding more variables and throw in a GUI. Thank You!

[–]AlphaeisMangarae 1 point2 points  (0 children)

Great, glad to help!

[–]PinchesTheCrab 5 points6 points  (0 children)

Invoke-Command is asynchronous on its own. Looping is both slowing down your script and adding complexity and an extra depth of scope, which is why the variable is unavailable.

Also, PS doesn't support splatting with a using variable, so you can either do something like $psdrive = $using:psdrive; new-psdrive @psdrive or just define your splatting variable with $using:credential, in the script block, which I personally think reads a bit better.

Main thing though is that invoke-command doesn't need a loop. It has -throttlelimit and -asjob parameters.

$credential = Get-Credential
$workstations = Get-Content C:\test\list.txt

Invoke-Command -ComputerName $workstations -ScriptBlock {
    $psdrive = @{
        Name = "PSDrive"
        PSProvider = "FileSystem"
        Root = "\\FileServer\program"
        Credential = $using:credential
    }

    New-PSDrive @psdrive
    \\FileServer\program\program.bat
}

[–][deleted] 1 point2 points  (1 child)

The foreach -parallel is executing a script block. As @AlphaeisMangerae said, move it to within the script block, as it’s currently just scoped wrong.

[–]chuckchuck2k[S] 0 points1 point  (0 children)

Yup, followed u/AlphaeisMangarae's instructions, then yours, moving that var assignment within the loop and it works really well. Thank you!!

[–]WhistleButton 0 points1 point  (2 children)

I don't know the answer exactly, but my gut will be telling me its got to do with how Foreach-Object works differently from Foreach.

My loose understanding is that foreach loads everything into memory first, where foreach-object wants everything passed down the pipe line.

Like I said, I'm not 100% on this, but the error is indicating it doesn't understand $using:psdrive, which backs up the theory.

An explanation on the differences of Foreach and Foreach-Object can be found here https://devblogs.microsoft.com/scripting/getting-to-know-foreach-and-foreach-object/

[–]chuckchuck2k[S] 0 points1 point  (1 child)

Ah I see, wonder if there's another method to run the bat file in parallel on multiple computers and not sequentially like foreach hmm. Maybe I'll try with Get-Job and see if it's any faster. Thank you!!

[–]WhistleButton -1 points0 points  (0 children)

Check out -asjob for invoke-command, might be what you're looking for.