Intermediate 7 min · 2026-06-21

Ansible Windows Automation: WinRM CredSSP Pitfall with Double-Hop & Fix

Master Ansible Windows automation with WinRM configuration, Kerberos/NTLM/CredSSP auth, win_* modules, and PowerShell scripts.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Production
production tested
June 21, 2026
last updated
1,596
articles · all by Naren
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

Use ansible_connection:winrm and set ansible_winrm_transport to credssp for double-hop scenarios. Configure WinRM on Windows hosts with Enable-PSRemoting and Set-Item WSMan:\localhost\Client\TrustedHosts. Prefer win_shell over win_command when you need PowerShell-specific features like pipelines or object manipulation. For Kerberos auth, ensure SPN is set and time sync within 5 minutes; use klist to verify tickets. CredSSP requires Group Policy enablement and the credentialssp feature on the host. Always use ansible_winrm_server_cert_validation: ignore for self-signed certs in production labs. win_copy uses SMB; ensure proper firewall rules for port 445 and 5986 (HTTPS). Troubleshoot with ansible -m win_ping -vvvv to see WinRM transport details.

✦ Definition~90s read
What is Ansible Windows Automation?

Ansible Windows automation is the practice of managing Windows hosts using Ansible's winrm connection plugin instead of the default SSH. It leverages the Windows Remote Management (WinRM) service, which implements the WS-Management protocol. On the control node, you need pywinrm (pip install pywinrm) and optionally requests-credssp for CredSSP support.

Imagine you're a remote control operator trying to fix a computer in another building.

The ansible_connection: winrm variable tells Ansible to use WinRM, and you must specify ansible_winrm_transport (e.g., credssp, kerberos, ntlm). Ansible provides a suite of win_* modules (win_service, win_package, win_copy, win_command, win_shell) that map to Windows-native operations.

The core problem it solves is enabling idempotent, agentless configuration management for Windows environments that lack SSH.

Plain-English First

Imagine you're a remote control operator trying to fix a computer in another building. The remote control app (Ansible) talks to a helper program (WinRM) on that computer. But if you need the helper to then access a file server in a third building, the helper can't pass your credentials — that's the 'double-hop' problem. CredSSP is like giving the helper a temporary badge that lets it go to the third building on your behalf. NTLM is like a simple password check, Kerberos is like a secure ticket system, and each has its own rules for when it can pass credentials.

I still remember the outage. We had 200 Windows servers that needed a hotfix deployed via Ansible. The playbook worked perfectly on the first 50, then suddenly failed with 'WinRM transport failed' on a cluster of servers in a different domain. The error message was cryptic: 'The WinRM client cannot process the request because the server name is not in the trusted hosts list.' We had set TrustedHosts, but the issue was deeper — it was a Kerberos double-hop problem. That night, I learned the hard way that Windows automation with Ansible is not just about installing pywinrm and running a playbook. It's about understanding WinRM authentication protocols, Group Policy settings, and the subtle differences between win_shell and win_command. This article covers everything I wish I knew then.

1. WinRM Configuration on Windows Hosts

Before Ansible can manage a Windows host, you need to configure WinRM. The quickest way is to run Enable-PSRemoting -Force in an elevated PowerShell. This starts the WinRM service, sets it to auto-start, and creates HTTP and HTTPS listeners. However, for production, you need to secure it.

HTTPS Listener with Self-Signed Cert: ``powershell $cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName $env:COMPUTERNAME -FriendlyName 'WinRM HTTPS' New-WSManInstance -ResourceURI winrm/config/Listener -SelectorSet @{Address='*';Transport='HTTPS'} -ValueSet @{CertificateThumbprint=$cert.Thumbprint} ``

Firewall rules: ``powershell New-NetFirewallRule -DisplayName 'WinRM HTTP' -Direction Inbound -Protocol TCP -LocalPort 5985 -Action Allow New-NetFirewallRule -DisplayName 'WinRM HTTPS' -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow ``

TrustedHosts: For non-domain or cross-domain, set TrustedHosts to allow connections: ``powershell Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force ``

Ansible Inventory for Windows: ``yaml [windows] server1 ansible_host=192.168.1.10 ansible_user=Administrator ansible_password=Passw0rd ansible_connection=winrm ansible_winrm_server_cert_validation=ignore ``

Production insight: I once spent hours debugging a connection issue only to find the WinRM service was set to manual start after a Windows update. Always verify with Get-Service WinRM.

Security Note
Never use ansible_password in plaintext in inventory files. Use ansible-vault or environment variables (ANSIBLE_NET_PASSWORD).
Production Insight
In a production environment, we had a group policy that disabled WinRM over HTTP. We had to use HTTPS only. Make sure your Group Policy allows WinRM if you see connection timeouts.
Key Takeaway
Always verify WinRM listener and firewall rules before blaming Ansible.

2. WinRM Authentication Protocols: NTLM, Kerberos, CredSSP

Ansible supports three main authentication transports: ntlm, kerberos, and credssp. Each has trade-offs.

NTLM: Default, works for workgroup and domain. Simple, but no double-hop. Use ansible_winrm_transport: ntlm.

Kerberos: Requires domain-joined hosts, time sync, and proper SPN. Set ansible_winrm_transport: kerberos. You need python-gssapi or pywinrm[kerberos] on the control node. Verify with klist get HTTP/target.domain.com.

CredSSP: Enables double-hop delegation. Set ansible_winrm_transport: credssp. On the target, run: ``powershell Enable-WSManCredSSP -Role Server -Force ` On the control node, install pip install pywinrm[credssp]`.

Choosing the right one: - Same domain, no double-hop: Kerberos (fastest) - Workgroup or cross-domain: NTLM - Need to access network shares: CredSSP

Production insight: We once had Kerberos fail because the DNS suffix was missing. Always use FQDN in ansible_host for Kerberos to work.

Kerberos Debugging
If Kerberos fails, check /etc/krb5.conf and ensure [libdefaults] dns_lookup_kdc = true. Also, the Windows host must have an SPN for HTTP/hostname.
Production Insight
When we switched from NTLM to Kerberos, we saw a 30% performance improvement because Kerberos uses fewer round trips.
Key Takeaway
Match the authentication protocol to your network topology and credential delegation needs.

3. The ansible_connection: winrm Plugin Deep Dive

The winrm connection plugin is what makes Ansible talk to Windows. Key variables:

  • ansible_winrm_transport: ntlm, kerberos, credssp, basic
  • ansible_winrm_port: 5985 (HTTP) or 5986 (HTTPS)
  • ansible_winrm_server_cert_validation: ignore or validate (default: validate)
  • ansible_winrm_operation_timeout_sec: default 60
  • ansible_winrm_read_timeout_sec: default 60
  • ansible_winrm_pipeline_timeout_sec: default 60

Example inventory with advanced settings: ``yaml [windows:vars] ansible_connection=winrm ansible_winrm_transport=credssp ansible_winrm_port=5986 ansible_winrm_server_cert_validation=ignore ansible_winrm_operation_timeout_sec=120 ansible_winrm_read_timeout_sec=120 ansible_winrm_pipeline_timeout_sec=120 ``

Why timeouts matter: Long-running PowerShell scripts may timeout. For example, a win_shell that runs a 5-minute script needs pipeline_timeout > 300.

Production insight: We had a deployment that kept failing with 'WinRM operation timeout' because the default 60 seconds wasn't enough for a large package installation. Bumping to 300 fixed it.

Connection Testing
Always test with ansible target -m win_ping -vvvv to see which transport and port are being used.
Production Insight
Once, a misconfigured proxy caused WinRM to fail. We had to set ansible_winrm_proxy to bypass.
Key Takeaway
Tune timeouts based on your playbook's longest running task.

4. Using win_service for Service Management

The win_service module manages Windows services. Common parameters: - name: service name (e.g., Spooler) - state: started, stopped, restarted - start_mode: auto, manual, disabled

Example playbook: ``yaml - name: Ensure print spooler is running and set to auto win_service: name: Spooler state: started start_mode: auto ``

Production gotcha: Service names are case-insensitive but must match exactly. Use Get-Service to verify.

Idempotency: win_service is idempotent; it will only change state if needed.

Restart with dependencies: ``yaml - name: Restart service and its dependencies win_service: name: W3Svc state: restarted dependencies: - WAS ``

Production insight: We once tried to stop a service that was already stopped, and win_service reported 'changed' because the start_mode was different. Always check the module's return values.

Service Recovery
win_service does not manage service recovery actions. Use win_shell with sc.exe for that.
Production Insight
During a critical patch, we needed to stop IIS, apply updates, and restart. win_service with state: restarted worked perfectly.
Key Takeaway
Use win_service for simple service state management; for complex recovery, use win_shell.

5. Installing Software with win_package

win_package installs or uninstalls software using MSI or EXE. Key parameters: - path: path to installer - product_id: GUID for idempotency (required for MSI) - state: present or absent - arguments: additional CLI arguments

Example: ``yaml - name: Install 7-Zip win_package: path: '\\fileserver\share\7z1900-x64.msi' product_id: '{23170F69-40C1-2702-1900-000001000000}' state: present ``

Double-hop issue: If the installer is on a network share, use CredSSP or copy it locally first.

Getting product_id: ``powershell Get-WmiObject Win32_Product | Select-Object Name, IdentifyingNumber ``

Production insight: We once had an MSI that required a reboot. win_package doesn't handle reboots; you need to use win_reboot module after installation.

Logging Installations
Add /L*v C:\install.log to arguments for MSI installations to debug failures.
Production Insight
A customer's installer required a specific order of arguments. We had to use arguments: '/S /D=C:\Program Files\App' to get silent install.
Key Takeaway
Always test win_package with a local path first to avoid double-hop issues.

6. File Transfer with win_copy

win_copy copies files from the control node to the Windows host (or between Windows hosts if using remote_src). Key parameters: - src: local path - dest: remote path - remote_src: yes if src is on the remote host

Example: ``yaml - name: Copy configuration file win_copy: src: ./app.config dest: C:\Program Files\App\app.config ``

Performance: win_copy uses SMB under the hood. For large files, consider using win_get_url or a file server.

Production gotcha: The destination folder must exist. Use win_file to create it first.

Copy from network share (requires CredSSP): ``yaml - name: Copy from share win_copy: src: '\\fileserver\share\file.txt' dest: C:\temp\file.txt remote_src: yes ``

Production insight: We had a 2GB file that timed out. We split it into chunks and used multiple win_copy tasks.

Checksum Verification
Use checksum parameter to verify file integrity after copy.
Production Insight
One team used win_copy with a UNC path without CredSSP and got 'Access Denied'. They spent hours on permissions before realizing it was a double-hop issue.
Key Takeaway
For network shares, either use CredSSP or copy locally first.

7. Running Commands: win_command vs win_shell

Both modules execute commands, but they differ in how they process output.

win_command: Runs a command via cmd.exe. Does not support PowerShell pipelines. Best for simple executables. ``yaml - name: Run ipconfig win_command: ipconfig ``

win_shell: Runs via PowerShell. Supports pipelines, variables, and complex scripts. ``yaml - name: Get services with status win_shell: Get-Service | Where-Object {$_.Status -eq 'Running'} | Select-Object Name ``

Key differences: - win_command returns stdout as string; win_shell returns stdout as string but can also return structured data if you use ConvertTo-Json. - win_shell has a executable parameter to choose the shell (e.g., powershell.exe, cmd.exe). - win_command is faster for simple commands.

Production insight: We used win_command to run a legacy batch file that failed because it needed PowerShell. Switching to win_shell with executable: cmd.exe fixed it.

Output Truncation
Both modules may truncate output if it's too large. Use win_shell with | Out-String -Width 4096 to avoid.
Production Insight
A playbook using win_command to run a PowerShell script failed silently. We switched to win_shell and got the actual error.
Key Takeaway
Use win_command for simple executables, win_shell for anything involving PowerShell.

8. PowerShell Scripts via win_shell

For complex automation, write PowerShell scripts and execute them with win_shell. Best practices:

  • Use executable: powershell.exe explicitly.
  • Set ansible_winrm_pipeline_timeout_sec high enough.
  • Use $ErrorActionPreference = 'Stop' to catch errors.
  • Return data as JSON for easy parsing.

Example playbook with inline script: ```yaml - name: Run custom script win_shell: | $ErrorActionPreference = 'Stop' $result = Get-Service | Select-Object Name, Status ConvertTo-Json $result args: executable: powershell.exe register: script_output

  • debug:
  • var: script_output.stdout
  • ```

External script file: ``yaml - name: Run script from file win_shell: | C:\scripts\deploy.ps1 -Param1 value1 args: executable: powershell.exe ``

Production insight: We had a script that took 10 minutes. The default timeout caused failures. We set ansible_winrm_pipeline_timeout_sec=900.

Script Paths
Use forward slashes or escaped backslashes in paths: 'C:/scripts/script.ps1' or 'C:\scripts\script.ps1'.
Production Insight
A script that used Write-Host returned nothing because Write-Host goes to information stream. We changed to Write-Output.
Key Takeaway
Always set ErrorActionPreference and return data as JSON for reliable automation.

9. Configuring Windows Hosts for Ansible at Scale

For large-scale deployment, automate the WinRM configuration using Group Policy or DSC.

Group Policy settings: - Computer Configuration -> Administrative Templates -> Windows Components -> Windows Remote Management (WinRM) -> WinRM Service - Allow remote server management through WinRM: Enabled - Allow unencrypted traffic: Disabled (use HTTPS) - Windows Firewall: Allow inbound WinRM ports

PowerShell DSC for WinRM: ``powershell Configuration WinRMConfig { Node localhost { Script EnableWinRM { SetScript = { Enable-PSRemoting -Force Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force } TestScript = { (Get-Service WinRM).Status -eq 'Running' } GetScript = { @{Result = 'Check WinRM'} } } } } ``

Ansible playbook to bootstrap Windows hosts: ``yaml - hosts: all gather_facts: no tasks: - name: Enable WinRM win_shell: Enable-PSRemoting -Force - name: Set TrustedHosts win_shell: Set-Item WSMan:\localhost\Client\TrustedHosts -Value '' -Force - name: Create HTTPS listener win_shell: | $cert = New-SelfSignedCertificate -DnsName $env:COMPUTERNAME -CertStoreLocation Cert:\LocalMachine\My New-WSManInstance -ResourceURI winrm/config/Listener -SelectorSet @{Address='';Transport='HTTPS'} -ValueSet @{CertificateThumbprint=$cert.Thumbprint} ``

Production insight: We used Ansible to bootstrap itself: first run with NTLM over HTTP, then switch to Kerberos over HTTPS.

Domain vs Workgroup
For domain-joined hosts, use Kerberos. For workgroup, use NTLM or CredSSP.
Production Insight
We had a script that used Write-Host returned nothing because Write-Host goes to information stream. We changed to Write-Output.
Key Takeaway
Automate WinRM setup with Group Policy or Ansible itself for consistent configuration.

10. Common WinRM Pitfalls and How to Avoid Them

1. WinRM service not running: ``powershell Get-Service WinRM | Start-Service Set-Service WinRM -StartupType Automatic ``

2. Firewall blocking ports: Check with Test-NetConnection -ComputerName target -Port 5986.

3. Certificate validation failure: Set ansible_winrm_server_cert_validation: ignore for self-signed certs.

4. Authentication failure due to time skew: Kerberos requires time within 5 minutes. Use NTP.

5. Double-hop access denied: Use CredSSP or copy files locally first.

6. Module not found (e.g., win_package): Ensure you have the latest ansible.windows collection: ansible-galaxy collection install ansible.windows.

7. PowerShell execution policy: Set to RemoteSigned: ``powershell Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Force ``

Production insight: We once had a host where WinRM was configured but the user account was locked out. Always check account status.

HTTPS vs HTTP
Always use HTTPS in production. HTTP sends credentials in plaintext for basic auth.
Production Insight
A junior engineer set TrustedHosts to a specific IP instead of '*' and then wondered why connections from other IPs failed.
Key Takeaway
Systematically check service, firewall, authentication, and time sync when troubleshooting.

11. Advanced: Using win_shell with PSSession for Complex Tasks

For tasks that require multiple commands in a single session (e.g., changing directory, setting variables), use a PSSession within win_shell.

Example: ``yaml - name: Run multi-step task win_shell: | $session = New-PSSession -ComputerName localhost Invoke-Command -Session $session -ScriptBlock { Set-Location C:\Deploy .\deploy.ps1 } Remove-PSSession $session ``

When to use: When you need to preserve state between commands (e.g., importing a module once, then using it).

Performance: Creating a PSSession adds overhead. Only use when necessary.

Production insight: We used this to run a script that required a specific working directory and environment variables.

PSSession Limits
WinRM has a default MaxShellsPerUser limit. Increase with: Set-Item WSMan:\localhost\Shell\MaxShellsPerUser -Value 100
Production Insight
We had to run a legacy script that created many temporary files. Using a PSSession kept the environment clean.
Key Takeaway
Use PSSession for multi-step tasks that share state, but be aware of performance and limits.

12. Monitoring and Logging Ansible Windows Automation

Enable detailed logging for troubleshooting.

Ansible logging: ``bash ANSIBLE_LOG_PATH=/var/log/ansible.log ansible-playbook playbook.yml -vvvv ``

WinRM logging on Windows: ``powershell Set-Item WSMan:\localhost\Client\MaxEnvelopeSizekb -Value 2048 Enable-WSManTrace ``

Collect WinRM logs: ``powershell Get-WinEvent -LogName Microsoft-Windows-WinRM/Operational | Select-Object -First 10 ``

Integration with monitoring: Use win_shell to send custom metrics to your monitoring system.

Production insight: We set up a centralized log collector to capture all Ansible runs and WinRM errors. This helped us identify a pattern of failures related to memory pressure.

Log Retention
WinRM logs can grow quickly. Set a max size: wevtutil set-log Microsoft-Windows-WinRM/Operational /ms:20971520
Production Insight
After enabling verbose logging, we discovered that a failing task was due to a missing PowerShell module, not a WinRM issue.
Key Takeaway
Log everything. It's the only way to debug complex Windows automation issues.
● Production incidentPOST-MORTEMseverity: high

The Double-Hop CredSSP Nightmare

Symptom
win_copy module failed with 'Access denied' or 'The network path was not found' when the source was a UNC path.
Assumption
The team assumed it was a firewall issue or permission problem on the share.
Root cause
WinRM by default (NTLM/Kerberos without delegation) cannot forward credentials to a second hop (the file server).
Fix
Changed ansible_winrm_transport to credssp and enabled CredSSP on both the control node and the target hosts via Group Policy (Allow delegating fresh credentials) and the CredSSP Windows feature.
Key lesson
  • Always test file copy from local paths first.
  • If you need network shares, use CredSSP or use win_copy with local path and then copy from share via PowerShell (e.g., Copy-Item with -Credential).
Production debug guideSymptom → Root cause → Fix4 entries
Symptom · 01
ansible -m win_ping fails with 'winrm transport failed'
Fix
Check connectivity: Test-WSMan on target. Ensure WinRM service is running and firewall allows 5985/5986. Verify ansible_user and ansible_password are correct.
Symptom · 02
win_copy fails with 'Access denied' for UNC path
Fix
Switch to CredSSP transport. Enable CredSSP on target: Enable-WSManCredSSP -Role Server -Force. On control node: set ansible_winrm_transport=credssp.
Symptom · 03
Kerberos auth fails with 'kerberos: authGSSClientStep failed'
Fix
Check time sync (ntpdate). Verify SPN exists: setspn -Q HTTP/hostname. Ensure /etc/krb5.conf is correct. Run klist to see tickets.
Symptom · 04
win_shell script returns empty stdout but no error
Fix
Use win_shell with executable: powershell.exe and set ansible_winrm_pipeline_timeout_sec to a higher value. Check if script uses Write-Output vs Write-Host.
★ Ansible Windows Automation Quick Referenceprint this for your desk
WinRM connection refused
Immediate action
Check firewall and WinRM listener
Commands
Test-WSMan -ComputerName target -Credential $cred
Get-ChildItem WSMan:\localhost\Listener
Fix now
Enable-PSRemoting -Force; New-NetFirewallRule -DisplayName 'WinRM HTTPS' -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow
Double-hop access denied+
Immediate action
Switch to CredSSP
Commands
Enable-WSManCredSSP -Role Server -Force
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force
Fix now
Set ansible_winrm_transport=credssp in inventory
Kerberos auth fails+
Immediate action
Check time and SPN
Commands
klist get HTTP/target.domain.com
setspn -L target
Fix now
ntpdate time.server; setspn -A HTTP/target target
win_shell script returns nothing+
Immediate action
Increase timeout and use Write-Output
Commands
ansible target -m win_shell -a 'Write-Output test' -vvvv
Fix now
Set ansible_winrm_pipeline_timeout_sec=120
win_package fails to install+
Immediate action
Check if installer path is accessible
Commands
ansible target -m win_stat -a 'path=C:\installer.msi'
Fix now
Use win_copy to copy installer locally first, then run win_package with local path
WinRM Authentication Protocols Comparison
ProtocolDouble-hopDomain RequiredPerformanceUse Case
NTLMNoNoMediumWorkgroup or simple cross-domain
KerberosNo (without delegation)YesFastSame domain, no delegation
CredSSPYesNo (but easier with domain)SlowerDouble-hop needed
BasicNoNoFastOnly over HTTPS, not recommended

Key takeaways

1
WinRM must be configured on the target
Enable-PSRemoting, TrustedHosts, firewall, and HTTPS listener.
2
Choose authentication
NTLM for workgroup, Kerberos for domain, CredSSP for double-hop.
3
Increase timeouts for long-running tasks
ansible_winrm_operation_timeout_sec, ansible_winrm_read_timeout_sec, ansible_winrm_pipeline_timeout_sec.
4
Use win_shell for PowerShell scripts and win_command for simple executables.
5
For network shares with win_copy, use CredSSP or copy locally first to avoid double-hop.
6
Always use HTTPS in production and set ansible_winrm_server_cert_validation=ignore for self-signed certs.
7
Install pywinrm on control node
pip install pywinrm[credssp].
8
Log everything with -vvvv and centralized logging for troubleshooting.

Common mistakes to avoid

8 patterns
×

Using win_command for PowerShell scripts

Symptom
Script fails or output is truncated
Fix
Use win_shell with executable: powershell.exe
×

Not setting TrustedHosts

Symptom
WinRM transport failed: server not in trusted hosts list
Fix
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force
×

Using default timeouts for long-running tasks

Symptom
WinRM operation timeout
Fix
Increase ansible_winrm_operation_timeout_sec and ansible_winrm_read_timeout_sec
×

Assuming win_copy works with UNC paths without CredSSP

Symptom
Access denied on network share
Fix
Use CredSSP transport or copy locally first
×

Not enabling CredSSP on target for double-hop

Symptom
win_copy from share fails
Fix
Enable-WSManCredSSP -Role Server -Force
×

Using HTTP with basic auth in production

Symptom
Credentials sent in plaintext
Fix
Use HTTPS and Kerberos or NTLM
×

Forgetting to install pywinrm on control node

Symptom
Module not found error
Fix
pip install pywinrm[credssp]
×

Not using FQDN for Kerberos

Symptom
Kerberos auth fails
Fix
Use ansible_host: target.domain.com
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
What is the double-hop problem in WinRM and how do you solve it with Ans...
Q02SENIOR
What is the difference between win_command and win_shell in Ansible?
Q03SENIOR
How do you configure a Windows host for Ansible management?
Q04SENIOR
What are the key parameters for the win_package module and how do you fi...
Q05SENIOR
Explain the difference between NTLM, Kerberos, and CredSSP in WinRM.
Q06SENIOR
How do you troubleshoot a failed win_ping?
Q07JUNIOR
What is the purpose of ansible_winrm_pipeline_timeout_sec?
Q08SENIOR
How do you handle reboots in Ansible Windows automation?
Q01 of 08SENIOR

What is the double-hop problem in WinRM and how do you solve it with Ansible?

ANSWER
The double-hop problem occurs when you connect to a Windows host via WinRM and then try to access a network resource from that host. WinRM cannot delegate credentials to the second hop by default. The solution is to use CredSSP authentication (ansible_winrm_transport: credssp) and enable CredSSP on the target with Enable-WSManCredSSP -Role Server.
FAQ · 8 QUESTIONS

Frequently Asked Questions

01
What is the double-hop problem?
02
How do I find the product_id for win_package?
03
Why does win_copy fail with 'Access denied' on a network share?
04
What is the difference between win_command and win_shell?
05
How do I increase the timeout for a long-running PowerShell script?
06
Do I need to install anything on the Windows host for Ansible?
07
How do I test WinRM connectivity from Ansible?
08
Can I use SSH for Windows automation?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Verified
production tested
June 21, 2026
last updated
1,596
articles · all by Naren
🔥

That's Ansible. Mark it forged?

7 min read · try the examples if you haven't

Previous
Ansible Linting and Testing with Molecule
22 / 23 · Ansible
Next
Ansible Network Automation