Author Posts

August 4, 2017 at 5:32 pm

I want to create a new PSSession with multiple computers and assign it a session name. The below only assigns the first computer in the list to the session name and not the second. Is this by design? If I pipe the names to a foreach statement or pipe the names to New-PSSession it seems to work fine. Any reason the first example would not assign the session name to all computers assigned by the -computername parameter?

PS> New-PSSession -ComputerName 'dt-600062','dt-600044' -Name kevin2

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
 14 Session14       dt-600044       RemoteMachine   Opened        Microsoft.PowerShell     Available
 13 kevin2          dt-600062       RemoteMachine   Opened        Microsoft.PowerShell     Available

Note: I use the foreach alias '%' in the below command.

PS> 'dt-600062','dt-600044' | % {New-PSSession -ComputerName $_ -Name 'kevin'}

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  9 kevin           dt-600062       RemoteMachine   Opened        Microsoft.PowerShell     Available
 10 kevin           dt-600044       RemoteMachine   Opened        Microsoft.PowerShell     Available
PS> 'dt-600062','dt-600044' | New-PSSession -Name kevin

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
 11 kevin           dt-600062       RemoteMachine   Opened        Microsoft.PowerShell     Available
 12 kevin           dt-600044       RemoteMachine   Opened        Microsoft.PowerShell     Available

August 4, 2017 at 5:35 pm

-Name is an array. You'd pass it an array of session names, just as you pass an array of computer names to -ComputerName. It's designed so that you can provide a unique name for each session, not to provide a non-unique name to a group of sessions.

In the third example, there's a kind of implicit ForEach going on inside New-PSSession because you passed values from the pipeline. The non-pipeline parameters end up with the same parameter values for each iteration of that loop. So it's more or less the same, functionally, as the second example.

August 4, 2017 at 6:15 pm

It looks like name accepts but does not accept pipeline input.

I could do this, but I think using the pipeline would be better.

PS> New-PSSession -ComputerName 'dt-600062','dt-600044' -Name 'session1','session2'

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
 19 session1        dt-600062       RemoteMachine   Opened        Microsoft.PowerShell     Available
 20 session2        dt-600044       RemoteMachine   Opened        Microsoft.PowerShell     Available
PS> Get-PSSession -Name session3

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
 22 session3        dt-600044       RemoteMachine   Opened        Microsoft.PowerShell     Available
 21 session3        dt-600062       RemoteMachine   Opened        Microsoft.PowerShell     Available

August 4, 2017 at 6:17 pm

Whoops forgot to past the line above Get-PSSession -Name session3

PS> New-PSSession -ComputerName 'dt-600062','dt-600044' -Name 'session3','session3'

August 4, 2017 at 6:22 pm

Well, the way the pipeline works, you can only have a command wired up to accept "String" objects to one parameter, and it's -ComputerName. So no, -Name isn't rigged to accept strings from the pipeline. That's just the command's design. Given how PowerShell is designed, you just can't.

That said, you could shortcut it for yourself. That's the point of PowerShell – being a wrapper.

function New-BetterPSSession {
 [CmdletBinding()]
 Param(
  [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
  [hashtable[]]$InputObject
 )
 PROCESS {
  ForEach ($I in $InputObject) {
   New-PSSession -Comp $I.ComputerName -Name $I.Name
  }
 }
}
$sessions = $(@{ComputerName='SERVER1';Name='Session1'},@{'ComputerName'='SERVER2';Name='Kevin})
$sessions | New-BetterPSSession

I mean, vaguely like that. I literally just typed that here. But the way to get multiple values down the pipeline at once is to structure them as an object of some kind, in this case I used a hash table, obviously. You can make it work however you want, if you're willing to add whatever interfacing you need around it.

August 4, 2017 at 7:10 pm

That is very cool, thank you for showing me the Hash table type. I will be testing that out in some other applications as well!