# Win\_shell + loops + delegate\_to does not work (not at all or as expected)

**URL:** <https://forum.ansible.com/t/win-shell-loops-delegate-to-does-not-work-not-at-all-or-as-expected/11203>\
**Category:** Get Help\
**Tags:** winrm, windows, loop\
**Created:** [November 28, 2024, 10:33am UTC](https://forum.ansible.com/t/win-shell-loops-delegate-to-does-not-work-not-at-all-or-as-expected/11203 "2024-11-28T10:33:39Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![msperl](https://avatars.discourse-cdn.com/v4/letter/m/9e8a1a/32.png) [@msperl](https://forum.ansible.com/u/msperl)\
**Post date:** [November 28, 2024, 10:33am UTC](https://forum.ansible.com/t/win-shell-loops-delegate-to-does-not-work-not-at-all-or-as-expected/11203/1 "2024-11-28T10:33:39Z")

</div>

I am trying to run several win\_shell command to different windows hosts for a single linux server.

The number of iterations we want to run is totally defined by the inventory (i.e group membership).

This unfortunately fails as the kerberos ticket is created for the linux host name and NOT the delegate\_to name.  
Other issues also show in other possible variants.

Code:

```auto
- name: test windows delegate loop
  run_once: true
  ansible.windows.win_shell: hostname
  delegate_to: '{{ item }}'
  loop:
    - windows_host_a
    - windows_host_b
  vars:
   ansible_delegated_vars:
	ansible_pipelining: False
	ansible_user: '{{ hostvars[item | default(inventory_hostname)].ansible_user | default("ansible") }}'
	ansible_password: '{{ hostvars[item | default(inventory_hostname)].ansible_password | default() }}'
	ansible_connection: '{{ hostvars[item | default(inventory_hostname)].ansible_connection | default("winrm") }}'
    ansible_winrm_host: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_host | default(hostvars[item | default(inventory_hostname)].inventory_hostname) | default(item | default(inventory_hostname)) }}'
    remote_addr: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_host | default(hostvars[item | default(inventory_hostname)].inventory_hostname) | default(item | default(inventory_hostname)) }}'
    ansible_winrm_kerberos_delegation: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_kerberos_delegation | default(False) }}'
    ansible_winrm_message_encryption: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_message_encryption | default("always") }}'
    ansible_winrm_send_cbt: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_send_cbt | default(True) }}'
	ansible_winrm_server_cert_validation: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_server_cert_validation | default("ignore") }}'
	ansible_winrm_service: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_service | default("wsman") }}'
	ansible_winrm_transport: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_transport | default("kerberos") }}'
    remote_address: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_host | default(hostvars[item | default(inventory_hostname)].inventory_hostname) | default(item | default(inventory_hostname)) }}'

```

as long as I have the delegate\_to + ansible\_delegated\_vars in there we get in our case:

```auto
<undelegated inventory_hostname> ESTABLISH WINRM CONNECTION FOR USER: ansible@<DOMAIN> on PORT 5986 TO <undelegated inventory_hostname>
creating Kerberos CC at /tmp/tmpv10gaw0w
calling kinit with subprocess for principal ansible@<DOMAIN>
kinit succeeded for principal ansible@<DOMAIN>
<undelegated inventory_hostname> WINRM CONNECT: transport=kerberos endpoint=https://<undelegated inventory_hostname>:5986/wsman
<undelegated inventory_hostname> WINRM CONNECTION ERROR: authGSSClientStep() failed: (('Unspecified GSS failure. Minor code may provide more information', 851968), ('Server not found in Kerberos database', -1765328377))

```

So the kerberos ticket is created for a linux host that is not in the Windows AD.  
Hence the “Server not Found”.

When I just remove the ansible\_delegated\_vars and assign the ansible\_\* directly in vars:

```auto
- name: test windows delegate loop
  run_once: true
  ansible.windows.win_shell: hostname
  delegate_to: '{{ item }}'
  loop:
    - windows_host_a
    - windows_host_b
  vars:
	ansible_pipelining: False
	ansible_user: '{{ hostvars[item | default(inventory_hostname)].ansible_user | default("ansible") }}'
	ansible_password: '{{ hostvars[item | default(inventory_hostname)].ansible_password | default() }}'
	ansible_connection: '{{ hostvars[item | default(inventory_hostname)].ansible_connection | default("winrm") }}'
    ansible_winrm_host: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_host | default(hostvars[item | default(inventory_hostname)].inventory_hostname) | default(item | default(inventory_hostname)) }}'
    remote_addr: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_host | default(hostvars[item | default(inventory_hostname)].inventory_hostname) | default(item | default(inventory_hostname)) }}'
    ansible_winrm_kerberos_delegation: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_kerberos_delegation | default(False) }}'
    ansible_winrm_message_encryption: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_message_encryption | default("always") }}'
    ansible_winrm_send_cbt: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_send_cbt | default(True) }}'
	ansible_winrm_server_cert_validation: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_server_cert_validation | default("ignore") }}'
	ansible_winrm_service: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_service | default("wsman") }}'
	ansible_winrm_transport: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_transport | default("kerberos") }}'
    remote_address: '{{ hostvars[item | default(inventory_hostname)].ansible_winrm_host | default(hostvars[item | default(inventory_hostname)].inventory_hostname) | default(item | default(inventory_hostname)) }}'

```

I get the following:

```auto
<undelegated inventory_hostname> ESTABLISH WINRM CONNECTION FOR USER: ansible on PORT 5986 TO <undelegated inventory_hostname>
<undelegated inventory_hostname> WINRM CONNECT: transport=kerberos endpoint=https://<undelegated inventory_hostname>:5986/wsman
<undelegated inventory_hostname> WINRM CONNECTION ERROR: authGSSClientInit() failed: (('No credentials were supplied, or the credentials were unavailable or inaccessible', 458752), ("Can't find client principal ansible@DOMAIN in cache collection", -1765328243))

```

not even a kerberos ticket is created…

when I run the same but also remove the delegate to (but keep all the ansible\_\* variables in vars):

```auto
<windows_host_a> ESTABLISH WINRM CONNECTION FOR USER: ansible@<DOMAIN> on PORT 5986 TO windows_host_a
creating Kerberos CC at /tmp/tmpd8ypqo_s
calling kinit with subprocess for principal ansible@<DOMAIN>
kinit succeeded for principal ansible@<DOMAIN>
<windows_host_a> WINRM CONNECT: transport=kerberos endpoint=https://weganeu.olymp.ontec.at:5986/wsman
<windows_host_a> WINRM OPEN SHELL: BF3CDFC3-1095-429A-8676-F8CF0033A736

```

and it works in principle.

But there is a snag: it ONLY connects to the windows\_host\_a host for both iterations so the loop is there but not as intended.

As a note: ansible -m win\_ping windows\_host\_a,windows\_host\_b works fine…

As may be obvious: I have already spent lots of time trying to figure this out (especially those vars: tricks as well as the “ansible\_delegated\_vars” have been found out by inspecting the code.

For comparisson: the same works for a linux host without any issues:

```auto
- name: test linux delegate loop
  run_once: true
  shell: hostname
  delegate_to: '{{ item }}'
  loop:
    - linux_host_a
    - linux_host_b

```

So any ideas what I need to do to get loop + delegate work propperly in winrm context?
