Managing Windows hosts with salt-ssh¶
The winshell extension lets salt-ssh manage Windows hosts without installing a minion. Everything runs over OpenSSH: salt-ssh connects to the target, uploads a tiny Python shim, and executes it with a pre-staged Python environment that the extension deploys on first use.
Hint
Despite the roster flag name, no WinRM is involved. The winrm: True flag is a
historical leftover from the original saltwinshell module; it simply tells
salt-ssh to treat the target as a Windows host. The actual transport is plain
SSH (paramiko) plus SCP for file transfers.
How it works¶
salt-ssh connects to the target over SSH using the salt-ssh private key (paramiko) and transfers files with SCP.
It runs
powershell $ENV:PROCESSOR_ARCHITECTUREto determine the target architecture (AMD64orx86).It uploads a per-command Python shim to
C:\saltremote\binand executes it with the deployedpython.exe.On first use the shim reports what is missing and salt-ssh automatically deploys:
salt-thin →
C:\saltremote\thin(salt-thin.tgz)the Salt-Env Python environment →
C:\saltremote\bin(extracted from aSalt-Env-<version>-<arch>-Py3.ziparchive)
Subsequent commands reuse the deployed environment until the shim signals that something (
deployorext_mods) needs to be redeployed.
Master-side prerequisites¶
The salt master (the machine running salt-ssh) needs three things:
1. The extension installed¶
Install the extension into the same Python environment Salt uses - see Installation.
2. The Salt-Env archives¶
Place the Windows Python environment archives on the master at
/extra/salt/saltwinshell/:
/extra/salt/saltwinshell/Salt-Env-3008-AMD64-Py3.zip
/extra/salt/saltwinshell/Salt-Env-3008-x86-Py3.zip
The version in the filename must match
ENV_VERSIONfromsaltext.winshell.env_version(3008for this release).Keep both archives available unless every target is known to be
AMD64; the architecture is detected at connect time and the wrong (or missing) archive causes a configuration error.These archives are intentionally not distributed with the extension - you need to obtain them from your Salt environment (they are the
Salt-Env-<version>-AMD64/x86-Py3.zipzips shipped alongside salt releases).
3. An SSH private key¶
The default key is
/etc/salt/pki/master/ssh/salt-ssh.rsa, auto-generated on first use.It can be overridden with the
ssh_privmaster option or with a per-targetprivroster option.Only key-based authentication is used. The
passwdroster option is ignored for Windows targets - make sure the target accepts the public key.
Roster entries¶
Add each Windows host to your roster (by default /etc/salt/roster):
win2012dev:
host: win2012dev.example.com
user: Administrator
winrm: True
Option |
Required |
Description |
|---|---|---|
|
yes |
Hostname or IP address of the Windows target. |
|
yes |
The Windows account salt-ssh connects as. |
|
yes |
Must be |
|
no |
Path to the SSH private key on the master. Falls back to |
Multiple hosts can share the same settings:
win2012dev:
host: win2012dev.example.com
user: Administrator
winrm: True
win2019:
host: win2019.example.com
user: svc-salt
priv: /etc/salt/pki/master/ssh/windows_key
winrm: True
Target host prerequisites¶
Each Windows host needs the following one-time setup.
1. OpenSSH Server¶
Enable and start the built-in Windows OpenSSH server:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service sshd -StartupType Automatic
Start-Service sshd
Also make sure the Windows firewall allows inbound TCP 22.
2. The master’s public key¶
The key-based connection requires the master’s public key (the .pub file
next to the salt-ssh private key, e.g.
/etc/salt/pki/master/ssh/salt-ssh.rsa.pub) in the target user’s
authorized_keys:
For regular users:
C:\Users\<user>\.ssh\authorized_keysFor accounts in the local Administrators group:
C:\ProgramData\ssh\administrators_authorized_keys(as configured by the Windows OpenSSH defaultsshd_config)
Administrator key files need restrictive ACLs or sshd will refuse to use them:
icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "SYSTEM:F" /grant "BUILTIN\Administrators:F"
3. PowerShell¶
PowerShell must be available - it is used for architecture detection and for
extracting the Python environment archive (via the .NET System.IO.Compression
API, with an Expand-Archive fallback on older systems).
4. Account privileges¶
The connecting account must be able to create C:\saltremote and write to it -
typically a local Administrator account.
Hint
No salt minion is required on the target - this is a fully agentless setup.
Verifying the setup¶
Once the extension is installed on the master, the Salt-Env archives are in place, and the target accepts the key:
salt-ssh 'win2012dev' test.version
salt-ssh 'win2012dev' cmd.run 'hostname'
salt-ssh 'win2012dev' winshell.version
winshell.version reports the installed extension version and the version of
the deployed Salt-Env environment. Expect the first command on a new host to
be slow - it deploys the thin and Python environment archives. Later commands
only transfer the small per-command shim.
Troubleshooting¶
Permission denied when connecting - the public key is not being accepted. Check the
authorized_keyslocation (administrator accounts must useadministrators_authorized_keys) and the file ACLs.Python env ... doesn't exist- the master is missing theSalt-Env-<version>-<arch>-Py3.ziparchive for the target’s architecture, or it is not under/extra/salt/saltwinshell/.First command hangs or times out - deploying the archives can take a while on slow links; subsequent commands are much faster.
SCP send failures - the extension retries each file transfer three times and drops the connection between attempts; a persistently failing transfer aborts with an error naming the file. A truncated file left behind by a failed transfer is never treated as success.
For verbose logs run salt-ssh with
-l debug(or-l traceto see the individual shim commands).