Powershell : harmonisation de la configuration DNS

Afin d’harmoniser la configuration DNS sur des serveurs situés sur différents sites géographiques, j’ai développé un script Powershell lié à une GPO qui l’exécute au démarrage.

Ce script récupère grâce au nom du serveur son emplacement et applique en fonction de ce dernier les bonnes adresses IP. Naturellement, il faudra adapter l’extraction de l’emplacement dans le nom de la machine en fonction de l’environnement sur lequel le script sera déployé ; de plus, le domaine sur lequel la carte est connectée sert d’identification de la carte réseau employée pour la résolution DNS.

$location = (hostname).Substring(2,3)
switch($location){
"PAR" { $dnslist = '("192.168.1.1","192.168.1.2","192.168.2.1")' }
"BXL" { $dnslist = '("192.168.2.1","192.168.2.2","192.168.1.1")' }
"BER" { $dnslist = '("192.168.3.1","192.168.3.2","192.168.2.1")' }
"LDN" { $dnslist = '("192.168.4.1","192.168.4.2","192.168.3.1")' }
"NYC" { $dnslist = '("192.168.5.1","192.168.1.1","192.168.4.1")' }
}
$cards = Get-NetIPConfiguration
foreach($card in $cards){
if($card.NetProfile.Name -eq "dundermifflin.local") { $index = $card.InterfaceIndex }
}

$query = "Set-DnsClientServerAddress -InterfaceIndex $index -ServerAddresses $dnslist"
Invoke-Expression $query

Ce snippet fonctionne si par exemple mes serveurs ont une nomenclature de nommage comme celle-ci : <OS><Environnement><Emplacement><Rôle><ID>, qui pourrait donner par exemple pour un contrôleur de domaine de production WPLDNDC01 ou un serveur PostgreSQL de recette LRBXLPG03.

Utilisation de Get-ACL sur une arborescence ActiveDirectory

Cet article fait plus ou moins écho à celui d’hier où j’explique comment accorder des droits spécifiques à un utilisateur ou un groupe sur une OU ActiveDirectory. Get-ACL est une instruction Powershell permettant de retourner les permissions d’un fichier, répertoire ou même clef de registre. Par défaut, Get-ACL ne permet pas de retourner les autorisations d’un objet ActiveDirectory, mais il existe une technique de sioux permettant d’utiliser cette instruction sur un AD.

Sur une station ayant les RSAT d’installés ou bien directement sur un contrôleur de domaine, il suffit d’importer le module AD pour Powershell :

Import-Module ActiveDirectory

Ensuite, se placer dans l’arborescence AD :

Set-Location AD:

Un simple dir permet de retourner des informations nous confirmant que nous sommes bien dans l’AD.

Lancer un Get-ACL à la racine de AD: n’aura aucun effet. Il est tout de même nécessaire d’indiquer un chemin à la commande ; on utilisera alors le DistingushedName. Par exemple, pour récupérer l’intégralité des permissions à la racine du domaine (attention, ce n’est pas récursif !) :

(Get-Acl (Get-ADDomain).DistinguishedName).Access

Ainsi, il est possible de se concocter un petit snippet si l’on souhaite parcourir tout l’AD à la recherche de privilèges accordés à un groupe ou à un utilisateur sur des OU, par exemple :

Import-Module ActiveDirectory
Set-Location AD:
$oulist = Get-ADOrganizationalUnit -Filter * | select DistinguishedName
foreach($ou in $oulist){
$privileges = (Get-Acl $ou.DistinguishedName).Access | Where-Object { $_.IdentityReference -eq "DUNDERMIFFLIN\gclooney" }
if($privileges -ne $null) { Write-Host "OU:"$ou.DistinguishedName ; $privileges }
}

Par exemple, ayant accordé les droits à l’utilisateur gclooney sur l’OU End-Users, il récupère par héritage ces mêmes privilèges sur les 3 OU enfant.

Cela se vérifie avec le snippet plus haut :

Ce code peut naturellement être modifié pour interroger des groupes ou des utilisateurs. Par exemple, je vais octroyer des droits au groupe US-Presidents sur le groupe Actors. La capture suivante montre bien que le droit WriteProperty a été attribué.

En jouant sur la clause Where-Object de ce snippet, on peut modifier le filtre de recherche. Par exemple, afin rechercher tous les utilisateurs ayant le droit WriteProperty sur un objet défini, il suffit de modifier le snippet :

$grplist = Get-ADgroup -Identity "Actors" | select DistinguishedName
$privileges = (Get-Acl $grp.DistinguishedName).Access | Where-Object { $_.ActiveDirectoryRights -like "*WriteProperty*" }

Au final, la seule limite de Get-Acl et du code que l’on adapte autour, ce sont les informations que l’on souhaite récupérer et les actions éventuelles à mener pour cadrer au mieux les privilèges attribués au fil du temps !

Octroi de droits à un utilisateur spécifique sur une OU

Récemment, j’ai dû implémenter une tâche planifiée exécutant des scripts Powershell – vulgairement appelés moulinettes – de manière assez régulière pour automatiser et palier à de possibles oublis humains. Cette tâche s’exécute avec un compte de service ; seulement ce compte de service doit pouvoir modifier des groupes ActiveDirectory. Par défaut, un compte fraîchement créé ne dispose pas de tels privilèges. Il a donc fallu que j’accorde les droits à ce compte de service pour qu’il puisse écrire sur les objets présents dans une OU spécifique. A noter que la procédure ci-dessous – quasi-similaire à l’octroi de droits sur un répertoire NTFS tout simple – fonctionne pour la très grande majorité des objets ActiveDirectory.

La console ActiveDirectory, pouvant s’appeler avec dsa.msc doit avoir les fonctionnalités avancées d’activées : View > Advanced Features.

Ensuite, se rendre sur l’OU en question, puis ouvrir les propriétés de celle-ci. Les fonctionnalités avancées débloquent l’onglet Security. Cet onglet affiche les entités ayant des privilèges particuliers sur l’OU. En cliquant sur Advanced, une fenêtre apparaît.

Les diverses autorisations ou interdictions sont listées ; il est possible de faire un test avec un compte d’utilisateur dans Effective Access pour vérifier que ce dernier a bien le droit – ou non – d’effectuer certaines opérations sur cette OU.

Add ouvre une nouvelle fenêtre qui demandera de saisir un compte ; je vais donc saisir mon compte de service, puis lui accorder le privilège d’écriture (encadré en bleu).

Par défaut, le compte de service a le droit de lire les propriétés de l’OU ainsi que la parcourir. En ajoutant le droit d’écriture, j’autorise le compte à modifier les objets présents dans l’OU car l’octroi concerne cette OU et ce qu’elle contient (paramètre encadré en vert).

Une simple exécution de test de la tâche planifiée a confirmé le bon fonctionnement de l’accord des privilèges.

Powershell : liste des utilisateurs désactivés

Toujours dans une optique de réaliser un nettoyage de printemps sur son ActiveDirectory, voici un script listant les comptes utilisateurs désactivés et qui ne se sont pas connectés au domaine depuis un nombre de jours spécifié.

Write-Host "Disabled accounts listing script"
Write-Host "================================"
Write-Host "This script will list disabled user accounts that didn't login since a specified number of days."
[int]$nodays = Read-Host "Number of days"
$dusers = Get-AdUser -filter * -Properties LastLogonDate | Where-Object {$_.Enabled -eq $false}
$fdusers = $dusers | Where-Object {$_.LastLogonDate -ne $null -and $_.LastLogonDate.AddDays($nodays) -lt (Get-Date)}
$fdusers | ft SamAccountName,LastLogonDate
Write-Host "Done. Bye."