
Remote PowerShell Core session to a Linux host from Windows machine
Remote sessions using OpenSSH from Windows to Linux host
Starting from January 2018, Microsft has made PowerShell Core 6, a cross-platform tool available not only to Windows users which was the case so far with previous versions, but to Linux and Mac users as well.
Since it was tool for Windows only, it had it's own ways for remoting using WinRM unlike Linux operating systems which primarily rely on SSH. Windows is great for editing and development, I find it really comfortable to work on with so many tools and platform available. On the other hand, it is too robust, especially because of it's UI which makes it not so suitable for scaling. On the other hand, you can run Linux as a headless OS which makes is blazing fast, but it is not so comfortable for development because of the lack of UI.
For me winning combination is using Windows for development, but deploy to Linux machine. Now when there is PowerShell runing on both hosts it makes it a lot easier to automate stuff. Let's start with setting up new PowerShell on both host and finally connect from the development Windows machine to deployment Linux machine.
1. Setting up PowerShell on Linux
I will use Debian headless Linux VM for setting up PowerShell 6 Core for this demo, but you are free to use any other distro. If you are planning to install PowerShell 6 Core on any other distro other than Debian 9 Linux, follow the instructions from Microsoft documentation page https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-powershell-core-on-linux?view=powershell-6. Login to your Linux machine using SSH and execute following commands
sudo apt-get update sudo apt-get install curl gnupg apt-transport-https curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/microsoft.list' sudo apt-get update # Install PowerShell sudo apt-get install -y powershell
Now just verify the powershell is installed
pwsh -V
You should get the PowerShell version installed as an output of the command above
2. Configure OpenSSH on Linux host
First thing we need to do to enable OpenSSH connections for PowerShell is to modify OpenSSH config. Open the config using nano editor
sudo nano /etc/ssh/sshd_config
In opened configuration file in nano editor, paste the following live below existing subsystem line
Subsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile
Save the file and exit nano editor with CTRL+O ENTER to save and CTRL+X key combination to close nano editor
Restart the sshd service in order for it to pick up new configuration
sudo service sshd restart
We have now setup out Linux machine for running PowerShell 6 Core and to accept remote PowerShell sessions over OpenSSH.
3. Setting up PowerShell 6 Core on Windows machine
Setting up PowerShell 6 Core on Windows is pretty straight forward, pretty much like any other application on Windows. Navigate to https://github.com/PowerShell/PowerShell#get-powershell in your browser and download the .msi installer for your Windows platform. Upon download, double click on .msi installation package and follow the wizard instructions.
Verify that PowerShell 6 Core is installed by running the following commands in Windows console
cd C:\Program Files\PowerShell\6.0.2 pwsh -V
You should get the PowerShell Core version installed on your Windows machine. Additionally you can update PATH environment variable from Windows UI. You can access environment variables direly from elevated Command Prompt window by executing the following command
rundll32 sysdm.cpl,EditEnvironmentVariables
Or by running the following command Windows command prompt which will append PowerShell 6 Core installation path folder to PATH environemnt varibale
setx PATH "%PATH%;C:\Program Files\PowerShell\6.0.2" /M
Before adding the PowerShell path to PATH Environment Variable, verify that PowerShell Core is installed at that location. Folder may vary depending on the release you installed
4. Setting up OpenSSH on Windows machine
Download OpenSSH binaries for Windows from https://github.com/PowerShell/Win32-OpenSSH/releases. Extract files from downloaded archive on the Windows machine. I picked C:\Program Files\OpenSSH folder. For the consistency with this sample, create same folder on your machine and extract archive to this folder.
Open Windows console as administrator and execute following command
PowerShell -ExecutionPolicy bypass -File "C:\Program Files\OpenSSH\install-sshd.ps1"
You should get the following output from the command above executed
From the elevated command prompt you can run the following command to get you directly to the Windows environment variables window
rundll32 sysdm.cpl,EditEnvironmentVariables
In the System Variables section, locate Path variable and click Edit button
Path list should already contain path to OpenSSH with value %SYSTEMROOT%\System32\OpenSSH\. If this value is not present in the Path list, add the path of OpenSSH installation which is in our case C:\Program Files\OpenSSH.
Open the firewall port for OpenSSH by running the following command from elevated (Run as Administrator) Windows console
netsh advfirewall firewall add rule name=sshd dir=in action=allow protocol=TCP localport=22
Restart sshd service from Control Panel > Administrative Tools > Services of running PowerShell command from elevated Windows console
PowerShell -command "Restart-Service sshd -Force"
5. Connect to remote session from PowerShell 6 Core with OpenSSH
Now when we have PowerShell 6 Core setup on both Windows and Linux host we can try to connect and execute a command for remote session. You can use both Invoke-Command or Enter-Pssession. The command structure for both options is the following
Invoke-Command -Hostname "IP or Hostname" -UserName "Username" -ScriptBlock {PowerShell commands} Enter-Pssession -Hostname "IP or Hostname" -UserName "Username" -ScriptBlock {PowerShell commands}
For and example, let's list the processes on the remote Linux host
Invoke-Command -Hostname 192.168.211.129 -UserName dejan -ScriptBlock {Get-Process}
The output of this command will be the table of all processes currently running on the remote Linux host
References
Disclaimer
Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.
Comments for this article