Chapter 14Lesson 01~155 minutes

Remoting Mental Model: PSRP, Transports, Sessions, and Serialization

Build the correct mental model for PowerShell remoting: PSRP over a transport, remote execution contexts, persistent sessions, serialization, variable capture, and bounded fan-out.

BeginnerPSRPSerializationRemoting

Learning objectives

  • Distinguish PSRP, transport, endpoint, authentication, session, and serialization.
  • Compare one-off Invoke-Command with persistent PSSession workflows.
  • Explain why many remote objects become deserialized snapshots.
  • Use $Using: and -ArgumentList with a clear data-boundary mental model.
  • Preserve remote provenance such as PSComputerName.
  • Describe fan-out and throttling before automating fleets.

1. Remote execution creates a second execution environment

When you run Get-Process locally, the command, variables, modules, filesystem paths, permissions, and .NET objects all belong to your current PowerShell process. Remoting changes that model: a client asks another PowerShell process to run code elsewhere and return a representation of the result.

The most important beginner habit is to ask, “Which computer and which PowerShell process owns this state?” A path such as C:\Logs, a module name, or a variable can mean something completely different on the remote host.

2. The remoting vocabulary describes separate responsibilities

Term Meaning
PSRP The PowerShell Remoting Protocol: the PowerShell-level protocol that carries commands, streams, and serialized data.
Transport The underlying connection mechanism. In modern PowerShell this is commonly WSMan between Windows systems or SSH across platforms.
Endpoint / session configuration The remote PowerShell hosting configuration you connect to. WSMan supports named endpoint configurations; current SSH remoting uses an SSH subsystem and does not provide the same endpoint/JEA hosting model.
Authentication How the remote side establishes who you are, such as Kerberos/Negotiate for Windows WSMan or SSH key/password mechanisms for SSH.
PSSession A persistent logical remote PowerShell session that can retain remote variables and other session state between commands.
Serialization Converting objects into transferable data so they can cross a process/network boundary.

These layers are related but not interchangeable. SSH is not PSRP, and PSRP is not authentication. Keeping the layers separate makes troubleshooting much easier.

3. Mental model: command goes out, serialized data comes back

The transport carries PSRP traffic to a remote PowerShell host. The command runs there, then result objects and streams are serialized for the return trip.

Mental model: command goes out, serialized data comes back
flowchart TD
  A[Local PowerShell client] -->|PSRP messages| B[Transport: WSMan or SSH]
  B --> C[Remote PowerShell host]
  C --> D[Command executes with remote paths modules permissions]
  D --> E[Objects and streams]
  E -->|serialize| B
  B -->|deserialize| A

4. Temporary commands and persistent sessions solve different problems

Invoke-Command can create a temporary connection, run a script block, return the result, and close that temporary session. This is excellent for one-off read operations.

# Windows WSMan example -- requires a configured Windows target.
Invoke-Command -ComputerName 'server01' -ScriptBlock {
    [pscustomobject]@{
        Computer = $env:COMPUTERNAME
        Edition  = $PSVersionTable.PSEdition
        Version  = $PSVersionTable.PSVersion.ToString()
    }
}

For a sequence of related commands, create a PSSession. State created inside that remote session can be reused later.

$session = New-PSSession -ComputerName 'server01'
Invoke-Command -Session $session -ScriptBlock { $script:InventoryTag = 'batch-42' }
Invoke-Command -Session $session -ScriptBlock { $script:InventoryTag }
Remove-PSSession -Session $session

5. Most remote output is a snapshot, not a live remote object

Live .NET objects cannot simply move across the network with their process-bound methods and handles intact. PowerShell serializes object properties, sends the representation, then deserializes it locally. Many complex values therefore arrive as PSObject snapshots whose type names are prefixed with Deserialized..

$remote = Invoke-Command -ComputerName 'server01' -ScriptBlock {
    Get-Process -Id $PID
}

$remote.PSObject.TypeNames | Select-Object -First 3
$remote | Get-Member

You can filter, select, export, and inspect the returned properties. But a process-specific method such as Kill() must operate on the remote live process object inside the remote command, not on a deserialized local snapshot.

6. Remote results carry provenance

PowerShell adds remoting metadata such as PSComputerName and RunspaceId to many results. Preserve that provenance when you are collecting from multiple machines; it answers the critical question “which host produced this record?”

Invoke-Command -ComputerName 'server01','server02' -ScriptBlock {
    Get-Culture
} | Select-Object PSComputerName,Name,DisplayName

7. $Using: embeds a caller value into out-of-session code

A variable name inside a remote script block normally refers to a variable in the remote session. Prefixing it with Using: tells PowerShell to take the value from the calling session and make that value available to the remote command.

$pattern = '*.log'
Invoke-Command -ComputerName 'server01' -ScriptBlock {
    Get-ChildItem -Path $HOME -Filter $Using:pattern -File -ErrorAction SilentlyContinue |
        Select-Object Name,Length
}

For remote and other out-of-process execution, that value crosses the boundary as an independent serialized copy. Assigning to a remote value does not mutate the original local variable.

8. Parameters make remote data flow easier to test

For larger script blocks, explicit parameters often make the boundary clearer than many $Using: references. -ArgumentList supplies local values to parameters declared inside the remote script block.

$minimumMb = 512
Invoke-Command -ComputerName 'server01' -ScriptBlock {
    param([int]$MinimumMb)

    Get-Process |
        Where-Object WorkingSet64 -ge ($MinimumMb * 1MB) |
        Select-Object Name,Id,WorkingSet64
} -ArgumentList $minimumMb

9. Fan-out means one control point targets many remote systems

PowerShell can execute the same command against multiple targets. That is fan-out. Concurrency must be bounded because every remote connection consumes CPU, memory, sockets, authentication work, and remote capacity. -ThrottleLimit exists on relevant remoting commands to cap concurrent work.

Do not interpret fan-out as an all-or-nothing transaction. Results can arrive in a different order than targets were listed, and one host can fail while others succeed.

10. Lab: model the boundary without requiring a second machine

If you do not have a remoting target, this lab uses a separate local PowerShell process to demonstrate the same core process boundary: data must be serialized, local variables are not shared, and returned values are copies.

$pwsh = (Get-Command pwsh -CommandType Application).Source
$payload = [pscustomobject]@{ Name='academy'; Count=3 }
$json = $payload | ConvertTo-Json -Compress
$previous = $env:ACADEMY_PAYLOAD
try {
    $env:ACADEMY_PAYLOAD = $json
    $result = & $pwsh -NoProfile -Command @'
$item = $env:ACADEMY_PAYLOAD | ConvertFrom-Json
[pscustomobject]@{
    ProcessId = $PID
    Name      = $item.Name
    Doubled   = $item.Count * 2
} | ConvertTo-Json -Compress
'@
}
finally {
    if ($null -eq $previous) { Remove-Item Env:ACADEMY_PAYLOAD -ErrorAction SilentlyContinue }
    else { $env:ACADEMY_PAYLOAD = $previous }
}

$result | ConvertFrom-Json

The transport here is not PSRP, so it is not a remoting substitute. It is a safe demonstration of the fundamental boundary that remoting must also solve.

11. Verification checklist

  • You can distinguish PSRP from WSMan and SSH.
  • You know when a one-off Invoke-Command is enough and when a PSSession is useful.
  • You expect remote complex objects to be serialized snapshots.
  • You preserve PSComputerName when collecting fleet data.
  • You understand that $Using: supplies a copied value to remote/out-of-process code.
  • You treat fan-out as bounded concurrent work with partial failure.

12. Common mistakes and why they fail

  • Assuming a local path exists remotely: the remote process has its own filesystem and current directory.
  • Calling methods on a deserialized object: many live methods were not transmitted.
  • Expecting a remote assignment to change a local variable: out-of-process values are copied.
  • Dropping target metadata: you lose the source of a fleet result.
  • Opening unlimited connections: concurrency becomes a load problem instead of an automation feature.

13. Knowledge check

Question 1. What does PSRP provide?

Question 2. Why can a remote process object lose methods locally?

Question 3. When is a PSSession more useful than a one-off Invoke-Command?

Question 4. What does $Using:name mean in a remote command?

Question 5. Why keep PSComputerName in fleet output?

14. Summary and next bridge

Remoting is a boundary: code executes in another PowerShell host, reached through a transport, and data crosses via serialization. Once that model is clear, Windows WSMan configuration becomes easier to understand because listeners, authentication, endpoints, and trust are security controls around that boundary. Lesson 2 focuses on that Windows path.

15. Authoritative references

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.