--- - name: Генерация инвентаря Windows PC по DNS hosts: localhost connection: local gather_facts: yes vars: domain: "zag.lan" dns_servers: - "192.168.1.250" - "192.168.1.254" 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: Генерация списка всех IP shell: | python3 << 'EOF' import ipaddress subnets = {{ subnets | to_json }} for subnet in subnets: network = ipaddress.ip_network(subnet) for ip in network.hosts(): print(ip) EOF register: all_ips changed_when: false - name: Парсинг IP адресов set_fact: ip_list: "{{ all_ips.stdout_lines }}" - name: Информация о сканировании debug: msg: "Будет проверено {{ ip_list | length }} IP адресов" - name: DNS резолв для всех IP shell: | result=$(nslookup {{ item }} {{ dns_servers[0] }} 2>/dev/null | grep 'name =' | awk '{print $NF}' | sed 's/\.$//') if [ -z "$result" ]; then result=$(nslookup {{ item }} {{ dns_servers[1] }} 2>/dev/null | grep 'name =' | awk '{print $NF}' | sed 's/\.$//') fi if [ -z "$result" ]; then echo "NO_DNS" else echo "$result" fi loop: "{{ ip_list }}" register: dns_results changed_when: false # Выполнение параллельно для ускорения async: 30 poll: 0 - name: Ожидание завершения DNS запросов async_status: jid: "{{ item.ansible_job_id }}" register: dns_jobs until: dns_jobs.finished retries: 60 delay: 1 loop: "{{ dns_results.results }}" - name: Фильтрация PC хостов set_fact: pc_hosts: "{{ pc_hosts | default([]) + [{'hostname': item.stdout | trim, 'ip': item.item}] }}" loop: "{{ dns_jobs.results }}" when: - item.stdout is defined - item.stdout != "NO_DNS" - item.stdout | trim | lower is match('^pc\\d+.*') - name: Создание инвентаря YAML copy: content: | # ========================================== # Инвентарь Windows PC # Сгенерирован: {{ ansible_date_time.iso8601 }} # DNS серверы: {{ dns_servers | join(', ') }} # Подсети: {{ subnets | join(', ') }} # Всего IP проверено: {{ ip_list | length }} # PC хостов найдено: {{ pc_hosts | default([]) | length }} # ========================================== all: children: windows_pcs: hosts: {% for host in pc_hosts | default([]) | sort(attribute='hostname') %} {{ host.hostname | regex_replace('\\.' + domain + '$', '') | regex_replace('\\..*$', '') }}: ansible_host: {{ host.ip }} {% endfor %} vars: ansible_connection: winrm ansible_winrm_transport: ntlm ansible_winrm_server_cert_validation: ignore ansible_port: 5985 ansible_winrm_scheme: http dest: "{{ inventory_file }}" - name: Итоговая статистика debug: msg: - "==========================================" - "Просканировано подсетей: {{ subnets | length }}" - "Проверено IP адресов: {{ ip_list | length }}" - "Найдено PC хостов: {{ pc_hosts | default([]) | length }}" - "Файл инвентаря: {{ inventory_file }}" - "==========================================" - name: Список найденных PC debug: msg: "{{ item.hostname }} ({{ item.ip }})" loop: "{{ pc_hosts | default([]) | sort(attribute='hostname') }}" when: pc_hosts is defined