Powershell : ActiveDirectory Recycle Bin Explorer

La corbeille ActiveDirectory est une fonctionnalité disponible sur les forêts en niveau fonctionnel 2008 R2. Comme son nom l'indique, elle permet de restaurer des objets qui ont été supprimés, durant un laps de temps qui dépend de la configuration de la forêt.

Cette corbeille n'apparaît pas en tant que telle dans la console ActiveDirectory Users and Computers ou encore dans ADSI Edit, et pourtant elle existe bien dans l'AD en tant que "Deleted Objects".

Si il est possible de parcourir le contenu de la corbeille via la console ActiveDirectory Administrative Center disponible dans le Server Manager à partir de Windows Server 2012, cela implique d'avoir l'environnement graphique d'installé sur les contrôleurs de domaine et cela est surtout incompatible dans un environnement où l'on travaille avec les RSAT.

C'est pourquoi j'ai développé un script Powershell avec une interface graphique simpliste permettant d'afficher le contenu de la corbeille ActiveDirectory et permettant de restaurer en un clic un objet préalablement supprimé.

Les informations sont affichées dans un DataGridView ; il est possible de trier ou de rechercher / filtrer par nom ou type, de réaliser un export CSV de la liste complète des objets étant dans la corbeille.


Powershell : obtention des liens des GPO

Si la console gpmc.msc permet de parcourir toutes les GPO ainsi que leurs liens, cela n'est pas directement possible avec Powershell et la commande Get-GPO qui ne retournera que les informations de base de la GPO.

Afin de pouvoir obtenir les liens dans Powershell, il faut ruser un peu ; dans les deux scripts Powershell suivants, j'ai donc utilisé une technique de sioux consistant à réaliser un rapport au format XML de la GPO (grâce à Get-GPOReport) et à parcourir ledit fichier XML pour y identifier les liens grâce aux balises <LinksTo>.

Ce premier script liste toutes les GPO qui n'ont aucun lien, activé ou non :

Write-Host "Unlinked GPO listing script"
Write-Host "==========================="
Write-Host "Working… Please wait.`r`n"
$GPOlist = Get-GPO -all
foreach($GPO in $GPOList){
[xml]$xmlreport = Get-GPOReport -Guid $GPO.Id -Report xml
if($xmlreport.GPO.LinksTo.Count -eq 0){ Write-Host $GPO.DisplayName ; $count+=1}
}
Write-Host "`r`nUnlinked GPO count:"$count
Write-Host "GPO parsed:"$gpolist.Length
Write-Host "Done."

Ce deuxième script attend en paramètre le nom d'une GPO et retourne dans la console Powershell les objets auxquels cette GPO est liée. Par exemple, on appellera le script ainsi : .\win_gpolinks.ps1 -gpo "SRV-2016-Security-V3"

Param([string]$gpoinput)
$gpo = Get-GPO $gpoinput
[xml]$report = Get-GPOReport -Guid $gpo.Id -Report xml
foreach($link in $report.GPO.LinksTo){
Write-Host $link.SOMPath
}

A noter qu'il est nécessaire d'avoir les RSAT d'installés sur la station (si ce n'est pas un DC) depuis laquelle le script est exécuté ; il peut également être nécessaire d'appeler Import-Module GroupPolicy pour exécuter les cmdlets Get-GPO et Get-GPOReport.

Exchange et Powershell : usage des databases

Ce script renvoie le nombre de boîtes aux lettres stockées dans une database Exchange ainsi que sa taille.

Le script peut s'appeler avec le nom de la database en paramètre ; si aucun paramètre n'est spécifié, alors le script parcourt toutes les databases.

Par exemple, pour récupérer les informations sur la database DBEXCHFR1, il suffira d'appeler le script de cette manière :

.\exch_dbusage.ps1 -db dbexchfr1

Le script est téléchargeable dans une version commentée.

Param([string]$db)
if($db -eq $null) { $mbxdbs = Get-MailboxDatabase -status | select Name,DatabaseSize }
else { $mbxdbs = Get-MailboxDatabase -status | select Name,DatabaseSize | Where-Object { $_.Name -eq $db } }
foreach($mbxdb in $mbxdbs){
$mbxindb = Get-Mailbox | Where-Object { $_.Database -eq $mbxdb.Name }
Write-Host "Database"$mbxdb.Name
Write-Host "Number of mailboxes on that database:"$mbxindb.Count
Write-Host "Size:"$mbxdb.DatabaseSize`r`n
}

Powershell : extraction des mots de passe BitLocker

Comme j'en avais parlé il y a presque un an déjà dans ce billet, il est possible de configurer BitLocker pour qu'il stocke les mots de passe des volumes chiffrés dans l'ActiveDirectory, en lien avec l'objet Ordinateur correspondant.

BitLocker stocke dans l'ActiveDirectory un objet de type msFVE-RecoveryInformation ; l'objet Ordinateur est donc le père. On peut retrouver toutes les informations en ouvrant un ADSI Edit et en allant sur l'objet Ordinateur :

Les différents mots de passe ont pour canonical name une concaténation de leur date de création et de différentes propriétés.

Dans les propriétés de l'objet, on retrouve donc l'attribut msFVE-RecoveryPassword que je vais récupérer dans le script Powershell ci-dessous ; ce script génère la liste de tous les objets Ordinateur et leurs objets msFVE-RecoveryInformation associés pour ensuite écrire le contenu dans un fichier CSV. Ainsi, ce script permet de réaliser une copie de sauvegarde des mots de passe et de ce qui est nécessaire pour déverrouiller les disques chiffrés des stations jointes au domaine. Naturellement, on prendra soin de bien protéger ce fichier et son accès. Le script est téléchargeable dans une version commentée à la fin de l'article.

Requires -RunAsAdministrator
Add-Type -AssemblyName System.Windows.Forms
$fileExpl = New-Object System.Windows.Forms.SaveFileDialog
$fileExpl.ValidateNames = $true
$fileExpl.CreatePrompt = $false
$fileExpl.OverwritePrompt = $true
$fileExpl.RestoreDirectory = $false
$fileExpl.InitialDirectory = "$env:userprofile"
Write-Host "WARNING : This script will extract from your ActiveDirectory all the BitLocker recovery keys and passwords. This is CRITICAL DATA as you would not want unauthorized users to be able to unlock the protected drives. Please ensure the exported data is stored somewhere safe." -Foreground "Red"
Write-Host "Please press ENTER to start."
Read-Host
$global:tempfile = "$env:temp\temp-bl.csv"
if(Test-Path $tempfile){ Remove-Item $tempfile }
$dump = "ComputerName,DistinguishedName,msFVE-RecoveryPassword"
Add-Content -Value $dump -path $tempfile
$complist = Get-AdComputer -Filter *
foreach($comp in $complist){
$BLInfo = Get-AdObject -Filter 'objectClass -eq "msFVE-RecoveryInformation"' -SearchBase $comp.DistinguishedName -Properties 'msFVE-RecoveryPassword'
foreach($BL in $BLInfo){
$dn =$BL.DistinguishedName
$dump = $comp.Name+","+"'"+$dn+"'"+","+$BL.'msFVE-RecoveryPassword'
Add-Content -Value $dump -Path $tempfile
}
}
$fileExpl.DefaultExt = "csv"
$fileExpl.Filter = "Comma-separated values file (.csv)|.csv"
$fileExpl.Title = "Export data to CSV file"
$fileExpl.Filename = ""
$fileExpl.ShowDialog() | out-null
if ($fileExpl.Filename -ne "") {
Copy-Item $global:tempfile -Destination $fileExpl.Filename
if ($?){ Remove-Item $global:tempfile ; Write-Host "Data exported to"$fileExpl.Filename }
else { Write-Host "Couldn't save the CSV file to the specified location." ; Remove-Item $global:tempfile }
}
else { Remove-Item $global:tempfile ; Write-Host "Data export aborted." }

Ce fichier CSV peut ensuite être importé dans Excel par exemple, en le convertissant :

Disque virtuel de taille nulle sur vSphere 6.5

Alerte de sauvegarde sur une machine virtuelle en exécution, snapshot impossible pour cause de disque inaccessible : celui-ci affiche une taille de 0 Ko.

Pourtant, en allant parcourir le datastore, on voit bien les fichiers VMDK aux côtés des fichiers de configuration et de mémoire vive.

Afin de résoudre le problème, j'ai essayé les manipulations suivantes :

  • Storage vMotion vers un autre datastore, machine éteinte : KO
  • vMotion vers un autre hôte, machine éteinte : KO

Il a finalement fallu que je supprime la machine de l'inventaire avant de la réinscrire sur le datastore d'origine. J'imagine que la réinscription dans l'inventaire et la lecture du fichier .vmx a permis à vSphere de rafraîchir les informations.

Enfin, le démarrage de la machine s'est déroulé sans accroc et j'ai pu créer un snapshot de test pour vérifier le bon fonctionnement d'une interaction avec le fichier VMDK. Mon flux de sauvegarde pourra reprendre son cours.