EVERYTHING About PowerShell Remoting
This article contains the video notes that goes with the video https://youtu.be/sg_9r0PHnnM which covers EVERYTHING you should know about PowerShell Remoting.
In order to avoid that the contents of this article looks random, I will recomend you watch the video related to this article FIRST!
IF you already come from the youtube video, first of all THANK YOU SO MUCH for watching it. I spend SO MUCH time preparing that video, that every single view on that video feels like a whole stadium looked at it. Thanks!
Second, you should be able to find the contents I mention in the article in order they appear in the video.
This article might evolve / change over time to complete or add details to the video that the community might would like to see. So, don’t hesitate to subscribe to the blog too, and come back here once in a while to see if thinks have changed.
List of PowerShell cmdlets that have Built-In remoting support in PowerShell 5.1 (-ComputerName)
This is the list of PowerShell cmdlets that have built-in remoting capabilities on Windows Powershell (Powershell 5.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
Name ModuleName ---- ---------- Add-Computer Microsoft.PowerShell.Management Clear-EventLog Microsoft.PowerShell.Management Connect-PSSession Microsoft.PowerShell.Core Connect-WSMan Microsoft.WSMan.Management Disconnect-WSMan Microsoft.WSMan.Management Enter-PSSession Microsoft.PowerShell.Core Get-EventLog Microsoft.PowerShell.Management Get-HotFix Microsoft.PowerShell.Management Get-Process Microsoft.PowerShell.Management Get-PSSession Microsoft.PowerShell.Core Get-Service Microsoft.PowerShell.Management Get-WmiObject Microsoft.PowerShell.Management Get-WSManInstance Microsoft.WSMan.Management Invoke-Command Microsoft.PowerShell.Core Invoke-WmiMethod Microsoft.PowerShell.Management Invoke-WSManAction Microsoft.WSMan.Management Limit-EventLog Microsoft.PowerShell.Management New-EventLog Microsoft.PowerShell.Management New-PSSession Microsoft.PowerShell.Core New-WSManInstance Microsoft.WSMan.Management Receive-Job Microsoft.PowerShell.Core Receive-PSSession Microsoft.PowerShell.Core Register-WmiEvent Microsoft.PowerShell.Management Remove-Computer Microsoft.PowerShell.Management Remove-EventLog Microsoft.PowerShell.Management Remove-PSSession Microsoft.PowerShell.Core Remove-WmiObject Microsoft.PowerShell.Management Remove-WSManInstance Microsoft.WSMan.Management Rename-Computer Microsoft.PowerShell.Management Restart-Computer Microsoft.PowerShell.Management Set-Service Microsoft.PowerShell.Management Set-WmiInstance Microsoft.PowerShell.Management Set-WSManInstance Microsoft.WSMan.Management Show-EventLog Microsoft.PowerShell.Management Stop-Computer Microsoft.PowerShell.Management Test-Connection Microsoft.PowerShell.Management Test-WSMan Microsoft.WSMan.Management Write-EventLog Microsoft.PowerShell.Management |
List of PowerShell cmdlets that have Built-In remoting support in PowerShell 6.X and above (-ComputerName)
The following list contain the PowerShell cmdlets that contain built-in PowerShell remoting capabilities in PowerShell 6.X (PowerShell Core) and above.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Name ModuleName ---- ---------- Connect-PSSession Microsoft.PowerShell.Core Enter-PSSession Microsoft.PowerShell.Core Get-HotFix Microsoft.PowerShell.Management Get-PSSession Microsoft.PowerShell.Core Invoke-Command Microsoft.PowerShell.Core New-PSSession Microsoft.PowerShell.Core Receive-Job Microsoft.PowerShell.Core Receive-PSSession Microsoft.PowerShell.Core Remove-PSSession Microsoft.PowerShell.Core Rename-Computer Microsoft.PowerShell.Management Restart-Computer Microsoft.PowerShell.Management Stop-Computer Microsoft.PowerShell.Management |
It is easy to measure how many PowerShell cmdlets have built-in remoting support using the following Powershell Snippet:
In a nutshell, if the cmdlet has -ComputerName as a parameter, it has built-in PowerShell remoting capability.
1 2 3 |
Get-Command -CommandType Cmdlet | Where-Object { $_.Parameters.ContainsKey('ComputerName') } | Select-Object Name, ModuleName |
The list is WAY shorter than the one in PowerShell 5.1. In PowerShell Core (also known as PowerShell 7+), the -ComputerName
parameter is not as prevalent as in Windows PowerShell because PowerShell Core emphasizes cross-platform compatibility and uses PowerShell Remoting (via SSH) or WinRM for remote management, rather than relying on the -ComputerName
parameter. As a result, many cmdlets that had -ComputerName
in Windows PowerShell do not include it in PowerShell Core.
In PowerShell Core, most of the remoting functionalities are handled through the *-Session cmdlets such as:
- Invoke-Command
- Enter-PsSession
- New-PsSession
For more details on these cmdlets, I invite you to watch my video here
Why is there a difference between the cmdelts in PowerShell 5.1 and Powershell Core in the first place?
Many cmdlets like Get-Process
or Get-Service
, which used to have -ComputerName
in Windows PowerShell, no longer support it in PowerShell Core. The reason is that PowerShell Core was designed to be more modular and platform-independent, focusing on remote management through protocols like SSH or WinRM.
How to change the network profile type to domain / private
List the network card name (alias)
1 |
(Get-NetAdapter).InterfaceAlias |
Get the current network connection profile
1 |
Get-NetConnectionProfile -InterfaceAlias "BasementLab 0" |
How to change the network profile to type Public using powershell
Use the following snippet to change the network profile to type public.
1 |
Set-NetConnectionProfile -InterfaceAlias "BasementLab 0" -NetworkCategory Public |
How to change the network profile to type Domain using powershell
If instead you want to change it to the type Domain use the below snippet:
1 |
Set-NetConnectionProfile -InterfaceAlias "BasementLab 0" -NetworkCategory Domain |
Working with WinRm listeners:
Listing existing WinRM Listeners
List the existing WinRM listeners using the following WinRM command:
1 |
winrm enumerate winrm/config/listener |
Creating a new WinRm Listener on Https
Use the following snippet to create a HTTPS WinRM listener
1 |
winrm quickconfig -transport:https #Will fail with a self signed certificate |
It is also possible to create an HTTPS listener using New-Item and the WSMAN: drive
1 2 |
$Cert = Get-Certificate -SubjectName "Woop" New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificatethumbPrint $Cert.ThumbPrint |
Removing non used http WinRm Listeners
1 |
Get-ChildItem -Path WSMan:\LocalHost\Listener | Where-Object -Property Keys -eq 'Transport=http' | Remove-Item -Recurse |
Creating a new self signed certificate:
Use the following line in order to create a new selfsigned certificate on a Windows Machine.
1 2 3 |
$Cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "win103" $Cert |
Creating a session option to skip the CA check
In most cases, the default options for a Remote session will be exactly the ones you need to connect. In some more rare cases, it might not be the case. For that you have the possibility to create a session option, which you can add to your session when you are establishing the connection.
The example I used in my video, is to bypass the CA verification check for a self signed certificate.
Note: This is a BAD IDEA to do this in production, as you are REDUCING the security of your connection. Do this ONLY when it makes sense.
1 2 3 |
$SessionOption = New-PSSessionOption -SkipCACheck New-Psession -ComputerName Server03.Lab.Local -SessionOption $sessionOption |
List the currently open connections on a machine
In order to check current open tcp connections, use the following command:
1 |
Get-netTcpconnection -State Established |
Working with Trusted hosts
List the contents of the trusted hosts
1 |
Get-ChildItem WSMan:\localhost\Listener | Where-Object { $_.Keys -like '*HTTP*' } |
Add a system to the trusted host list:
1 |
Set-Item WSMAN:\LocalHost\Listener\client\TrustedHost -Value "192.168.11.101" |
Remove / clear the trusted host list
1 |
Clear-Item WSMan:\localhost\Listener\client\TrustedHosts -Force |
Working with PowerShell and OpenSSH
Get state of OpenSSH installation
1 |
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*' |
Install the OpenSSH Client
1 |
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 # Install the OpenSSH Server Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 |
Change the OpenSSH service to Automatic
1 2 |
Set-Service -Name sshd -StartupType 'Automatic' Start-service -Name sshd |
This will create a bunch of config files in C:\programData\ssh
Configure Firewall for OpenSSH
1 2 3 4 5 6 |
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) { Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..." New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 } else { Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists." } |
Uninstall the OpenSSH Client
1 |
Remove-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 |
Uninstall the OpenSSH Server
1 |
Remove-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 |
Change the default SSH prompt to Powershell
Set the
1 2 3 |
HKLM:\Software\OpenSSH\DefaultShell -> C:\program Files\Powershell7\pwsh.exe |
Add the OpenSSH subsystem
Add the following line under the substem part of your sshd.config file
1 |
Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -nologo |
The default location of the PowerShell executable is c:/progra~1/powershell/7/pwsh.exe. The location can vary depending on how you installed PowerShell.
You must use the 8.3 short name for any file paths that contain spaces. There’s a bug in OpenSSH for Windows that prevents spaces from working in subsystem executable paths. For more information, see this GitHub issue.
The 8.3 short name for the Program Files folder in Windows is usually Progra~1. However, you can use the following command to make sure using the follwing command
1 |
Get-CimInstance Win32_Directory -Filter 'Name="C:\\Program Files"' | Select-Object EightDotThreeFileName |
Generate SSH keys
Simply use the following executable:
1 |
Keygen.exe |
Give administrator access:
Copy the contents of the public key to administrator_known_hosts.pub
Make sure that only the administrator and the system account have access to this file.
Powershell over SSH on Linux systems
Install the openSSH client
1 |
sudo apt install openssh-client |
Install the OpenSSH server on Linux
1 |
sudo apt install openssh-server |
Configure the poweshell subsystem
Open the ssd_config file with VIM using the following line
1 |
Sudo vim /etc/ssh/sshd_config |
Search for the ‘subsystems’ section, and add the following line beneath the existing subsystem.
1 |
subsystem powershell /usr/bin/pwsh -sshs -nologo |
Un comment password authentication (make sure it is set to yes)
Restart the sshd deamon
1 |
sudo systemctl restart sshd.service |
After that, you can use the regular *-PsSession cmdlets to create, use remove the session.
Leave A Comment