- ssh-config-key-management: add Windows OpenSSH admin user key auth section (administrators_authorized_keys, BOM-free writing, ACL requirements) - windows-openssh-wsl-default-shell: add bash.exe as recommended fix (Option 1), demote PowerShell to Option 2, add shell-not-found diagnostic tip - windows-sshd-stops-after-reboot: fix stale wsl.exe reference to bash.exe - index/README: update Recently Updated table and article descriptions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
3.8 KiB
Markdown
94 lines
3.8 KiB
Markdown
---
|
|
title: "Windows OpenSSH: WSL as Default Shell Breaks Remote Commands"
|
|
domain: troubleshooting
|
|
category: networking
|
|
tags:
|
|
- windows
|
|
- openssh
|
|
- wsl
|
|
- ssh
|
|
- majorrig
|
|
- powershell
|
|
status: published
|
|
created: 2026-04-03
|
|
updated: 2026-04-07T21:55
|
|
---
|
|
|
|
# Windows OpenSSH: WSL as Default Shell Breaks Remote Commands
|
|
|
|
## Problem
|
|
|
|
SSH remote commands fail with:
|
|
|
|
```
|
|
Invalid command line argument: -c
|
|
Please use 'wsl.exe --help' to get a list of supported arguments.
|
|
```
|
|
|
|
This happens on **every** remote command — `ssh-copy-id`, `ssh user@host "command"`, `scp`, etc. Interactive SSH (no command) may still work if it drops into WSL.
|
|
|
|
## Cause
|
|
|
|
Windows OpenSSH's default shell is set to `C:\Windows\System32\wsl.exe`. When SSH executes a remote command, it invokes:
|
|
|
|
```
|
|
<default_shell> -c "<command>"
|
|
```
|
|
|
|
But `wsl.exe` does not accept the `-c` flag. It expects `-e` for command execution, or no flags for an interactive session. Since OpenSSH hardcodes `-c`, every remote command fails.
|
|
|
|
## Fix — Option 1: Use `bash.exe` (Recommended)
|
|
|
|
`bash.exe` is a WSL shim that **does** accept the `-c` flag. This gives you a Linux-first SSH experience where both interactive sessions and remote commands work natively.
|
|
|
|
```powershell
|
|
# Find the actual path to bash.exe (it varies by install)
|
|
Get-Command bash.exe | Select-Object Source
|
|
|
|
# Set it as the default shell (elevated PowerShell)
|
|
Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Users\<username>\AppData\Local\Microsoft\WindowsApps\bash.exe"
|
|
Restart-Service sshd
|
|
```
|
|
|
|
> **Note:** `bash.exe` may not be at `C:\Windows\System32\bash.exe` on all installs. Always verify the path with `Get-Command` first — the Windows Store WSL install places it under `AppData\Local\Microsoft\WindowsApps\`.
|
|
|
|
### After the fix (bash.exe)
|
|
|
|
- Interactive SSH sessions land directly in your WSL distro
|
|
- Remote SSH commands execute in WSL's bash — Linux commands work natively
|
|
- `ssh user@host "uname -s"` returns `Linux`
|
|
|
|
## Fix — Option 2: Revert to PowerShell
|
|
|
|
If you need Windows-native command execution over SSH (e.g., for Windows-targeted Ansible or remote PowerShell administration), set the default shell back to PowerShell:
|
|
|
|
```powershell
|
|
Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
|
|
Restart-Service sshd
|
|
```
|
|
|
|
### After the fix (PowerShell)
|
|
|
|
- Remote SSH commands execute via PowerShell
|
|
- To run Linux commands, prefix with `wsl`:
|
|
```bash
|
|
ssh user@host "wsl bash -c 'cd /mnt/d/project && git pull'"
|
|
```
|
|
- Interactive SSH sessions land in PowerShell (type `wsl` to enter Linux)
|
|
- `ssh-copy-id` still won't work for WSL's `authorized_keys` — Windows OpenSSH reads from `C:\Users\<user>\.ssh\authorized_keys`, not the WSL home directory
|
|
|
|
## Key Notes
|
|
|
|
- This registry key (`HKLM:\SOFTWARE\OpenSSH\DefaultShell`) is the **only** supported way to change the OpenSSH default shell on Windows
|
|
- The change persists across reboots and Windows Updates
|
|
- `wsl.exe` does **not** support `-c` — never use it as the default shell
|
|
- `bash.exe` **does** support `-c` — use it for a Linux-first SSH experience
|
|
- The path to `bash.exe` varies by install method — always verify with `Get-Command bash.exe`
|
|
- Tools like Ansible, `scp`, `rsync`, and `ssh-copy-id` all depend on `-c` working
|
|
- If the shell path in the registry doesn't exist on disk, sshd will reject the user entirely with `User <name> not allowed because shell <path> does not exist` — check `Get-WinEvent -LogName OpenSSH/Operational` to diagnose
|
|
|
|
## Related
|
|
|
|
- [Windows OpenSSH Server (sshd) Stops After Reboot](windows-sshd-stops-after-reboot.md) — sshd service startup issues
|
|
- [Microsoft Docs: OpenSSH DefaultShell](https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh-server-configuration#configuring-the-default-shell-for-openssh-in-windows)
|