Copy a key to a Linux or Mac server
Run this in PowerShell on your Windows machine:
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo >> ~/.ssh/authorized_keys && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
You type the account password once. For another port, add -p 2222 after ssh. The same command works in Command Prompt if you replace the first part with type %USERPROFILE%\.ssh\id_ed25519.pub.
Then test it. This refuses to fall back to a password, so it only succeeds if the key works:
ssh -o PasswordAuthentication=no user@server
No key yet? Create one first, as shown in how to generate an SSH key on Windows.
Why this version
Most copies of this command online skip the echo >> part. It adds an empty line first, because an existing authorized_keys may not end in a newline. Without it your key is glued to the end of the last line, and that key and yours both stop working. In our test the login was refused in that case and worked with the empty line, which the server ignores.
Three other things we checked:
- Windows line endings. A key followed by CRLF still worked, with or without a comment, on OpenSSH 9.6.
- UTF-16. A file in UTF-16 does not work: the login was refused. In Windows PowerShell 5.1,
>and>>write UTF-16, so never createauthorized_keyswith them.Add-Contentand the pipe above do not have this problem for a plain key. - Repeating. Running the command twice adds the key twice. That is harmless, but
ssh-copy-idwould have skipped it.
If you have Git Bash or WSL
Those are Unix environments with their own tools. Check whether the real command is there:
command -v ssh-copy-id
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
Remember that WSL has its own home folder, so its ~/.ssh is not your Windows .ssh.
Copy a key to a Windows server
The one-liner fails here, since the default shell is cmd.exe and the file location is different. The simplest way is to work on the server itself and paste the key, as shown in the OpenSSH Server guide.
To do it remotely, Microsoft documents this for a standard user:
$authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ed25519.pub
$remotePowershell = "powershell New-Item -Force -ItemType Directory -Path $env:USERPROFILE\.ssh; Add-Content -Force -Path $env:USERPROFILE\.ssh\authorized_keys -Value '$authorizedKey'"
ssh user@server $remotePowershell
Note that $env:USERPROFILE inside the double quotes is filled in on your machine, before it is sent. It only lands in the right place if the profile path is the same on both, so check the result.
For a member of Administrators, the key goes in a different file with strict permissions:
$authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ed25519.pub
$remotePowershell = "powershell Add-Content -Force -Path $env:ProgramData\ssh\administrators_authorized_keys -Value '$authorizedKey';icacls.exe ""$env:ProgramData\ssh\administrators_authorized_keys"" /inheritance:r /grant ""Administrators:F"" /grant ""SYSTEM:F"""
ssh user@server $remotePowershell
If the login still asks for a password
On Linux, look at the server's log while you try: permissions on the home folder, ~/.ssh and authorized_keys are the usual cause. See Permission denied (publickey). On a Windows server, first check whether the account is an administrator and whether you used the matching file.
Questions
Is there an ssh-copy-id for Windows?
Not in the OpenSSH client that comes with Windows. Git Bash or WSL may have the real command, which you can check with command -v ssh-copy-id. In PowerShell, pipe the public key into ssh instead.
Why does the server still ask for a password after I copied the key?
Usually the permissions on the server: the home folder, ~/.ssh and authorized_keys must not be writable by others. A key saved in UTF-16 or glued to the previous line also fails. Watch the server log while you try.
Where does the public key go on a Windows server?
For a standard user, in .ssh\authorized_keys in the user's profile. For a member of Administrators, in C:\ProgramData\ssh\administrators_authorized_keys, readable only by Administrators and SYSTEM.
Sources
- Key-based authentication in OpenSSH for Windows, Microsoft Learn
- about_Character_Encoding, Microsoft Learn
- ssh-copy-id(1), Debian 13