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 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
}