--- - name: Максимально быстрая генерация инвентаря hosts: localhost connection: local gather_facts: yes vars: domain: "zag.lan" dns_server: "192.168.1.250" inventory_file: "/tmp/windows_inventory.yml" subnets: - "192.168.0.0/24" - "192.168.1.0/24" - "192.168.2.0/24" - "192.168.3.0/24" - "172.19.8.0/23" - "172.19.10.0/23" - "172.19.24.0/23" - "172.19.26.0/23" - "172.19.40.0/23" - "172.19.42.0/23" - "172.19.56.0/23" - "172.19.58.0/23" tasks: - name: Быстрый поиск активных хостов (nmap) command: "nmap -sn -T5 {{ subnets | join(' ') }} --min-parallelism 100" register: nmap_result changed_when: false - name: Извлечение активных IP set_fact: active_ips: "{{ nmap_result.stdout | regex_findall('Nmap scan report for ([0-9.]+)') }}" - name: DNS резолв только для активных хостов shell: | python3 << 'EOF' import subprocess import concurrent.futures DNS = "{{ dns_server }}" IPS = {{ active_ips | to_json }} def resolve(ip): try: r = subprocess.run(['nslookup', ip, DNS], capture_output=True, text=True, timeout=2) for line in r.stdout.split('\n'): if 'name =' in line: host = line.split('=')[-1].strip().rstrip('.') if host.lower().startswith('pc'): return f"{ip}|{host}" except: pass return None with concurrent.futures.ThreadPoolExecutor(max_workers=50) as ex: for r in filter(None, ex.map(resolve, IPS)): print(r) EOF register: dns_result changed_when: false when: active_ips | length > 0 - name: Формирование списка PC set_fact: pc_hosts: "{{ pc_hosts | default([]) + [{'ip': item.split('|')[0], 'hostname': item.split('|')[1]}] }}" loop: "{{ dns_result.stdout_lines }}" when: - dns_result.stdout_lines is defined - dns_result.stdout_lines | length > 0 - name: Создание инвентаря copy: content: | all: children: windows_pcs: hosts: {% for h in pc_hosts | default([]) | sort(attribute='hostname') %} {{ h.hostname.split('.')[0] }}: ansible_host: {{ h.ip }} {% endfor %} vars: ansible_connection: winrm ansible_winrm_transport: ntlm ansible_winrm_server_cert_validation: ignore ansible_port: 5985 dest: "{{ inventory_file }}" - name: Результат debug: msg: "Найдено {{ pc_hosts | default([]) | length }} PC хостов → {{ inventory_file }}"