Une des “limitations” du module GroupPolicy de PowerShell, c’est de ne pas pouvoir créer/modifier/supprimer des lecteurs mappés dans une GPO à l’aide de PowerShell. Il existe cependant une alternative pour pouvoir gérer cet aspect en PowerShell.

Cet article est le premier d’une série de plusieurs articles. Il concerne la gestion des GPO en PowerShell afin d’aborder ce sujet de manière à gagner en autonomie sur certains gestes qui ne sont pas nativement possibles sur les GPO via PowerShell.

Petit rappel : avant de manipuler les GPO en PowerShell, il est important de faire une sauvegarde des GPO avec la commande :

Backup-GPO -Name * -Path "C:\Backup\GPO\"

Créer une GPO avec des lecteurs mappés en PowerShell

Nous commençons par créer la GPO utilisateurs “U-Lecteurs mappés” :

New-GPO -Name "Lecteur mappés"
New-GPLink -Name "Lecteur mappés" -Target "OU=CaPingPas,DC=cpp,DC=local"

Notre GPO est fonctionnelle et liée au domaine.

Maintenant, nous allons créer un lecteur mappé qui pointe vers un partage nommé “Technique” et qui utilise la lettre Z:. Les lecteurs mappés dans les GPO sont stockés dans le répertoire de la GPO (User\Preferences\Drives\) dans un fichier XML qui se nomme “Drives.xml”. Tant qu’il n’y a pas de lecteur mappé, le chemin et le fichier ne sont pas créés, nous allons donc les créer manuellement et remplir le fichier dans la foulée :

# Contenu XML du fichier Drives.xml
$Content = @"
<?xml version="1.0" encoding="utf-8"?>
<Drives clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}"><Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="Z:" status="Z:" image="2" changed="2024-02-24 23:11:39" uid="{4921D726-DFC9-4383-8AF8-4D6CA8A2CBA8}"><Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="\\CPP-SRV1\Technique" label="" persistent="1" useLetter="1" letter="Z"/></Drive>
</Drives>
"@
# Récupération de l'ID de la GPO 
$GPOID = (Get-GPO -Name "U-Lecteur mappés").id
# Création de l'arborescence \Preferences\Drives\ dans le dossier User de la GPO
New-Item "\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\" -ItemType Directory -Force -Verbose
# Ajout du contenu au fichier Drives.xml
Add-Content "\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml" -Value $Content -Force -Verbose

Nous constatons dans le gestionnaire de stratégie de groupe que nous avons bien ajouté le lecteur à la stratégie :

Gestionnaire de stratégie de groupe

Il est également possible d’ajouter plusieurs lecteurs mappés en rajoutant des lignes dans le fichier XML. Dans cet exemple, j’ai rajouté 2 lecteurs mappés supplémentaires avec du “ciblage au niveau de l’élément” afin de pouvoir filtrer plus précisément son application :

<?xml version="1.0" encoding="utf-8"?>
<Drives clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}">
	<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="Z:" status="Z:" image="2" changed="2024-02-24 23:11:39" uid="{4921D726-DFC9-4383-8AF8-4D6CA8A2CBA8}"><Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="\\CPP-SRV1\Technique" label="" persistent="1" useLetter="1" letter="Z"/></Drive>
	<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="Y:" status="Y:" image="2" bypassErrors="1" changed="2024-02-24 23:39:38" uid="{E02F8E99-F2EF-4D15-B14D-580DE6798E3A}"><Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="\\CPP-SRV1\Support" label="" persistent="1" useLetter="1" letter="Y"/><Filters><FilterGroup bool="AND" not="0" name="CPP\Support" sid="S-1-5-21-637620520-2958170078-2356245748-1105" userContext="1" primaryGroup="0" localGroup="0"/></Filters></Drive>
	<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="X:" status="X:" image="2" changed="2024-02-24 23:42:24" uid="{C6B3EF00-5212-4F64-BEC1-B0BC9379A668}" bypassErrors="1"><Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="\\CPP-SRV2\Direction" label="Direction" persistent="0" useLetter="1" letter="X"/><Filters><FilterGroup bool="AND" not="0" name="CPP\Direction" sid="S-1-5-21-637620520-2958170078-2356245748-1106" userContext="1" primaryGroup="0" localGroup="0"/></Filters></Drive>
</Drives>

Modifier une GPO existante

Nous allons voir pour modifier une GPO existante.

Modifier l’emplacement du partage d’un ou plusieurs lecteurs mappés dans la GPO en PowerShell

Admettons que nous décommissionnons un serveur et que nous souhaitons que tous les chemins de partages qui étaient sur CPP-SRV2 deviennent CPP-SRV1. Il suffit de faire :

# Récupération de l'ID de la GPO 
$GPOID = (Get-GPO -Name "U-Lecteur mappés").id
# Récupération du fichier Drives.xml
$Content = Get-Content "\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml"
# Modification et enregistrement du fichier Drives.xml
$Content.Replace("CPP-SRV2","CPP-SRV1") | Set-Content "\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml"

Supprimer un des lecteurs mappés dans la GPO en PowerShell

Aussi, il est possible de vouloir supprimer un lecteur mappé au milieu de ceux-ci, dans ce cas, il est nécessaire de trouver un argument pour faire matcher la bonne ligne et de l’effacer du fichier. Pour l’occasion, nous allons faire appel aux fonctionnalités XML intégrés dans PowerShell :

# Récupération de l'ID de la GPO 
$GPOID = (Get-GPO -Name "U-Lecteur mappés").id
# Récupération du fichier Drives.xml
[xml]$Content = Get-Content "\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml"
# Recherche du noeud XML contenant "Direction"
$NodeToRemove = $Content.Drives.Drive | Where-Object { $_.Properties.path -like "*direction*" }
# Suppression du noeud XML
$Content.Drives.RemoveChild($NodeToRemove)
# Sauvegarde du fichier XML modifié
$Content.Save("\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml")

Ajouter un lecteur mappé supplémentaire dans la GPO en PowerShell

Parfois le besoin peut être de devoir rajouter un lecteur supplémentaire à une liste de lecteurs mappés déjà existante. Dans ce cas, nous pouvons le faire de cette manière :

# Récupération de l'ID de la GPO 
$GPOID = (Get-GPO -Name "U-Lecteur mappés").id
# Récupération du fichier Drives.xml
[xml]$Content = Get-Content "\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml"
# Ligne a ajouter dans Drives.xml
$XMLToAdd = @"
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="J:" status="J:" image="2" changed="2024-02-25 00:09:15" uid="{AC09FD14-9F83-4F6A-824E-12D6050C9ED9}"><Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="\\CPP-SRV1\Analyse" label="Analyse" persistent="0" useLetter="1" letter="J"/></Drive>
"@
# Ajout de la ligne au XML
$Content.Drives.InnerXml += $XMLToAdd
# Sauvegarde du fichier XML modifié
$Content.Save("\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml")

Supprimer tous les lecteurs mappés de la GPO en PowerShell

Derniers cas, la suppression de tous les lecteurs mappés :

# Récupération de l'ID de la GPO 
$GPOID = (Get-GPO -Name "U-Lecteur mappés").id
# Récupération du fichier Drives.xml
[xml]$Content = Get-Content "\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml"
# Selection des noeuds XML "Drive"
$NodeToRemove = $Content.Drives.Drive
# Suppression des noeuds XML
$NodeToRemove |  ForEach-Object { $Content.Drives.RemoveChild($_)}
# Sauvegarde du fichier XML modifié
$Content.Save("\\localhost\SYSVOL\cpp.local\Policies\{$GPOID}\User\Preferences\Drives\Drives.xml")

Quelques recommandations sur l’utilisation de PowerShell dans la gestion des GPO

  • En définitive, afin de faciliter l’utilisation lors de la création, ou d’une modification, je recommande de réaliser ce qui est voulu directement dans l’éditeur de GPO et de récupérer le contenu du fichier .xml dans le but de l’intégrer dans les scripts PowerShell.
  • Et pour finir, je le redis, mais les GPO peuvent être sensibles et contenir beaucoup de paramètre critique d’une organisation, en fonction de comment celle-ci sont gérées. Il est impératif de faire une sauvegarde afin d’avoir un retour arrière possible.