# Liaison GG-GDL

[![agdlp.png](https://docs.rakouns.bzh/uploads/images/gallery/2025-10/scaled-1680-/NlHagdlp-png.png)](https://docs.rakouns.bzh/uploads/images/gallery/2025-10/NlHagdlp-png.png)

### Introduction

Il s'agit de la dernière étape pour mettre en place des droits AGDLP, ajout les GG comme membres des GDLP afin que les utilisateurs puissent accéder aux ressources partagées.

## Introduction

Nous reprenons une nouvelle fois notre fichier CSV :

[![image.png](https://docs.rakouns.bzh/uploads/images/gallery/2026-02/scaled-1680-/QmFimage.png)](https://docs.rakouns.bzh/uploads/images/gallery/2026-02/QmFimage.png)

```
NIVEAU 1;NIVEAU 2;NIVEAU 3;NIVEAU 4;NIVEAU 5;NIVEAU 6;NIVEAU 7;NIVEAU 8;FolderPath;CREER_GROUPES;GG_ECRITURE;GG_LECTURE;GDL_ECRITURE;GDL_LECTURE;GDL_VUE;Parent_GDL
01-DIRECTION;;;;;;;;01-DIRECTION;;ORG_GG_DIRECTION;;GDL_01_ECRITURE;GDL_01_LECTURE;GDL_01_VUE;
02-FINANCE;;;;;;;;02-FINANCE;;ORG_GG_FINANCE;ORG_GG_DIRECTION;GDL_02_ECRITURE;GDL_02_LECTURE;GDL_02_VUE;
02-FINANCE;01-BUDGET;;;;;;;02-FINANCE\01-BUDGET;;ORG_GG_FINANCE;ORG_GG_DIRECTION;GDL_02-01_ECRITURE;GDL_02-01_LECTURE;GDL_02-01_VUE;GDL_02_VUE
02-FINANCE;02-FACTURES;;;;;;;02-FINANCE\02-FACTURES;;ORG_GG_FINANCE;ORG_GG_DIRECTION;GDL_02-02_ECRITURE;GDL_02-02_LECTURE;GDL_02-02_VUE;GDL_02_VUE
03-RH;;;;;;;;03-RH;;ORG_GG_RH;ORG_GG_DIRECTION;GDL_03_ECRITURE;GDL_03_LECTURE;GDL_03_VUE;
03-RH;01-CONTRATS;;;;;;;03-RH\01-CONTRATS;;ORG_GG_RH;ORG_GG_DIRECTION;GDL_03-01_ECRITURE;GDL_03-01_LECTURE;GDL_03-01_VUE;GDL_03_VUE
03-RH;02-PAIE;;;;;;;03-RH;NON;;;;;;
04-IT;;;;;;;;04-IT;;ORG_GG_IT;ORG_GG_DIRECTION;GDL_04_ECRITURE;GDL_04_LECTURE;GDL_04_VUE;
04-IT;01-INFRA;;;;;;;04-IT\01-INFRA;;ORG_GG_IT;ORG_GG_DIRECTION;GDL_04-01_ECRITURE;GDL_04-01_LECTURE;GDL_04-01_VUE;GDL_04_VUE
04-IT;02-PROJETS;;;;;;;04-IT\02-PROJETS;;ORG_GG_IT;ORG_GG_DIRECTION;GDL_04-02_ECRITURE;GDL_04-02_LECTURE;GDL_04-02_VUE;GDL_04_VUE
04-IT;02-PROJETS;2026;;;;;;04-IT\02-PROJETS\2026;NON;;;;;;

```

### Ajouter les GG dans les GDL

Pour cette dernière étape, le script va utiliser les colonnes GG\_RW qui va ajouter comme membre du GDL\_RW correspondant, idem pour GG\_RO avec GDL\_RO :

```powershell
<#
===============================================================================
SCRIPT : 6.1 - Ajout_G_dans_GDL.ps1
OBJET  : Aligne les GDL avec les GG listes dans le CSV (GG_ECRITURE / GG_LECTURE)
===============================================================================

DESCRIPTION :
  - Pour chaque ligne du CSV :
      * Nettoie les membres "groupes non GDL" des GDL cibles
      * Ajoute les GG_ECRITURE dans GDL_ECRITURE
      * Ajoute les GG_LECTURE  dans GDL_LECTURE
  - Ignore proprement les cellules vides
  - Logue les groupes AD introuvables (UTF8-BOM)
  - Une seule barre de progression Write-Progress
  - Messages sans accents (compatibilite)

PREREQUIS :
  - 2.1 : GDL crees (GDL_ECRITURE / GDL_LECTURE renseignes dans CSV)
  - 5.1 : GG crees (version 2-passes recommande)

===============================================================================
#>

Param(
    [string]$CsvPath = "C:\AGDLP\ORG_ARBO_GDL.csv",
    [string]$LogFile = "C:\AGDLP\GG_to_GDL_Errors.txt"
)

$ErrorActionPreference = "Stop"

# ----------------------------------------------------------------------------
# 0) Chargement module Active Directory
# ----------------------------------------------------------------------------
try { Import-Module ActiveDirectory -ErrorAction Stop }
catch { Write-Error "Module ActiveDirectory introuvable (installer RSAT)."; exit 1 }

# ----------------------------------------------------------------------------
# 1) Initialisation log
# ----------------------------------------------------------------------------
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
[System.IO.File]::WriteAllText($LogFile, "", $utf8Bom)

# ----------------------------------------------------------------------------
# 2) Lecture / validations de base
# ----------------------------------------------------------------------------
if (-not (Test-Path $CsvPath)) { Write-Error "CSV introuvable : $CsvPath"; exit 1 }

$rows  = Import-Csv -Path $CsvPath -Delimiter ";" -Encoding UTF8
$total = $rows.Count
$index = 0

Write-Host "Ajout des GG dans les GDL a partir : $CsvPath"
Write-Host "Log : $LogFile"
Write-Host ""

# ----------------------------------------------------------------------------
# 3) Fonctions utilitaires
# ----------------------------------------------------------------------------

# Nettoyage leger des cellules (supprime NBSP, guillemets typographiques, espaces parasites)
function Clean-Cell([string]$s) {
    if (-not $s) { return "" }
    $s = $s -replace "&nbsp;", " "
    $s = $s -replace "\u00A0", " "  # NBSP
    $s = $s -replace "\u200B", ""   # ZWSP
    $s = $s -replace "[«»“”‘’]", ""
    return ($s -replace "\s+", " ").Trim()
}

# Transforme "A, B , C" -> tableau ["A","B","C"] en nettoyant chaque element
function Parse-GGList([string]$cell) {
    $cell = Clean-Cell $cell
    if (-not $cell) { return @() }
    return $cell.Split(",") | ForEach-Object { Clean-Cell $_ } | Where-Object { $_ -ne "" }
}

# ----------------------------------------------------------------------------
# 4) Parcours des lignes
# ----------------------------------------------------------------------------
foreach ($row in $rows) {
    $index++
    Write-Progress -Activity "Ajout GG -> GDL" -Status "$index / $total" -PercentComplete (($index / $total) * 100)

    # Recup GDL cibles
    $gdlE = Clean-Cell $row.GDL_ECRITURE
    $gdlL = Clean-Cell $row.GDL_LECTURE

    # Rien a faire si pas de GDL cible
    if ([string]::IsNullOrWhiteSpace($gdlE) -and [string]::IsNullOrWhiteSpace($gdlL)) { continue }

    # Parse des listes de GG declarees
    $ggE = Parse-GGList $row.GG_ECRITURE
    $ggL = Parse-GGList $row.GG_LECTURE

    # ---------------------------
    # 4.1) Nettoyage GDL_ECRITURE
    # ---------------------------
    if ($gdlE) {
        # On ne retire que les "groupes non GDL_*" (on conserve chainages/parents GDL)
        $currentE = Get-ADGroupMember -Identity $gdlE -ErrorAction SilentlyContinue |
                    Where-Object { $_.objectClass -eq 'group' -and $_.Name -notlike "GDL_*" }
        if ($currentE) {
            try {
                Remove-ADGroupMember -Identity $gdlE -Members $currentE -Confirm:$false -ErrorAction SilentlyContinue
                Write-Host "Nettoye : $gdlE (groupes non GDL)"
            }
            catch {
                $msg = "Nettoyage impossible GDL_ECRITURE=$gdlE : $_`r`n"
                [System.IO.File]::AppendAllText($LogFile, $msg, $utf8Bom)
                Write-Warning "Nettoyage partiel : $gdlE (voir log)."
            }
        }
    }

    # -------------------------
    # 4.2) Nettoyage GDL_LECTURE
    # -------------------------
    if ($gdlL) {
        $currentL = Get-ADGroupMember -Identity $gdlL -ErrorAction SilentlyContinue |
                    Where-Object { $_.objectClass -eq 'group' -and $_.Name -notlike "GDL_*" }
        if ($currentL) {
            try {
                Remove-ADGroupMember -Identity $gdlL -Members $currentL -Confirm:$false -ErrorAction SilentlyContinue
                Write-Host "Nettoye : $gdlL (groupes non GDL)"
            }
            catch {
                $msg = "Nettoyage impossible GDL_LECTURE=$gdlL : $_`r`n"
                [System.IO.File]::AppendAllText($LogFile, $msg, $utf8Bom)
                Write-Warning "Nettoyage partiel : $gdlL (voir log)."
            }
        }
    }

    # ---------------------------------
    # 4.3) Ajout des GG_ECRITURE -> GDL_ECRITURE
    # ---------------------------------
    if ($gdlE -and $ggE.Count -gt 0) {
        foreach ($m in $ggE) {
            $grp = Get-ADGroup -Identity $m -ErrorAction SilentlyContinue
            if (-not $grp) {
                $msg = "GG_ECRITURE introuvable : $m (cible : $gdlE)`r`n"
                [System.IO.File]::AppendAllText($LogFile, $msg, $utf8Bom)
                Write-Warning "GG introuvable : $m -> ignore"
                continue
            }
            Add-ADGroupMember -Identity $gdlE -Members $grp -ErrorAction SilentlyContinue
            Write-Host "Ajoute : $m -> $gdlE"
        }
    }

    # -------------------------------
    # 4.4) Ajout des GG_LECTURE -> GDL_LECTURE
    # -------------------------------
    if ($gdlL -and $ggL.Count -gt 0) {
        foreach ($m in $ggL) {
            $grp = Get-ADGroup -Identity $m -ErrorAction SilentlyContinue
            if (-not $grp) {
                $msg = "GG_LECTURE introuvable : $m (cible : $gdlL)`r`n"
                [System.IO.File]::AppendAllText($LogFile, $msg, $utf8Bom)
                Write-Warning "GG introuvable : $m -> ignore"
                continue
            }
            Add-ADGroupMember -Identity $gdlL -Members $grp -ErrorAction SilentlyContinue
            Write-Host "Ajoute : $m -> $gdlL"
        }
    }
}

Write-Progress -Activity "Ajout GG -> GDL" -Completed

Write-Host ""
Write-Host "Alignement GG -> GDL termine. Voir le log si des avertissements apparaissent."
```