Files
semaphore/playbooks/scan_inventory.yml

129 lines
4.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
- name: Сбор инвентаря Windows (Nmap SMB + DNS)
hosts: localhost
connection: local
gather_facts: yes
vars:
inventory_file: "/tmp/windows_inventory.ini"
# Список подсетей
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.9.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"
# Порты для проверки доступности (WinRM, SSH, SMB)
scan_ports:
- 5985
- 22
- 445
tasks:
- name: Сканирование сети (поиск живых IP)
command: >
nmap -p {{ scan_ports | join(',') }}
-Pn -n --open --min-rate 1000 -T4 -oG -
{{ subnets | join(' ') }}
register: nmap_result
changed_when: false
- name: Извлечение IP адресов
set_fact:
active_ips: "{{ nmap_result.stdout | regex_findall('Host: ([0-9.]+).*Ports:.*(?:' + scan_ports | join('|') + ')/open') | unique | list }}"
- name: Статистика
debug:
msg: "Найдено активных IP: {{ active_ips | length }}"
# ГЛАВНОЕ ИЗМЕНЕНИЕ: Получаем имя через SMB (NetBIOS) или DNS
- name: Определение имен хостов (SMB Discovery)
shell: |
IP="{{ item }}"
# 1. Пробуем узнать имя через SMB (самый надежный способ для Windows)
SMB_NAME=$(nmap -p 445 --script smb-os-discovery $IP -Pn -n | grep "Computer name:" | awk -F': ' '{print $2}')
if [ ! -z "$SMB_NAME" ]; then
echo "$SMB_NAME" | tr '[:upper:]' '[:lower:]'
else
# 2. Если SMB закрыт/не ответил, пробуем DNS (как раньше)
DNS_NAME=$(nslookup -timeout=1 $IP 192.168.1.250 2>/dev/null | grep 'name =' | awk '{print $NF}' | sed 's/\.$//' | head -n 1)
if [ ! -z "$DNS_NAME" ]; then
echo "$DNS_NAME" | tr '[:upper:]' '[:lower:]'
else
echo "UNKNOWN"
fi
fi
loop: "{{ active_ips }}"
register: host_names
changed_when: false
no_log: true # Чтобы не засорять лог
# Фильтруем и готовим списки
- name: Сортировка хостов
set_fact:
# Ищем 'pc' в любом месте имени (было ^pc - только в начале)
pc_list: >-
{{ host_names.results
| selectattr('stdout', 'search', 'pc')
| map(attribute='item') | list
| zip(host_names.results | selectattr('stdout', 'search', 'pc') | map(attribute='stdout') | list)
| list }}
# Остальные (сервера, принтеры, неизвестные)
other_list: >-
{{ host_names.results
| rejectattr('stdout', 'search', 'pc')
| map(attribute='item') | list
| zip(host_names.results | rejectattr('stdout', 'search', 'pc') | map(attribute='stdout') | list)
| list }}
- name: Запись инвентаря
copy:
content: |
# === Найденные PC (по имени содержит 'pc') ===
[windows_pcs]
{% for ip, name in pc_list %}
{{ name }} ansible_host={{ ip }}
{% endfor %}
# === Остальные устройства (Servers, Unknown) ===
[windows_other]
{% for ip, name in other_list %}
{% if name == "UNKNOWN" %}
unknown_{{ ip | replace('.', '_') }} ansible_host={{ ip }}
{% else %}
{{ name }} ansible_host={{ ip }}
{% endif %}
{% endfor %}
[windows:children]
windows_pcs
windows_other
[windows:vars]
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=ignore
ansible_port=5985
ansible_user=Administrator
# Пароль лучше задать в Secret Store, не здесь
dest: "{{ inventory_file }}"
- name: ПОКАЗАТЬ РЕЗУЛЬТАТ (Скопируйте это в новый инвентарь)
command: cat {{ inventory_file }}
register: cat_inventory
changed_when: false
- name: Вывод в лог
debug:
var: cat_inventory.stdout_lines