Chapitre 1118 minIntermédiaire
Automatiser Windows Server et Active Directory
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- installer des rôles et des mises à jour sur Windows Server ;
- créer un partage et ses droits NTFS selon AGDLP ;
- gérer des réservations DHCP et des enregistrements DNS ;
- créer des OU, des groupes et des comptes Active Directory ;
- choisir entre un module
win_*et un script PowerShell.
2 exercices corrigés
Automatiser Windows Server avec Ansible, c'est installer ses rôles, gérer ses partages, ses droits NTFS, son DHCP et son DNS, et créer les comptes Active Directory à partir de listes versionnées, avec les modules des collections ansible.windows et microsoft.ad. Ce chapitre suppose que la connexion WinRM ou SSH fonctionne (chapitre 10) ; il automatise le serveur de fichiers, le DHCP et le DNS des contrôleurs, puis le cycle de vie des comptes de Sorbier.
Exemple : le serveur de fichiers
Le playbook fichiers.yml installe les rôles du serveur de fichiers sur srv-fichiers, crée le dossier et le partage de la comptabilité avec les droits de la stratégie AGDLP du cours Windows Server, ouvre le port de l'agent de supervision et installe les mises à jour de sécurité.
---
- name: Configurer le serveur de fichiers
hosts: fichiers
tasks:
- name: Installer le serveur de fichiers et le gestionnaire de ressources
ansible.windows.win_feature:
name:
- FS-FileServer
- FS-Resource-Manager
include_management_tools: true
state: present
register: roles_fichiers
- name: Redémarrer si l'installation l'exige
ansible.windows.win_reboot:
when: roles_fichiers.reboot_required
- name: Créer le dossier de la comptabilité
ansible.windows.win_file:
path: D:\Partages\Compta
state: directory
- name: Donner la modification au groupe DL_Compta_M (NTFS)
ansible.windows.win_acl:
path: D:\Partages\Compta
user: SORBIER\DL_Compta_M
rights: Modify
type: allow
inherit: ContainerInherit, ObjectInherit
state: present
- name: Donner la lecture au groupe DL_Compta_L (NTFS)
ansible.windows.win_acl:
path: D:\Partages\Compta
user: SORBIER\DL_Compta_L
rights: ReadAndExecute
type: allow
inherit: ContainerInherit, ObjectInherit
state: present
- name: Partager le dossier
ansible.windows.win_share:
name: Compta
path: D:\Partages\Compta
description: Partage de la comptabilité
change: SORBIER\DL_Compta_M
read: SORBIER\DL_Compta_L
list: false
state: present
- name: Autoriser l'agent de supervision depuis srv-journaux
ansible.windows.win_firewall_rule:
name: Agent de supervision (srv-journaux)
localport: "10050"
protocol: tcp
direction: in
action: allow
remoteip: 192.168.10.180
profiles: domain
state: present
enabled: true
- name: Installer les mises à jour critiques et de sécurité
ansible.windows.win_updates:
category_names:
- CriticalUpdates
- SecurityUpdates
reboot: true
win_featurerenvoiereboot_required: le redémarrage n'a lieu que si Windows le demande.win_aclajoute une entrée à la liste de contrôle d'accès NTFS ;inheritla propage aux sous-dossiers et aux fichiers. Les droits réels passent par les groupes de domaine local, comme le veut AGDLP ; les autorisations du partage reprennent les mêmes groupes.list: falseactive l'énumération basée sur l'accès : un utilisateur ne voit pas le partage s'il n'y a pas accès.win_updatesavecreboot: trueredémarre autant de fois que nécessaire et reprend l'installation. Pour un contrôleur de domaine, on traite les deux contrôleurs l'un après l'autre (serial: 1) pour que le domaine reste toujours disponible.- La règle du pare-feu Windows n'ouvre le port 10050 qu'au serveur de supervision, et seulement sur le profil domaine ; l'agent Zabbix lui-même est expliqué dans le cours Supervision.
Les noms des fonctionnalités sont ceux de Get-WindowsFeature (colonne Name) : AD-Domain-Services, DHCP, DNS, FS-FileServer, RSAT-AD-Tools…
Exemple : DHCP et DNS sur les contrôleurs
Une réservation DHCP pour la nouvelle imprimante des ressources humaines, dans l'étendue du VLAN 10 (192.168.10.64) :
- name: Réserver l'adresse de l'imprimante des RH
ansible.windows.win_dhcp_lease:
type: reservation
scope_id: 192.168.10.64
ip: 192.168.10.111
mac: 00-1B-A9-4C-21-80
reservation_name: IMP-RH
description: Imprimante RH
state: present
Un enregistrement DNS pour le serveur de recette créé au chapitre 13 :
- name: Déclarer srv-recette dans la zone du domaine
ansible.windows.win_dns_record:
name: srv-recette
type: A
value: 192.168.21.186
zone: ad.sorbier.example
state: present
Une étendue DHCP, qu'aucun module ne gère : on passe par win_powershell, en écrivant soi-même le test d'idempotence. L'objet $Ansible permet au script de dire s'il a modifié quelque chose. Ici, l'étendue du VLAN 50 de la téléphonie, 192.168.10.160/28, passerelle .174 :
- name: Créer l'étendue DHCP de la téléphonie si elle n'existe pas
ansible.windows.win_powershell:
parameters:
ScopeId: 192.168.10.160
Debut: 192.168.10.161
Fin: 192.168.10.173
Masque: 255.255.255.240
Passerelle: 192.168.10.174
script: |
param($ScopeId, $Debut, $Fin, $Masque, $Passerelle)
$ErrorActionPreference = 'Stop'
if (Get-DhcpServerv4Scope -ScopeId $ScopeId -ErrorAction SilentlyContinue) {
$Ansible.Changed = $false
return
}
Add-DhcpServerv4Scope -Name 'VLAN50-TELEPHONIE' -StartRange $Debut -EndRange $Fin `
-SubnetMask $Masque -LeaseDuration 8.00:00:00 -State Active
Set-DhcpServerv4OptionValue -ScopeId $ScopeId -Router $Passerelle
Ces tâches vont dans un play qui vise srv-ad seulement (hosts: srv-ad) : le DNS est répliqué par l'annuaire, et l'étendue doit ensuite être ajoutée à la relation de basculement DHCP avec srv-ad2, configurée dans le cours Windows Server.
Créer des comptes Active Directory
C'est un usage typique d'Ansible chez Sorbier : chaque printemps, une vingtaine de saisonniers rejoignent la logistique. (Automatiser la création des comptes ne dispense pas de protéger l'annuaire : mots de passe, comptes de service et durcissement sont dans le cours Sécurité de l'Active Directory.) La liste est un fichier de variables versionné, vars/arrivees.yml :
---
arrivees:
- login: lgirard
prenom: Lucas
nom: Girard
service: Logistique
groupes: [GG_Logistique]
- login: eberard
prenom: Élise
nom: Bérard
service: Commercial
groupes: [GG_Commerciaux]
Le playbook comptes_ad.yml crée les OU et les groupes s'ils manquent, puis les comptes. Il vise un seul contrôleur, puisque l'annuaire se réplique :
---
- name: Créer les comptes Active Directory des arrivées
hosts: srv-ad
vars_files:
- vars/arrivees.yml
vars:
base_ou: OU=Sorbier,DC=ad,DC=sorbier,DC=example
tasks:
- name: Garantir l'OU de chaque service
microsoft.ad.ou:
name: "{{ item }}"
path: OU=Utilisateurs,{{ base_ou }}
protect_from_deletion: true
state: present
loop: "{{ arrivees | map(attribute='service') | unique }}"
- name: Garantir les groupes globaux
microsoft.ad.group:
name: "{{ item }}"
scope: global
category: security
path: OU=Groupes,{{ base_ou }}
state: present
loop: "{{ arrivees | map(attribute='groupes') | flatten | unique }}"
- name: Lister les comptes qui existent déjà
microsoft.ad.object_info:
ldap_filter: (&(objectClass=user)(objectCategory=person))
search_base: OU=Utilisateurs,{{ base_ou }}
properties:
- sAMAccountName
register: comptes_existants
- name: Créer ou mettre à jour chaque compte
microsoft.ad.user:
name: "{{ item.prenom }} {{ item.nom }}"
firstname: "{{ item.prenom }}"
surname: "{{ item.nom }}"
sam_account_name: "{{ item.login }}"
upn: "{{ item.login }}@ad.sorbier.example"
path: OU={{ item.service }},OU=Utilisateurs,{{ base_ou }}
password: "{{ lookup('ansible.builtin.password', 'identifiants/' ~ item.login ~ '.txt', length=16, chars=['ascii_letters', 'digits', '!?#%+']) }}"
update_password: on_create
password_expired: "{{ (logins_existants is not contains(item.login)) | ternary(true, omit) }}"
groups:
add: "{{ item.groupes }}"
enabled: true
state: present
loop: "{{ arrivees }}"
loop_control:
label: "{{ item.login }}"
vars:
logins_existants: "{{ comptes_existants.objects | map(attribute='sAMAccountName') | list }}"
no_log: true
Les points à comprendre :
- Les boucles calculées.
arrivees | map(attribute='service') | uniquedonne la liste des services sans doublon ;map(attribute='groupes') | flatten | uniqueaplatit les listes de groupes de chaque personne en une seule liste. - Le mot de passe initial. Le lookup
passwordgénère un mot de passe aléatoire de 16 caractères et l'enregistre dansidentifiants/<login>.txt, sur le nœud de contrôle : relancé, le playbook relit le même fichier au lieu d'en générer un autre.update_password: on_createne pose le mot de passe qu'à la création du compte. - Changer le mot de passe à la première connexion.
password_expiredn'est mis àtrueque pour les comptes absents de l'annuaire avant l'exécution : le testcontainsvérifie si la listelogins_existantscontient le login, et le filtreternarychoisit entre deux valeurs. Pour les comptes existants, la valeur spécialeomitretire l'option : le module ne touche pas à ce réglage, et un salarié qui a déjà changé son mot de passe n'est pas forcé de recommencer. groups.addajoute les groupes sans retirer ceux que le compte a déjà ;setremplacerait toute la liste.no_log: trueempêche le mot de passe d'apparaître dans la sortie (en 2.22, le masquage automatique le cacherait déjà, maisno_logcouvre aussi les journaux et les versions antérieures).
Pour le départ d'un salarié, la même logique s'applique : une liste departs et une tâche microsoft.ad.user avec enabled: false et un déplacement vers une OU d'archives, plutôt qu'une suppression immédiate (cycle de vie des comptes dans le cours Windows Server).
Exercices
Exercice 1 sur 2 Le module ou le script ? Réussi À revoir
Pour chaque besoin, donne le module à utiliser, ou explique pourquoi il faut win_powershell.
- Installer le rôle DHCP et ses outils d'administration sur
srv-ad2. - Vérifier que le service « Spouleur d'impression » (
Spooler) est arrêté et désactivé sur les contrôleurs de domaine. - Créer le groupe de domaine local
DL_RH_Mdans l'OUGroupes. - Ajouter un enregistrement CNAME
intranetverssrv-web.ad.sorbier.example. - Configurer l'option DHCP « serveur NTP » (option 042) sur une étendue.
Voir la réponseMasquer la réponse de l'exercice 1
ansible.windows.win_featureavecname: DHCP,include_management_tools: true.ansible.windows.win_serviceavecname: Spooler,state: stopped,start_mode: disabled. Désactiver le spouleur sur les contrôleurs de domaine est une recommandation de durcissement classique : il a été la cible de vulnérabilités graves.microsoft.ad.groupavecscope: domainlocal,category: security,path: OU=Groupes,OU=Sorbier,DC=ad,DC=sorbier,DC=example.ansible.windows.win_dns_recordavecname: intranet,type: CNAME,value: srv-web.ad.sorbier.example,zone: ad.sorbier.example.- Aucun module de la collection ne gère les options d'étendue :
win_powershellavecGet-DhcpServerv4OptionValuepour tester, puisSet-DhcpServerv4OptionValue -ScopeId … -OptionId 42 -Value …, et$Ansible.Changed = $falsequand la valeur est déjà la bonne.
Tu avais trouvé ?
Exercice 2 sur 2 Un départ Réussi À revoir
Lucas Girard (lgirard) quitte Sorbier à la fin de la saison. Écris la tâche qui désactive son compte, le déplace dans l'OU OU=Archives,OU=Sorbier,DC=ad,DC=sorbier,DC=example et le retire du groupe GG_Logistique, sans supprimer le compte.
Voir la réponseMasquer la réponse de l'exercice 2
- name: Désactiver et archiver le compte de Lucas Girard
microsoft.ad.user:
identity: lgirard
path: OU=Archives,OU=Sorbier,DC=ad,DC=sorbier,DC=example
enabled: false
groups:
remove:
- GG_Logistique
state: present
identity retrouve le compte par son sAMAccountName, quel que soit son emplacement ; path le déplace. Garder le compte désactivé quelques mois permet de retrouver ses droits et de transférer ses fichiers ; la suppression vient ensuite, selon la procédure de départ. Pour un traitement en série, on met les départs dans une liste et on boucle.
Tu avais trouvé ?