Powershell : liste des groupes vides et export CSV

Afin de compléter le script que j’ai proposé dans l’article hier permettant de lister les OU vides, j’ai conçu un script effectuant le même travail mais pour des groupes. Seule la requête à l’AD est différente.

Il est possible que le script renvoie des erreurs si il tente d’interroger un groupe dont il y a un membre qui n’est pas membre du domaine local mais membre d’un domaine approuvé ; c’est la commande Get-AdGroupMember qui la renvoie mais cette erreur n’a aucune incidence sur le traitement du script.

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$fileExpl = New-Object System.Windows.Forms.SaveFileDialog
$fileExpl.ValidateNames = $true
$fileExpl.CreatePrompt = $false
$fileExpl.OverwritePrompt = $true
$fileExpl.RestoreDirectory = $false
$fileExpl.InitialDirectory = "$env:userprofile"
$output = @()

$AllGroups = Get-AdGroup -filter * | select SamAccountName,DistinguishedName
foreach ($Group in $AllGroups){
    if((Get-ADGroupMember $Group.SamAccountName).Count -eq 0){
        $emptyGrp = New-Object PSCustomObject
		$emptyGrp | Add-Member -Name "DN" -Value $Group.SamAccountName -MemberType NoteProperty
		$output+=$emptyGrp
    }
}

$fileExpl.DefaultExt = "csv"
$fileExpl.Filter = "Comma-separated values file (*.csv)|*.csv"
$fileExpl.Title = "Export empty groups list to CSV file"
$fileExpl.Filename = "emptygrp.csv"
$fileExpl.ShowDialog() | out-null
if ($fileExpl.Filename -ne "") {
	$output | Export-CSV $fileExpl.Filename -Encoding UTF8
}

Powershell : liste des OU vides et export CSV

Avec le temps, un ActiveDirectory peut contenir de plus en plus d’OU ne contenant aucun objet, car ceux-ci ont été déplacés ailleurs ou il s’agit tout simplement d’un reliquat. Le script Powershell suivant parcourt l’annuaire et liste les OU qui ne contiennent aucun objet pour ensuite en faire un fichier CSV à l’emplacement spécifié par l’utilisateur.

A noter que les OU ont eu leur chemin inversé, c’est à dire que plutôt que de commencer à l’OU pour aller vers la racine du domaine, le script écrit dans le fichier CSV le nom en commençant par la racine du domaine ; cela permet une fois que la conversion CSV > tableau est réalisée, de pouvoir trier et lire plus facilement les chemins vers les OU.

Par exemple, au lieu d’avoir un tableau comme ceci :

On obtient ceci, plus exploitable et compréhensible car on reprend le chemin qui sera parcouru dans la console pour retrouver l’OU en question :

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$fileExpl = New-Object System.Windows.Forms.SaveFileDialog
$fileExpl.ValidateNames = $true
$fileExpl.CreatePrompt = $false
$fileExpl.OverwritePrompt = $true
$fileExpl.RestoreDirectory = $false
$fileExpl.InitialDirectory = "$env:userprofile"
$output = @()

$OUs = Get-ADOrganizationalUnit -filter * | select DistinguishedName
foreach ($OU in $OUs){
    $OUObjects = Get-ADObject -Filter * -SearchBase $OU.DistinguishedName -SearchScope OneLevel
    if($OUObjects -eq $null){
		$emptyOU = New-Object PSCustomObject
		$emptyOU | Add-Member -Name "DN" -Value $OU.DistinguishedName -MemberType NoteProperty
		$output+=$emptyOU
	}
}

$fileExpl.DefaultExt = "csv" 
$fileExpl.Filter = "Comma-separated values file (*.csv)|*.csv"
$fileExpl.Title = "Export empty OU list to CSV file"
$fileExpl.Filename = "emptyOU.csv"
$fileExpl.ShowDialog() | out-null 
if($fileExpl.Filename -ne "") { 
	$output | Export-CSV $fileExpl.Filename -Encoding UTF8
}

Access Denied en chaîne sur un FTP porté par IIS

J’ai mis en place un serveur FTP porté par un serveur IIS installé sur un Windows Server 2016. Ce serveur FTP autorise un compte de service sans droits particuliers à écrire sur un répertoire virtuel configuré dans IIS.

Ce compte de service est bien renseigné pour avoir les droits sur le répertoire dans lequel il est censé écrire, et ses droits Read, Write sont bien portés à la fois sur la racine FTP ftproot et sur le répertoire virtuel. Cependant, à la connexion et ce peu importe le client FTP, j’obtenais un simple Access Denied après la transaction d’authentification et l’acceptation du certificat SSL. Après avoir essayé avec mon compte d’administration ayant exactement les mêmes privilèges sur la machine, cela fonctionnait. Le problème est donc lié au compte en lui-même.

Un petit tour dans le fichier de configuration de IIS disponible dans C:\Windows\System32\inetsrv\config\applicationHost.config (comme expliqué dans cet article) me donne rien de plus : les balises sont bien renseignées et le compte en question a bien les droits de connexion.


J’essaye alors d’ajouter le compte en tant qu’administrateur local pour voir si cela fait la différence, et c’est alors qu’un détail me saute aux yeux : dans la fenêtre du groupe des administrateurs locaux, le compte apparaît avec son appellation pré-Windows 2000. Sur cet exemple, le compte testcomptedeserviceftp@mondomaine.com est renseigné avec son nom pré-Windows 2000 MONDOMAINE\testcomptedeservicef :


On peut vérifier dans l’ActiveDirectory les deux noms de connexion :

La console ActiveDirectory Users and Computers permet de vérifier les deux logins d’un utilisateur.

Dans IIS, en remplaçant le nom de connexion usuel par le nom pré-Windows 2000, j’ai pu me connecter.

Il est donc nécessaire d’attribuer les privilèges en utilisant les noms pré-Windows 2000.

En effet, si le nom de mon compte d’administration n’était pas tronqué car identique qu’il soit pré-Windows 2000 ou non, ce n’était pas le cas pour mon compte de service (identifiant trop long). Je tentais donc de me connecter avec un compte inconnu de IIS ; j’ai donc appris aujourd’hui que ce dernier gère les privilèges FTP avec les noms de connexion pré-Windows 2000, ce qui m’a pris une petite heure à réaliser.

Restauration d’un contrôleur de domaine virtuel grâce à Veeam

Si la problématique de la sauvegarde de contrôleurs de domaine et surtout de leur restauration fut un temps épineuse, ce n’est plus tellement le cas de nos jours, grâce à des avancées côté Windows et côté outils de sauvegarde.

Dans le cadre d’un contrôleur de domaine virtuel, si réaliser un snapshot avant d’installer des mises à jour Windows par exemple peut partir d’un bon sentiment, c’est la catastrophe assurée en cas de retour en arrière, toute la cohérence de l’annuaire étant remise en question puisque le DC sera incapable de comprendre pourquoi il se voit présenter des mises à jour venant du futur puisqu’il aura été restauré à un état passé comme si rien ne s’était passé depuis la création du snap. L’outil Windows Server Backup peut être un bon point de départ pour la sauvegarde d’AD ; cependant l’emplacement de stockage n’est peut-être pas toujours défini à l’avance et l’outil peut ne pas s’intégrer dans les politiques de sauvegarde de l’infrastructure générale.

Récemment, j’ai pu effectuer sur une plateforme de tests la sauvegarde et la restauration de contrôleurs de domaines virtualisés sous vSphere ESXi grâce à Veeam Backup & Replication. Dans cet article, je vais aborder les points principaux d’une telle manipulation si un contrôleur de domaine ne démarre plus (et que par conséquent, la structure de l’AD est intacte), sans oublier de rappeler qu’il est indispensable de valider sur des environnements iso ces procédures de sauvegarde et restauration, en plus d’avoir connaissance de la documentation Veeam à ce sujet (p. ex. ces deux articles : ici et ). Dans le cas où la cohérence même de l’annuaire a été remise en question
(corruption, par exemple), d’autres étapes peuvent être requises
(je pense notamment par un passage par le DSRM) mais je ne les aborderai pas dans cet article.

La plateforme de test est composée de 4 machines : 3 contrôleurs de domaine 2012 R2 et un client Windows 10, sous vSphere 6.5 et sauvegardée par Veeam Backup & Replication en version 9.5.

Tout d’abord, il est important de vérifier que le job de sauvegarde des DC ait l’option Enable Application-aware Processing d’activée.

Bien sûr, avant de s’engager dans plus de manipulations, il sera bienvenu de s’assurer que les sauvegardes ont été réalisées avec succès en temps et en heures.

Suite à des manipulations sur dc03, j’obtiens un célèbre BSOD :

Ce DC doit donc être restauré. Dans VMware, je vais procéder à sa mise hors-tension, et à la suppression de la VM.

Dans Veeam, je vais procéder à la restauration de la VM, en utilisant les options Entire VM Restore puis Instant Recovery.

Je choisis de restaurer la VM to the original location, sans connecter le réseau ni directement démarrer la VM. Une fois cette opération terminée, la VM sera ajoutée dans VMware et stockée sur le pool de sauvegarde Veeam ; il faut la déplacer sur le stockage de production.

En allant sur Instant Recovery dans Veeam, je peux sélectionner mon dc03 et choisir Migrate to Production.

Une vérification des paramètres s’impose pour être sûr de finaliser la récupération au bon endroit, puis le déplacement sur l’environnement de production s’effectue.

Une fois l’opération terminée, je sélectionne l’option Stop Publishing sur dc03. Ainsi, il disparaît de VMware où il apparaissait en double : en tant que dc03 (fraîchement restauré) et dc03-xxxxx (la restauration de Veeam avant son déplacement sur l’environnement de production). Il ne reste donc plus que dc03.

Un petit tour dans les paramètres de la VM pour confirmer que tout est bien configuré : ne pas oublier de connecter la carte réseau avant de la démarrer.

Windows va s’initialiser puis redémarrer au bout de quelques minutes – c’est normal.

En réalité, Windows démarre en mode sans échec, se resynchronise avec les autres contrôleurs de domaine, réalise des mises à jour de fichiers de configuration avant de redémarrer. Une fois ce redémarrage terminé, l’OS est utilisable et répond aux requêtes AD comme si rien ne s’était passé. Tout le processus est entièrement automatique et géré par Veeam, qui lors de la sauvegarde, applique certains paramètres en détectant que la VM est un DC Windows.

Il ne reste plus qu’à réaliser quelques tests grâce à dcdiag et repadmin :

Un dcdiag /a /i devrait tout de même renvoyer quelques erreurs systèmes qui ont été journalisées dans l’event viewer en fonction de la manière dont le DC a planté mais tous les autres tests devraient être en succès, pour peu qu’ils l’aient été pré-crash. D’autres tests comme la jonction de stations aux domaine doivent toujours fonctionner sans anicroche.