Edition rapide des GPO

I. Présentation

Votre environnement Active Directory contient de très nombreux objets de stratégies de groupes (alias GPO) et vous avez du mal à les retrouver. Vous pouvez investir dans des produits spécialisés tels que AGPM ou AD Manager Plus, mais si vous ne disposez d’aucun budget, rassurez-vous, Powershell peut vous faciliter la tache et en voici une petite démonstration.

28/11/2015 : v1.1 – Modification du code afin que le module GroupPolicy, apporté par RSAT, ne soit plus un pré-requis

10/09/2016 : v1.2 – Ajout d’un commutateur “-list” afin d’afficher uniquement le nom des GPO sans édition

12/10/2017 : v1.3 – Ajout de quelques modifications afin de proposer simplement l’affichage des noms de GPO, lorsqu’il y en a plusieurs qui sont proposées

II. Création de l’outillage

A. Les consoles d’administration des GPO

En premier lieu, je précise que la plupart des consoles d’administration MMC (*.msc) disposent de commutateurs, souvent méconnus. Pour notre cas de figure, il suffit de s’attarder sur l’éditeur de stratégie “GPEdit.msc“. Celui-ci dispose des 2 options suivantes :

  • gpedit.msc /gpcomputer:”NomDeMachine” – Permet d’éditer l’objet de  stratégie de groupe local de la machine. Généralement inutile du fait que c’est l’action par défaut au moment du lancement. Notez toutefois, l’importance des guillemets dans la syntaxe, qui sont loin d’être neutres dans le langage Powershell.
  • gpedit.msc /gpobject:”LDAP://CN={6AC1786C-016F-11D2-945F-00C04fB984F9},CN=Policies,CN=System,DC=Domaine,DC=tld” – Permet d’éditer un objet de  stratégie de groupe du domaine Active Directory. La encore, hormis l’importance des guillemets, la saisie manuelle d’une telle chaîne n’est pas raisonnable comparativement à l’interface graphique .

 

Plus d’information sur ces méthodes, c’est ici

Nous allons constater que l’usage de “l’éditeur local de stratégie de groupe” n’est pas nécessairement adapté à notre étude ,mais présente l’avantage d’être disponible sur tous les ordinateurs Windows. En résumé, voici les différentes consoles d’administration proposées dans le cadre de la gestion des  stratégies de groupes.

Console Nom (en-US) Disponibilité
gpedit.msc

 

Local Group Policy Editor Tout ordinateur depuis Windows 2000
gpmc.msc

 

Group Policy Management Console Contrôleurs de domaine AD

Fonctionnalité optionnelle (cf RSAT)

gpme.msc

 

Group Policy Management Editor Contrôleurs de domaine AD

Fonctionnalité optionnelle (cf RSAT)

gptedit.msc Group Policy Starter GPO Editor Contrôleurs de domaine AD

Fonctionnalité optionnelle (cf RSAT)

 

B. Le script Powershell

Ce script nécessite quelques prérequis :

  • La disponibilité du module “GroupPolicy
if (Get-Module -ListAvailable -name "GroupPolicy") { 
   write-host -fore green "Le module GroupPolicy est disponible sur cet ordinateur. On le charge."
   Import-Module GroupPolicy | Out-Null
 } else {
   write-host -fore red "Le module GroupPolicy n'est pas disponible sur cet ordinateur. On quitte le script."
   exit
}

 

  • Doit être utilisé sur une machine membre du domaine ou un contrôleur de domaine.
if ((gwmi win32_computersystem).partofdomain -eq $true) {
    write-host -fore green "L'ordinateur $env:computername est membre d'un domaine."
} else {
    write-host -fore red "L'ordinateur $env:computername n'est pas membre d'un domaine."
}

 

  • Disposer des privilèges d’administration des GPO (Edition)

Un contrôle précis de ces privilèges étant relativement délicat, et je n’aborderais pas ce point de contrôle afin de ne pas trop surcharger cet article. Il peut être plus simple de vous inspirer d’un test d’appartenance de groupe comme proposé dans l’exemple du technet https://gallery.technet.microsoft.com/scriptcenter/AD-Domain-Administration-82378ce6

 

Outre le contrôle de ces prérequis, la principale difficulté de ce script est le respect des guillemets qui sous Powershell sont interprétés et rendent ainsi la commande précitée invalide. On va donc renseigner ces caractères spéciaux via leur code ASCII (34), comme suit

gpedit.msc /gpobject:$([char]34)LDAP://$($GPO.Path)$([char]34)

Pour la récupération de l’identifiant du GPO, nous utiliserons dorénavant (petit changement de code) le fournisseur standard [ADSI] ce qui permet de nous affranchir du module “GroupPolicy” (Uniquement disponible sur les machines sur lesquelles sont installés les outils d’administration de serveur à distance, alias RSAT)

Contrairement l’applet de commande “Get-GPO -all” du module  “GroupPolicy” , il n’est plus nécessaire d’ajouter le préfixe “LDAP://” qui est déjà intégré dans la propriété “.Path” du fournisseur ADSI.

Ce qui donne quelque chose du genre :

param (
 [string]$GPOName
)

if (-not($GPOName)) { Throw "Entrez un nom de GPO" }

$AllGPOs = ([adsisearcher]'(objectCategory=groupPolicyContainer)').FindAll()
$MatchGPOs = $AllGPOs | Where-Object { $_.Properties.displayname -like "*$GPOName*" } 

if ($MatchGPOs -ne $null) {
 $MatchGPOs | % {gpedit.msc /gpobject:$([char]34)$($_.Path)$([char]34)}
 } else {
 write "Aucun GPO ne correspond au nom mentionné."
}

Pour utiliser ce script, que vous aurez préalablement enregistré sous le nom “Quick-GPOEdit.ps1” et sous réserve d’avoir autorisé la stratégie d’exécution Powershell, il vous suffira de procéder comme suit :

.\Quick-GPOEdit.ps1 -GPOName Default

Notez qu’il n’est pas nécessaire d’entrer le nom complet du GPO et qu’il faudra lui adjoindre des guillemets si le nom contient des espaces.

Dans cet exemple, cela doit avoir pour conséquence d’ouvrir les 2 stratégies par défaut du domaine, soit

  •  Default Domain Policy
  •  Default Domain Controllers Policy

 

Il y a toutefois un petit bémol à cette procédure, que je vous propose d’affiner. En effet, l’éditeur “gpedit.msc” étant lancé directement, sans passer par l’intermédiaire du gestionnaire des stratégies de groupes (alias “gpmc.msc“), vous n’aurez accès qu’aux parties “Stratégies” mais pas aux rubriques “Préférences“. Pour remédier à cette situation, nous devrons faire appel à la console “gpme.msc” évoquée précédemment. Il faudra toutefois ajouter un test de disponibilité des outils d’administration de serveur à distance (alias RSAT) dans nos pré-requis.

Si on ajoute quelques options, telles que le mode “list”, voici ce à quoi pourrait ressembler notre script final :

# ---------------------------------------------------------------------
# Script d'edition rapide de GPO Active Directory
# Entrez simplement le nom complet (ou partiel) du GPO à editer 
# Entrez le commutateur -list pour rechercher/vérifier simplement le nom 
#
# Necessite d'avoir les privilèges d'administration des GPO
# D'etre sur un ordinateur membre du domaine 
# Et idéalement disposant des outils d'administration (RSAT)
# v1.1 - Enum. GPO via [ADSI] - Le module GroupPolicy n'est plus imposé
# v1.2 - Ajout du commutateur -List afin d'afficher uniquement le nom des GPO sans édition
# v1.3 - Propose le mode "-List" s'il est omis alors que plusieurs GPO sont trouvés.
# USAGE
# .\Quick-GPOEdit.ps1 -GPOName * -List
# .\Quick-GPOEdit.ps1 -GPOName Controllers
# Edite tous les GPO qui correspondent au nom mentionné
#
# Version 1.3
# (c)Mandin
# ---------------------------------------------------------------------
param (
 [string]$GPOName,
 [switch]$List
)

# Controle d'appartenance de l'ordinateur à un domaine
if ((gwmi win32_computersystem).partofdomain -eq $true) {
 write-host -fore green "L'ordinateur $env:computername est membre d'un domaine."
 } else {
 write-host -fore red "L'ordinateur $env:computername n'est pas membre d'un domaine."
 write-host "Arret du Script." 
 exit
}

# Saisie et controle du nom du GPO
if (-not($GPOName)) { Throw "Paramètre obligatoire : Veuillez entrer tout ou partie d'un nom de GPO" }

# Controle de disponibilité de la console gpme.msc sinon on utilisera gpedit.msc
 if (Test-Path("$env:windir\system32\gpme.msc")) {
 $ed = "$env:windir\system32\gpme.msc" 
 } else {
 write-host -fore yellow "Console GPME.msc introuvable. Les préférences ne seront pas visibles"
 $ed = "$env:windir\system32\gpedit.msc"
 }

# Recherche du/des GPOs correspondantes au nom mentionné 
 $AllGPOs = ([adsisearcher]'(objectCategory=groupPolicyContainer)').FindAll()
 $MatchGPOs = $AllGPOs | Where-Object { $_.Properties.displayname -like "*$GPOName*" } # | % {$_.Properties }
 if ($MatchGPOs.Count -gt 1 -and $List -eq $false) {
 Write-Host "Attention vous allez éditer $($MatchGPOs.Count) GPO !...`n`r Voulez-vous simplement les lister ?" 
 $Confirm = Read-Host "Validez pour confirmer ou entrez [N] pour simplement les lister leurs noms."
 if ($Confirm -eq 'N') { $List = $true }
 }
 if ($MatchGPOs -ne $null) {
 Foreach ($GPO in $MatchGPOs) { 
 $displayname = ($GPO.Properties)["displayname"]
 if ($List) { 
 write-host "Nom du GPO : [$DisplayName]"
 } else {
 write-host -fore green "Edition du GPO : [$DisplayName] via $ed"
 Start-Process -FilePath $ed -ArgumentList "/gpobject:$([char]34)$($GPO.Path)$([char]34)"
 }
 }
 } else {
 write-host -fore red "Aucun GPO ne semble correspondre au texte ...[$GPOName]..."
 }

 

Voici un petit aperçu du résultat pris sur un contrôleur de domaine basique.

Aperçu de Quick-GPOEdit v1.3

 

En espérant que cet exemple vous démontre encore un peu plus, l’intérêt d’associer Powershell à votre quotidien. 🙂

Bien à vous

Christophe

 

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. Apprenez comment les données de vos commentaires sont utilisées.