Setup SSH Client and Server on Windows


Windows now has a built-in ssh client and a server, adapted from OpenSSH. They are available starting in Server 2019 and the corresponding Windows 10 1809. Older Windows 10 versions had beta versions available, and you also have been able to install OpenSSH separately for a while.

Read first

Many of these commands require administrator access. Commands that change settings are assumed to be run in an administrator Powershell.

I assume that you are coming into this with at least a little experience with OpenSSH on other platforms, if you do not then I would recommend doing some background reading first.

Enable the features

You can check if the server and client are enabled by running this-
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'

If they are not enabled you can install the features by running these commands.
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~

These can also be managed via GUI by going to Settings–>Apps & Features–>Optional Features.

Use the client

Once you have the SSH client feature enabled, it is ready to use. It can be run with the standard ssh command, both in PowerShell and CMD.

The directory to put private keys and whatnot is the same as on other platforms, ie in .ssh under your user directory. You can get to it via %userprofile%\.ssh (explorer.exe, cmd) or $env:USERPROFILE\.ssh (PowerShell). The files are in the same format as on other platforms, so you can just copy and paste your private key into id_rsa or whatever. known_hosts is also here.

Setup the server

Setting up the SSH server is a bit more complex.

First, you need to open up the firewall so people can connect.
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH SSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

Next, you need to start the service and set it to start at boot up.
Set-Service -Name sshd -StartupType Automatic -Status Running

Hopefully, you should be able to SSH into the machine now via password.

It is much much more secure to use pubkey authentication rather than passwords. I would strongly suggest setting it up and disabling password authentication if you intend to keep the server running.

Setup pubkey authentication

The authorized keys file is in the .ssh directory. $env:USERPROFILE\.ssh\authorized_keys Add public keys, one key per line, to this file so you can log in with the associated private key from another machine.

One thing to note is that by default, all administrators have a common authorized key file for public keys. It is located here: $env:ProgramData\ssh\administrators_authorized_keys. It can be changed by editing $env:ProgramData\ssh\sshd_config and commenting out or removing the following lines at the bottom of the file.

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

This will make the administrators authorized keys move back to the individual key files located in their .ssh directories.

You can add keys like this for individual authorized_key files, running as the user, you will have to change permissions if you are not running as the user.

$authorizedKeyFilePath = "$env:USERPROFILE\.ssh\authorized_keys"
$authorizedKeyFileData = 'ssh-rsa bla bla bla add your public key here'
$authorizedKeyFileData | add-Content $authorizedKeyFilePath

For administrators group keys.
This has extra permission changes because the server requires restricted permissions before it will use the file.

$authorizedKeyFilePath = "$env:ProgramData\ssh\administrators_authorized_keys"
$authorizedKeyFileData = 'ssh-rsa bla bla bla add your public key here'
$authorizedKeyFileData | add-Content $authorizedKeyFilePath
icacls.exe $authorizedKeyFilePath /remove “NT AUTHORITY\Authenticated Users”
icacls.exe $authorizedKeyFilePath /inheritance:r
Get-Acl “$env:ProgramData\ssh\ssh_host_dsa_key” | Set-Acl $authorizedKeyFilePath

Finally, you need to restart the service to make sure the config changes take effect.
Restart-Service -Name sshd

Once you have pubkey authentication working you should disable password login. Edit $env:ProgramData\ssh\sshd_config and uncomment and change PasswordAuthentication to no. Then restart the sshd again.


For the SFTP client, it looks like it just works out of the box, just like the ssh client.

The SFTP server is started as part of the sshd service, so it also should just work once you have the ssh sever setup.


There are also other tools available, I have not played around with them too much yet.


Liked and bookmarked :smiley: Thank you for sharing the information!

1 Like