Reputation: 322
I would like to create multiple Powershell sessions to my local machine to perform some operations on many files / folders at once, without slowing down my actual Powershell script. Therefore I was looking for possibilities to do multi-threading in Powershell.
The easiest approach appears to be the New-PSSession
cmdlet. I created a test script to play around with it.
Write-Host "Creating session"
$NewSession = New-PSSession
Write-Host "Session created" #This line will not show up anymore...
Invoke-Command -Session $NewSession -ScriptBlock {$WSH = Create-Object -comObject WScript.Shell; $WSH.Popup("Some popup", 1) } -AsJob
Whenever I run it, it simply freezes when calling New-PSSession
What am I doing wrong?
Upvotes: 2
Views: 2119
Reputation: 21518
Seems New-PSSession
hangs when not providing arguments. This is not really what New-PSSession
is meant for anyways, you should prefer the Start-Job
cmdlets (or you could use Start-ThreadJob
if available to you). An example:
$myFirstName = "Bender"
$myLastName = "the Greatest"
$jobWithArgs = Start-Job -ArgumentList $myFirstName, $myLastName -ScriptBlock {
Write-Output "My name is $($args[0]) $($args[1])"
}
# Do Local Script Stuff
$jobResult = Receive-Job $job -Wait
# Process the job result
Receive-Job -Wait
will block until all job results have been received. Basically it'll wait for the job to finish so you don't have to write any boilerplate around that. -ArgumentList
is optional and is used to pass in an array of arguments that can be processed within the job.
Here are additional Microsoft resources for Start-Job
and Receive-Job
:
Upvotes: 2
Reputation: 483
It is not necessary to create sessions to run commands in the background; just use the -AsJob
switch to Invoke-Command
and collect the resulting job objects. When you want the results, pass them to Receive-Job
.
# Not optimal for a few reasons; this is just example code.
$jobs = @()
foreach ($block in $scriptBlocksToRun) {
$jobs += (Invoke-Command -ScriptBlock $block -AsJob)
}
# Do things that don't depend on job results here...
foreach ($job in $jobs) {
$output = $job | Receive-Job
# Do something with output here...
}
Obviously, you should consult the documentation for Invoke-Command and Receive-Job for more details.
Upvotes: 0