Powershell : automatisation de la création et peuplement de groupes AD

Dans le billet précédent, j’expliquais la création de groupes ActiveDirectory pour cadrer les flux générés par le Windows Update Delivery Optimization. Afin de faciliter le process de création de groupes et de peuplement de ces groupes, j’ai développé un script Powershell qui, avec un peu d’adaptation, permet d’automatiser tout ce travail.

Ce script va importer un fichier CSV dans un tableau dont toutes les lignes seront traitées pour créer un groupe correspondant, renvoyer le GUID du groupe créé, puis ajouter à ce groupe les stations de travail correspondantes.

Dans cet exemple, le fichier CSV peut se présenter ainsi :

Le fichier CSV en question avec les « colonnes » ID et location qui seront ensuite importées dans un tableau.

Ensuite, en prenant comme nomenclature <SiteID><Type><No>, qui va donner des noms comme FR01F01 pour le premier desktop parisien ou UK02M03 pour le troisième laptop du site de Glasgow, on peut articuler la requête ActiveDirectory qui va lister les stations correspondantes au site pour ensuite peupler le groupe lié. Le passage d’un paramètre permet de sélectionner – si cela est possible – le type de station que l’on souhaite inclure. Il sera peut-être nécessaire de travailler le contenu de la requête ActiveDirectory afin qu’elle corresponde à la nomenclature de nommage des stations.

function adquery{
param($T)
$adQuery = "Get-ADComputer -filter 'Name -like ""$id$T*""'"
$compList = Invoke-Expression $adQuery
if($?) {
foreach($comp in $compList){
Add-ADGroupMember -Identity $GrpName -Members $comp
}
}
}

$siteList = Import-CSV site.csv
$dn = (Get-ADDomain).DistinguishedName
foreach ($site in $siteList){
$id = $site.ID
$loc = $site.Location
$GrpName = $id+"-WUDO"
New-ADGroup -Name $GrpName -Description "Groupe d'ordinateurs du site $id ($loc)" -GroupScope DomainLocal -GroupCategory Security -Path "OU=Groupes-WUDO,OU=Workstations,$dn"
Write-Host "Groupe $GrpName"
Write-Host (Get-ADGroup $GrpName).ObjectGuid.Guid
adquery("F")
adquery("L")
}

Powershell : Export CSV d’une liste de KB WSUS

Afin de pouvoir communiquer sur les KB qui devront être prochainement appliqués sur les stations de travail pilotes, j’ai réalisé un script permettant de récupérer la liste des patchs qui sont en statut FailedOrNeeded et qui sont Unapproved dans WSUS, avec un filtre supplémentaire appliqué plus tard sur le nom afin de rejeter ceux qui concernent les serveurs et le .NET Framework.

De plus, je souhaitais uniquement récupérer les mises à jour qui ne sont pas Superseded, signifiant qu’elles ne sont pas écrasées ou incluses dans d’autres patchs (par exemple, le KB numéro 12345 est un patch cumulatif et contient les KB 2345 et 4567, par conséquent je ne veux pas tester ces deux derniers mais uniquement 12345) ; ce qui force une double requête, transmise dans le pipe.

Write-Host "WSUS Updates CSV Export Script"
Write-Host "=============================="
Write-Host `r`n
Write-Host "Retrieving unapproved and failed or needed WSUS Updates.`r`nThis might take a couple of minutes..."
$output = @() 
$UpdateList = Get-WsusUpdate -Approval Unapproved -Status FailedOrNeeded -Classification All | Where {($_.Update.IsSuperseded -eq $false) -and ($_.Update.KnowledgeBaseArticles -ne $null) }
Write-Host "Filtering and exporting to CSV..."
foreach ($Update in $UpdateList) { 
    if ($Update.Update.Title.Contains("Server") -eq $false -and $Update.Update.Title.Contains("Framework") -eq $false){
        $title = $Update.Update.Title
        $kbnumber = $Update.Update.KnowledgeBaseArticles
        $product = $Update.Update.ProductTitles
        $classif = $Update.Update.UpdateClassificationTitle
        $date = $Update.Update.CreationDate
        $UpdatePSO = New-Object PSCustomObject
		$UpdatePSO | Add-Member -Type NoteProperty -Name "Title" -Value $title
        $UpdatePSO | Add-Member -Type NoteProperty -Name "KB" -Value $kbnumber
		$UpdatePSO | Add-Member -Type NoteProperty -Name "Product" -Value $product
		$UpdatePSO | Add-Member -Type NoteProperty -Name "Class" -Value $classif
		$UpdatePSO | Add-Member -Type NoteProperty -Name "Date" -Value $date		
		$output+=$UpdatePSO
    }
}
$output | Export-CSV wsus-export-unapproved-failed.csv
Write-Host "Done."

J’ai choisi une séparation des colonnes avec un point-virgule car il y a des virgules dans les titres de certaines mises à jour ; il faudra donc veiller à bien spécifier que le point-virgule est le séparateur lors de l’ouverture du fichier CSV dans Excel. Ensuite, d’autres filtres sont possibles dans le tableur, on pourra donc exclure les mises à jour qui ne sont pas de sécurité par exemple.

Ce script, plutôt adapté à mon cas, peut être facilement modifié pour coller aux filtres que vous souhaitez appliquer, soit dans la requête WSUS de base, soit dans le foreach traité juste après.

Powershell : listing des disques locaux d’une machine distante et export CSV

Pour un besoin ponctuel, j’ai eu à faire un recensement des disques locaux et de leur état sur de multiples machines distantes. J’ai donc réalisé un script Powershell permettant de les lister et d’obtenir d’autres informations et d’en faire un export CSV qui devient finalement exploitable sous Excel grâce à la conversion (onglet Données > Convertir).

Ce script utilise WMI, il est donc important que le service soit en fonctionnement sur les machines cibles et que le pare-feu autorise la communication. Si il s’agit du pare-feu Windows, cela est très facile dans les réglages de ce dernier :

Pour autoriser WMI, on coche les cases « Domaine » ou « Domestique/entreprise » en fonction de sa situation.

A noter que le script commenté est également téléchargeable sur mon miroir de téléchargement.

Le script nécessite de placer simplement en paramètre le nom de la machine en question. On l’appellera par l’instruction suivante :

PS> .\win_listdisks.ps1 server.local
Param
    ([string]$Comp)
    
$output = @()
$DiskList = Get-WmiObject Win32_LogicalDisk -ComputerName $Comp
foreach ($Disk in $DiskList){
    if ($Disk.DriveType -ne 3){continue}
    $DiskLetter = $Disk.DeviceID
    $DiskName = $Disk.VolumeName
    $DiskSize = $Disk.Size
    $DiskFS = $Disk.FreeSpace
    $DiskSize = [long]$DiskSize/1073741824
    $DiskFS = [long]$DiskFS/1073741824
    $DiskPerc = ($DiskFS/$DiskSize)*100
    
    echo "Disk $DiskLetter"
    echo "Name: $DiskName"
    echo "Size: $DiskSize"
    echo "Free: $DiskFS"
    echo "Percentage Free: $DiskPerc"
    
	$DiskObj = New-Object PSCustomObject
	$DiskObj | Add-Member -Type NoteProperty -Name 'DiskLetter' -Value $DiskLetter
	$DiskObj | Add-Member -Type NoteProperty -Name 'DiskName' -Value $DiskName
	$DiskObj | Add-Member -Type NoteProperty -Name 'DiskSize' -Value $DiskSize
	$DiskObj | Add-Member -Type NoteProperty -Name 'DiskFS' -Value $DiskFS
	$DiskObj | Add-Member -Type NoteProperty -Name 'DiskPerc' -Value $DiskPerc
	$output+=$DiskObj
}
$output | Export-CSV disks-$comp.csv

Ensuite, dans Excel, en convertissant le CSV en tableau en choisissant la virgule comme élément délimitant les données, on obtient quelque chose de lisible :