The paradigm of infrastructure automation has traditionally viewed Windows environments through the lens of WinRM (Windows Remote Management) or WMI (Windows Management Instrumentation). However, the evolution of the Windows ecosystem, culminating in the native integration of OpenSSH in Windows Server 2025, has shifted the operational landscape. Integrating Ansible with Windows via SSH allows system architects to leverage a unified transport layer across heterogeneous environments, eliminating the need for separate configuration paths for Linux and Windows targets. This integration is not merely a matter of connectivity but involves a precise alignment of shell types, authentication protocols, and firewall configurations to ensure that Ansible can execute PowerShell modules reliably. By transitioning to SSH, administrators can utilize a single port (TCP 22) for management, simplifying security audits and reducing the overhead associated with the WinRM listener.
The Technical Evolution of SSH on Windows
The transition to using SSH for Windows management represents a significant departure from legacy proprietary protocols. Historically, connecting Ansible to Windows required the complex setup of WinRM, which often involved managing certificates and configuring listeners. Starting with Ansible 2.8, the core team introduced support for SSH connections to Windows, a feature that has matured through subsequent versions like 2.12 and into the current stable releases such as 2.17.7.
In Windows Server 2025, OpenSSH is no longer an optional add-on but is included by default. This architectural decision by Microsoft reduces the manual overhead previously associated with downloading binaries from GitHub or managing manual extractions to directories such as C:\Program Files\OpenSSH. The presence of OpenSSH as a native capability means that the underlying infrastructure for remote command execution is already present, requiring only the administrative activation of the sshd service and the configuration of the default shell.
Comprehensive Installation and Service Configuration
Depending on the version of Windows being utilized, the method of enabling the SSH server varies between native capability deployment and manual binary installation.
Native Installation via PowerShell
For modern iterations of Windows Server, the OpenSSH server is managed as a Windows Capability. The process involves verifying the current state of the feature and then explicitly installing the server and client components.
To verify the installation status, the following cmdlet is employed: Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
If the output indicates that the state is NotPresent for both the OpenSSH.Client and OpenSSH.Server, the components must be installed using the Add-WindowsCapability cmdlet.
The installation process follows these specific commands: - Install the OpenSSH Client: Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 - Install the OpenSSH Server: Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Once the installation is confirmed with a GPath: Online : True and RestartNeeded : False response, the server daemon (sshd) must be operational.
Service Management and Persistence
The sshd service is the core process that listens for incoming SSH connections. By default, this service may be stopped or set to a manual start type, which would result in a failure of the Ansible control node to establish a connection upon reboot.
To ensure the service is active and persists across system restarts, an elevated PowerShell prompt is required to execute the following: - Start the service: Start-Service sshd - Set startup type to automatic: Set-Service -Name sshd -StartupType 'Automatic'
Verification of the service status is performed using the get-service -name sshd command, which confirms that the daemon is running and ready to accept TCP connections on port 22.
Manual Installation for Legacy Systems
In environments where the Windows Capability framework is not utilized, OpenSSH can be installed manually. This involves downloading the latest release of OpenSSH for the specific CPU architecture and extracting the archive to C:\Program Files\OpenSSH. After extraction, an administrator must navigate to that directory via an elevated PowerShell session to perform the initial configuration of the server.
Network Security and Shell Optimization
The ability to connect via SSH is contingent upon the Windows Firewall allowing traffic on the standard SSH port and the server directing that traffic to a compatible shell.
Firewall Configuration
The Windows Firewall, by default, blocks unsolicited inbound traffic. To allow the Ansible control node to communicate with the Windows managed nodes, a specific firewall rule must be created.
The command to establish this rule is: New-NetFirewallRule -DisplayName 'Allow SSH' -Name 'Allow SSH' -Profile Any -LocalPort 22 -Protocol TCP
This rule opens TCP port 22 across all network profiles (Domain, Private, and Public), ensuring that the Ansible control node can reach the sshd service regardless of the network environment.
Defining the Default SSH Shell
A critical technical requirement for Ansible is the use of PowerShell rather than the legacy Command Prompt (cmd.exe). Because Ansible modules for Windows are written to be executed by PowerShell, the SSH server must be configured to launch PowerShell as the default shell for incoming sessions.
This is achieved by modifying the Windows Registry. The specific key required is: New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
By forcing the default shell to PowerShell, Ansible can successfully execute the ansible.windows.win_ping module and other specialized Windows modules without encountering syntax errors resulting from cmd.exe.
Ansible Control Node Configuration
The control node, often an Ubuntu distribution (such as 22.04) running within the Windows Subsystem for Linux (WSL), must be configured to communicate with the Windows targets.
The Inventory Strategy
The inventory file is the central map that tells Ansible which hosts to manage and how to connect to them. A typical setup for a Windows environment involving SQL Servers and a Domain Controller would use a file named hosts_initial.ini.
The inventory is structured as follows:
| Group | Hosts | Purpose |
|---|---|---|
| sqlservers | SQL1, SQL2, SQL3 | SQL Server 2022 hosts |
| domaincontroller | DC1 | Target for Domain Controller configuration |
Global Variables for Windows SSH
Within the [all:vars] section of the inventory, specific parameters must be defined to override the default Linux-centric behavior of Ansible.
- ansible_connection = ssh: This explicitly instructs Ansible to use the SSH transport layer instead of the default WinRM connection.
- ansibleshelltype = powershell: This ensures that the remote shell is treated as PowerShell, allowing the correct execution of Windows-specific modules.
- ansiblesshcommonargs = '-o StrictHostKeyChecking=no': This is a critical setting for the initial connection. Since the Windows host keys will not yet be in the knownhosts file of the control node, Ansible would normally halt the connection for security verification. This argument disables that check, allowing the first connection to proceed without manual intervention.
Authentication Workflows
Ansible can connect to Windows using two primary methods: username/password authentication and key-based (passwordless) authentication.
Phase 1: Initial Username/Password Authentication
The first connection to a Windows node is typically performed using the Administrator account to verify connectivity. This is done using an ad-hoc command and the win_ping module.
The command executed on the control node is: ansible all -i hostsinitial.ini -m ansible.windows.winping -u Administrator --ask-pass
The --ask-pass flag prompts the user for the Administrator password interactively. A successful connection is indicated by four SUCCESS messages (corresponding to the four managed nodes: DC1, SQL1, SQL2, and SQL3).
Phase 2: Implementing Key-Based Authentication
To remove the need for interactive passwords, a public key infrastructure (PKI) is established. This involves generating a key pair on the Ubuntu control node and deploying the public key to the Windows targets.
The key generation process involves three primary steps: 1. Generating the key: ssh-keygen -b 4096 - This creates a 4096-bit RSA key pair, providing a high level of security. - It produces two files: idrsa (the private key, which must remain secure) and idrsa.pub (the public key). 2. Starting the agent: ssh-agent bash - This initiates the SSH agent in the background to manage the keys. 3. Adding the key to the agent: ssh-add ~/.ssh/id_rsa - This loads the private key into the agent for use during authentication.
Deploying the Public Key to Windows
For the Windows server to accept the key-based connection, the contents of the idrsa.pub file from the control node must be placed into the authorizedkeys file on the Windows machine.
The specific path for this file on the Windows host is: .ssh/authorized_keys
Once the public key is added to this folder, the Administrator account can be accessed without a password, enabling fully automated playbook execution.
Operational Verification and Testing
After the configuration of the sshd service, the registry modifications, the firewall rules, and the key-based authentication, the final step is validating the end-to-end connectivity.
Manual SSH Verification
Before running Ansible, a direct SSH attempt from the control node confirms the basic handshake: ssh Administrator@servername
If this connection is successful, it confirms that the network path is open and the credentials/keys are valid.
Ansible Ad-Hoc Testing
The final validation is performed using the Ansible winping module. Using the path to the inventory file, the following command is executed: ansible all -i path/to/inventory/file -m winping
This test confirms that not only is the SSH connection established, but the PowerShell shell is responsive and the Ansible modules are executing correctly on the Windows targets.
Summary of Technical Specifications
The following table summarizes the critical configuration values required for this deployment:
| Component | Required Setting/Value | Purpose |
|---|---|---|
| SSH Port | TCP 22 | Standard communication port |
| SSH Key Size | 4096-bit | Security standard for RSA keys |
| Default Shell | powershell.exe | Required for Ansible module execution |
| Registry Path | HKLM:\SOFTWARE\OpenSSH | Location for shell configuration |
| Connection Type | ssh | Overrides default WinRM |
| Host Key Check | StrictHostKeyChecking=no | Prevents connection failure on first run |
Conclusion
The integration of Ansible with Windows Server 2025 via OpenSSH represents a significant leap in administrative efficiency. By leveraging native OpenSSH capabilities, the requirement for third-party software or cumbersome WinRM configurations is eliminated. The process requires a disciplined approach to three distinct layers: the system layer (installing and starting the sshd service), the network layer (configuring the Windows Firewall for port 22), and the application layer (mapping the SSH session to PowerShell and configuring RSA key-based authentication).
The technical impact of this setup is a streamlined, secure, and scalable management framework. The use of a 4096-bit key ensures that the transport layer is resilient against brute-force attacks, while the use of the ansible.windows.win_ping module provides a reliable method for verifying the health of the connection. This architecture allows a single Ubuntu-based control node to orchestrate complex environments, such as the deployment of SQL Server 2022 hosts and the configuration of Active Directory Domain Controllers, with the same precision and ease typically reserved for Linux environments. The transition to SSH on Windows not only simplifies the connectivity matrix but also aligns Windows administration with modern DevOps practices, ensuring a consistent operational experience across the entire enterprise infrastructure.