Remoting and PSSessions
By the end of this lesson you'll run commands on remote machines with Invoke-Command, drop into an interactive remote prompt with Enter-PSSession, reuse persistent connections via New-PSSession, fan a command out across many servers at once, and pass local data into remote blocks with $using: — the foundation of real infrastructure automation.
Learn Remoting and PSSessions in our free PowerShell course — an interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Powershell course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
💡 Real-World Analogy
Remoting is like having remote control of other computers. Enter-PSSession is a video call — you're "in the room" on one machine, typing live. Invoke-Command is sending a task by courier — you hand over a sealed instruction (the script block), it's carried out on the far end, and the results are couriered back to you. New-PSSession is keeping the phone line open so you don't redial for every message, and $using: is writing your local notes into the instruction so the remote worker has the details they need.
1. Running Commands Remotely with Invoke-Command
Invoke-Command is the workhorse of remoting. You give it -ComputerName (where to run) and a -ScriptBlock (what to run); the block executes on the remote machine and the results come back to you as objects, each tagged with a PSComputerName property. Read this worked example, then run it against a host you control.
2. Interactive Sessions with Enter-PSSession
When you want to "go there and look around" one machine, Enter-PSSession drops you into an interactive remote prompt. Your prompt changes to show the remote host, every command you type runs there, and Exit-PSSession brings you home. Supply credentials with -Credential (Get-Credential) . This is ideal for single-machine troubleshooting; for automation across many hosts, reach for Invoke-Command instead.
Now you try. Fill in the one blank using the hint in the comment, then run it.
3. Persistent Connections with New-PSSession
Passing -ComputerName opens a throwaway connection per call. For repeated work, create a persistent session with New-PSSession and pass it to Invoke-Command -Session . Reuse is faster and keeps state between calls — a variable set in one call is still there in the next. Always Remove-PSSession when you finish to free resources on both ends.
Pro Tip
On Windows, remoting rides on WinRM (enable it once with Enable-PSRemoting ). In PowerShell 7 you can also remote over SSH with -HostName instead of -ComputerName , which works cross-platform to Linux and macOS. Pick WinRM inside a Windows domain; pick SSH when you need to cross operating systems.
Putting It Together: fan-out + $using:
The two features that make remoting scale: give -ComputerName a list and the block runs on every machine in parallel ; and use the $using: scope modifier to push a local variable into the remote block (a remote session can't see your local variables otherwise).
Each returned object carries PSComputerName , so even though all three ran at once you always know which host produced which row.
Common Errors (and the fix)
- "WinRM cannot complete the operation … check that the computer is accessible" — remoting isn't enabled or a firewall blocks it. Run Enable-PSRemoting on the target and confirm connectivity with Test-WSMan .
- A local variable is empty inside the remote block — the remote session can't see your locals. Prefix it with $using: , e.g. $using:logFolder .
- Leaking sessions / "maximum number of concurrent shells" — you forgot to close sessions. Always Remove-PSSession (or use them in a try/finally ).
- "Access is denied" — wrong identity. Pass explicit credentials with -Credential (Get-Credential) , and check the account has rights on the target.
- Expecting live objects back but getting "deserialized" ones — results returned over remoting are serialized snapshots, so their methods don't run locally. Do method calls inside the remote script block, then return plain data.
📋 Quick Reference — Remoting
Cmdlet
Purpose
Example
Invoke-Command
Run a block remotely
Invoke-Command -ComputerName S1 -ScriptBlock {...}
Enter-PSSession
Interactive remote prompt
Enter-PSSession -ComputerName S1
New-PSSession
Persistent connection
$s = New-PSSession -ComputerName S1
Remove-PSSession
Close a session
Remove-PSSession $s
-Credential
Authenticate
-Credential (Get-Credential)
$using:
Pass a local variable in
$using:path
Frequently Asked Questions
Mini-Challenge: multi-server uptime report
No blanks this time — just a brief and an outline to keep you on track. Build it, run it (against lab hosts), and check your output against the example in the comments. Fanning a check out across servers is everyday infrastructure work.
🎉 Lesson Complete
- ✅ Invoke-Command -ComputerName -ScriptBlock runs code remotely and returns objects
- ✅ Enter-PSSession gives an interactive one-machine prompt
- ✅ New-PSSession / Remove-PSSession reuse and clean up persistent connections
- ✅ Remoting rides WinRM on Windows or SSH cross-platform; authenticate with -Credential
- ✅ Fan out across many machines and pass local data in with $using:
- ✅ Next lesson: Strings, Formatting & Regex — shape and search text precisely
Practice quiz
What does PowerShell Remoting let you do?
- Run commands on remote computers
- Compress archives
- Format strings
- Edit local files faster
Answer: Run commands on remote computers. Remoting runs PowerShell commands and scripts on one or many remote machines from your local session.
Which cmdlet runs a script block on a remote computer?
- Get-Process
- Enter-Session
- Invoke-Command
- Start-Process
Answer: Invoke-Command. Invoke-Command -ComputerName <name> -ScriptBlock { ... } runs the block remotely and returns the results.
Which cmdlet opens an interactive one-to-one remote session?
- Invoke-Command
- Enter-PSSession
- Connect-Host
- New-PSSession
Answer: Enter-PSSession. Enter-PSSession starts an interactive session so your prompt operates on the remote machine until you Exit-PSSession.
What does New-PSSession create?
- A new local window
- A scheduled task
- A log file
- A persistent reusable connection to a remote host
Answer: A persistent reusable connection to a remote host. New-PSSession creates a persistent PSSession you can reuse across multiple Invoke-Command calls.
Which cmdlet closes and cleans up a PSSession?
- Remove-PSSession
- Stop-Session
- Close-PSSession
- Exit-Session
Answer: Remove-PSSession. Remove-PSSession disconnects and removes a session, freeing resources on both ends.
On Windows, which protocol is the traditional remoting transport?
- FTP
- WinRM
- SMTP
- Telnet
Answer: WinRM. WinRM (Windows Remote Management) is the default transport for PowerShell remoting on Windows.
Which transport enables cross-platform PowerShell remoting?
- HTTP only
- RDP
- SMB
- SSH
Answer: SSH. PowerShell 7 supports SSH-based remoting, letting you connect across Windows, Linux, and macOS.
How do you supply alternate credentials to a remote command?
- -Login
- -User
- -Credential
- -Password
Answer: -Credential. The -Credential parameter accepts a PSCredential so you can authenticate as a different user.
What does Invoke-Command do when given many computer names?
- Errors out
- Runs the command on all of them in parallel
- Runs them one at a time slowly
- Picks one at random
Answer: Runs the command on all of them in parallel. Invoke-Command fans out and runs the script block on all listed computers concurrently.
Inside a remote script block, how do you use a LOCAL variable?
- Prefix it with $using:
- Use $remote:
- It is impossible
- Just type $var
Answer: Prefix it with $using:. The $using: scope modifier passes a local variable into the remote script block, e.g. $using:path.
Continue this course
- Previous: Modules & the PowerShell Gallery
- Next: Strings, Formatting & Regex