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
-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.
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
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.