New-PSSession Parellel Execution

Douglas Plumley

We have two PSSessions that need to be established and imported into the current session before our script can continue. Both steps require about 10 - 15 seconds each for a total of 20 - 30 seconds when run in series.

Is it possible to run New-PSSession in a separate runspace and then somehow import that established session into the parent process?

For example change from this:

New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri ("https://$($service)/PowerShell/") -Credential $Credential -Authentication Basic -AllowRedirection -ErrorAction Stop

New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $Credential -Authentication Basic -AllowRedirection -ErrorAction Stop

To possibly something like this (warning this doesn't work):

$credential = Get-Credential

$scriptblock = 
{
       param ([string]$Credential)

       $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $Credential -Authentication Basic -AllowRedirection -ErrorAction Stop
       return $session
}


$shell = [PowerShell]::Create().AddScript($scriptblock).AddParameter($credential)

$job = $shell.BeginInvoke()
$result = $shell.EndInvoke($job)

Import-PSSession $result

The ultimate goal is to make this take less time, the idea being if we use New-PSSession in parallel it completes in 10 - 15 seconds instead of 20 - 30 seconds in series. I'd be happy with any answer that accomplishes this, it doesn't need to be using runspaces.

EDIT: Added goals

Elijah W. Gagne

Credit goes to @ShankarShastri for pointing us in the right direction. The New-PSSession commandlet supports taking an array of URIs or ComputerNames as input. I had servers to test against instead of URIs, but take a look at this:

$cred = Get-Credential DOMAIN\user

$servers = 
"server1.domain.company.com",
"server2.domain.company.com",
"server3.domain.company.com",
"server4.domain.company.com",
"server5.domain.company.com",
"server6.domain.company.com",
"server7.domain.company.com"

(Measure-Command {
    foreach($s in $servers) { $temp = New-PSSession -ComputerName $s -Authentication Negotiate -Credential $cred }
}).TotalSeconds

# 2.987739

(Measure-Command {
    $s1, $s2, $s3, $s4, $s5, $s6, $s7 = New-PSSession -ComputerName $servers -Authentication Negotiate -Credential $cred
}).TotalSeconds

# 0.5793281

That shows New-PSSession run 7 times vs running New-PSSession once and supplying 7 ComputerNames. The difference is about 6 times faster, which implies the connections are made asynchronously.

So in your case, you can probably accomplish what you want by running something like:

$sessions1, $sessions2 = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri ("https://$($service)/PowerShell/"),"https://outlook.office365.com/powershell-liveid/" -Credential $Credential -Authentication Basic -AllowRedirection -ErrorAction Stop

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related