Besoin d’identifier rapidement quels postes ont bien reçu le client Genian NAC via GPO ? Voici une méthode complète, outillée et reproductible pour obtenir une liste claire des installations réussies et des échecs, avec des scripts PowerShell prêts à l’emploi et des conseils de dépannage.
Contexte et objectif
Vous avez déployé le client Genian NAC par Stratégie de Groupe (GPO). Certains postes l’ont reçu, d’autres non. L’objectif : produire un inventaire fiable « Installé / Non installé / Échec », comprendre pourquoi une machine n’a pas reçu l’agent, puis corriger et relancer le déploiement au besoin.
Plan de contrôle en quatre axes
- Vérifier l’application de la GPO (ciblage, filtrage de sécurité, WMI filter, héritage/liaison OU).
- Collecter les journaux d’installation (MSI et « Application Management »).
- Valider la présence réelle du logiciel sur les postes (registre d’installation).
- Consolider le tout dans un rapport unique (CSV/HTML) afin de prioriser les actions.
Vue d’ensemble : objectifs, méthodes et livrables
Objectif | Méthode recommandée | Résultat attendu |
---|---|---|
Connaître l’état d’application de la GPO | Utiliser la Group Policy Management Console (GPMC) → Group Policy Results Wizard (ou RSoP). En masse, PowerShell Get-GPResultantSetOfPolicy ou gpresult . | Rapport par machine/utilisateur indiquant si la GPO « Genian NAC » s’est appliquée et, sinon, la raison (filtrage de sécurité, WMI filter, problème de liaison OU, héritage bloqué, etc.). |
Détecter les échecs d’installation | Observateur d’événements (local ou distant). Filtrer les journaux Application : Application Management (ID 301–302) et MsiInstaller (ID 103–108, 117–119). Export en CSV (PowerShell ou wevtutil ). | Liste horodatée des PC où l’installation a démarré, réussi ou échoué (codes et messages à l’appui). |
Vérifier la présence réelle du logiciel | Registre d’installation : HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\* et HKLM\Software\WOW6432Node\...\Uninstall\* (éviter Win32_Product en production). Filtrer DisplayName pour « Genian ». | Inventaire « Installé / Non installé » par poste avec nom du produit, version, éditeur. |
Dépanner les postes non visés | Vérifier l’OU, le filtrage de sécurité (Authenticated Users ou groupe cible), le WMI filter, l’accès UNC au package MSI, le paramètre « Toujours attendre le réseau… », forcer gpupdate /force et redémarrer si nécessaire. | Couverture GPO rétablie et conditions d’installation respectées. |
Réinstaller manuellement si besoin | Script silencieux msiexec ou EXE avec switches, via Intune, SCCM/ConfigMgr, PDQ, PsExec , tâche planifiée à distance. | Installation finalisée sur les postes récalcitrants. |
Vérifier l’application de la GPO « Genian NAC »
Avec la console GPMC (cas rapide)
- Ouvrez Group Policy Management depuis une machine d’admin avec RSAT.
- Clic droit sur Group Policy Results → Run Wizard.
- Sélectionnez l’ordinateur et l’utilisateur (ou « me »/machine locale), exécutez.
- Dans le rapport, cherchez la GPO « Genian NAC » : Applied GPOs (appliquée) ou Denied GPOs (refusée), et lisez la raison (sécurité, WMI, héritage, distance de liaison).
En masse avec PowerShell
Si le module GPMC est installé, Get-GPResultantSetOfPolicy
peut générer un RSOP au format XML lisible et diffusable :
# Exemple : RSOP pour une machine distante
$computer = "PC-001"
$outXml = "C:\Temp\RSOP_$computer.xml"
Get-GPResultantSetOfPolicy -ReportType Xml -Path $outXml -Computer $computer
# Recherche de la GPO "Genian" dans le RSOP
[xml]$rsop = Get-Content $outXml
$applied = $rsop.Rsop.ComputerResults.GPO | Where-Object { $*.Name -like "*Genian*" -and $*.Applied -eq "true" }
$denied = $rsop.Rsop.ComputerResults.GPO | Where-Object { $*.Name -like "*Genian*" -and $*.Applied -eq "false" }
Sans GPMC, utilisez gpresult
(XML/HTML) :
gpresult /S PC-001 /SCOPE COMPUTER /H C:\Temp\gpresult_PC-001.html
gpresult /S PC-001 /SCOPE COMPUTER /X C:\Temp\gpresult_PC-001.xml
Collecter les journaux d’installation MSI
Le déploiement par GPO écrit dans le journal Application :
Source | Event ID | Signification |
---|---|---|
Application Management | 301 / 302 | Application de stratégie d’installation logicielle (début/fin, attribution/ publication). |
MsiInstaller | 103–108 | Résultats de l’installation/suppression/ réparation MSI (message contient souvent « success » ou code d’erreur). |
MsiInstaller | 117–119 | Résultats liés aux patchs/annonces de produit. |
Extraction avec PowerShell (local ou distant) :
$computer = "PC-001"
$events = Get-WinEvent -ComputerName $computer -FilterHashtable @{
LogName = "Application"
Id = 103,104,105,106,107,108,117,118,119,301,302
} -ErrorAction SilentlyContinue |
Where-Object {
$_.ProviderName -in @("MsiInstaller","Application Management") -and
$_.Message -match "Genian"
} |
Select-Object TimeCreated, Id, ProviderName, LevelDisplayName, Message
$events | Format-Table -AutoSize
Export CSV :
$events | Export-Csv C:\Temp\GenianNAC_Events_PC-001.csv -NoTypeInformation -Encoding UTF8
Vérifier la présence réelle du client Genian NAC
Évitez Get-CimInstance Win32_Product
en production (lent et peut déclencher des « self-repair »). Préférez la lecture du registre :
function Get-InstalledGenianNac {
param([string]$ComputerName = $env:COMPUTERNAME)
$paths = @(
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall*",
"HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall*"
)
$script = {
param($paths)
$all = foreach($p in $paths){
if(Test-Path $p){
Get-ItemProperty $p -ErrorAction SilentlyContinue
}
}
$all | Where-Object { $_.DisplayName -like "Genian*" } |
Select-Object PSComputerName, DisplayName, DisplayVersion, Publisher, InstallDate
}
try {
Invoke-Command -ComputerName $ComputerName -ScriptBlock $script -ArgumentList ($paths) -ErrorAction Stop
} catch {
Write-Warning "Impossible d'interroger $ComputerName : $_"
}
}
# Exemple
Get-InstalledGenianNac -ComputerName "PC-001"
Rapport unifié : qui a (ou n’a pas) reçu Genian NAC
L’idée : pour chaque poste cible, agréger GPO appliquée ?, journaux MSI et présence réelle du produit, puis classifier l’état. Le script ci‑dessous produit à la fois un CSV et un HTML lisibles (style basique intégré).
Script PowerShell clé en main
Pré‑requis : WinRM/PowerShell Remoting activé pour l’interrogation distante, droits d’admin sur les postes, RSAT si vous utilisez Get-GPResultantSetOfPolicy
. À défaut, le script bascule vers gpresult
.
Param(
[string]$OU = "", # Exemple: "OU=Postes,OU=Paris,DC=contoso,DC=local"
[string]$ComputerListPath = "", # Option: CSV avec colonne 'ComputerName'
[string]$GpoName = "Genian", # Mot-clé de la GPO/produit
[string]$OutputFolder = "C:\Temp", # Où poser CSV/HTML
[int]$EventLookbackDays = 30
)
# --- Fonctions utilitaires ---------------------------------------------------
function Get-TargetComputers {
if (Test-Path $ComputerListPath) {
Import-Csv $ComputerListPath | ForEach-Object { $*.ComputerName } | Where-Object { $* }
} elseif ($OU) {
if (Get-Module -ListAvailable -Name ActiveDirectory) {
Import-Module ActiveDirectory -ErrorAction Stop
Get-ADComputer -Filter * -SearchBase $OU -SearchScope Subtree |
Select-Object -ExpandProperty Name
} else {
throw "Module ActiveDirectory absent et pas de liste CSV fournie."
}
} else {
throw "Précisez -OU ou -ComputerListPath."
}
}
function Test-Remote {
param([string]$Computer)
Test-Connection -ComputerName $Computer -Count 1 -Quiet -ErrorAction SilentlyContinue
}
function Get-GpoApplied {
param([string]$Computer, [string]$GpoName)
$result = [ordered]@{
Computer = $Computer
GpoApplied = $null
GpoReason = $null
Method = $null
}
try {
if (Get-Command Get-GPResultantSetOfPolicy -ErrorAction SilentlyContinue) {
$tmp = Join-Path $env:TEMP ("RSOP_{0}.xml" -f $Computer)
Get-GPResultantSetOfPolicy -ReportType Xml -Path $tmp -Computer $Computer -ErrorAction Stop
[xml]$rsop = Get-Content $tmp
```
$gpos = $rsop.Rsop.ComputerResults.GPO
if ($gpos) {
$matchApplied = $gpos | Where-Object { $_.Name -like "*$GpoName*" -and $_.Applied -eq "true" }
$matchDenied = $gpos | Where-Object { $_.Name -like "*$GpoName*" -and $_.Applied -ne "true" }
if ($matchApplied){
$result.GpoApplied = $true
$result.GpoReason = "Applied"
} elseif ($matchDenied){
$result.GpoApplied = $false
$result.GpoReason = ($matchDenied.Reason -join "; ")
} else {
$result.GpoApplied = $false
$result.GpoReason = "GPO non trouvée dans RSOP"
}
} else {
$result.GpoApplied = $false
$result.GpoReason = "RSOP vide"
}
$result.Method = "GPMC"
Remove-Item $tmp -ErrorAction SilentlyContinue
} else {
# Fallback gpresult
$tmp = Join-Path $env:TEMP ("GPRESULT_{0}.xml" -f $Computer)
cmd /c "gpresult /S $Computer /SCOPE COMPUTER /X `"$tmp`" >nul 2>&1"
if (Test-Path $tmp) {
[xml]$xml = Get-Content $tmp
$names = $xml.Rsop.ComputerResults.GPO | ForEach-Object { $_.Name }
if ($names -match $GpoName) {
$result.GpoApplied = $true
$result.GpoReason = "Applied (gpresult)"
} else {
$result.GpoApplied = $false
$result.GpoReason = "Non listée (gpresult)"
}
$result.Method = "gpresult"
Remove-Item $tmp -ErrorAction SilentlyContinue
} else {
$result.GpoApplied = $null
$result.GpoReason = "gpresult indisponible"
$result.Method = "gpresult"
}
}
```
} catch {
$result.GpoApplied = $null
$result.GpoReason = "Erreur RSOP/gpresult : $_"
$result.Method = "error"
}
[pscustomobject]$result
}
function Get-GenianInstallEvidence {
param([string]$Computer, [string]$GpoName, [int]$Days)
$ev = $null
try {
$ev = Get-WinEvent -ComputerName $Computer -FilterHashtable @{
LogName = "Application"
Id = 103,104,105,106,107,108,117,118,119,301,302
StartTime = (Get-Date).AddDays(-$Days)
} -ErrorAction Stop | Where-Object {
$*.ProviderName -in @("MsiInstaller","Application Management") -and
$*.Message -match $GpoName
} | Select-Object -First 1 TimeCreated, Id, ProviderName, LevelDisplayName, Message
} catch {
# ignore
}
$reg = $null
try {
$sb = {
param($name)
$paths = @(
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall*",
"HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall*"
)
$items = foreach($p in $paths){ if(Test-Path $p){ Get-ItemProperty $p -ErrorAction SilentlyContinue } }
$items | Where-Object { $_.DisplayName -like "*$name*" } |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
}
$reg = Invoke-Command -ComputerName $Computer -ScriptBlock $sb -ArgumentList $GpoName -ErrorAction Stop
} catch {
# ignore
}
[pscustomobject]@{
Computer = $Computer
Installed = [bool]$reg
ProductName = $reg.DisplayName -join "; "
ProductVersion = $reg.DisplayVersion -join "; "
EventId = $ev.Id
EventProvider = $ev.ProviderName
EventTime = $ev.TimeCreated
EventMessage = ($ev.Message -replace "\s+"," ").Substring(0, [Math]::Min(400, ($ev.Message -replace "\s+"," ").Length))
}
}
function Classify-Status {
param(
[bool]$Installed,
[nullable[bool]]$GpoApplied,
[int]$EventId,
[string]$EventMessage
)
if ($Installed) { return "Installé" }
if ($GpoApplied -eq $false) { return "GPO non appliquée" }
if ($GpoApplied -eq $true -and $EventId) {
if ($EventId -in 103,302 -and $EventMessage -match "(success|réuss|completed)") {
return "Installé (journaux)"
} else {
return "Échec MSI"
}
}
if ($GpoApplied -eq $true -and -not $EventId) { return "Pas de trace MSI" }
return "Inconnu"
}
# --- Corps principal ---------------------------------------------------------
$start = Get-Date
$computers = Get-TargetComputers | Sort-Object -Unique
Write-Host "Cibles : $($computers.Count) machine(s)"
$results = foreach($c in $computers){
Write-Host "Analyse $c ..."
if (-not (Test-Remote -Computer $c)) {
[pscustomobject]@{
Computer = $c
Online = $false
GpoApplied = $null
GpoReason = "Hôte injoignable"
Installed = $false
ProductName = $null
ProductVersion = $null
EventId = $null
EventProvider = $null
EventTime = $null
EventMessage = $null
Status = "Injoignable"
}
continue
}
$gpo = Get-GpoApplied -Computer $c -GpoName $GpoName
$ev = Get-GenianInstallEvidence -Computer $c -GpoName $GpoName -Days $EventLookbackDays
[pscustomobject]@{
Computer = $c
Online = $true
GpoApplied = $gpo.GpoApplied
GpoReason = $gpo.GpoReason
Installed = $ev.Installed
ProductName = $ev.ProductName
ProductVersion = $ev.ProductVersion
EventId = $ev.EventId
EventProvider = $ev.EventProvider
EventTime = $ev.EventTime
EventMessage = $ev.EventMessage
Status = Classify-Status -Installed $ev.Installed -GpoApplied $gpo.GpoApplied -EventId $ev.EventId -EventMessage $ev.EventMessage
}
}
# Export CSV
$csvPath = Join-Path $OutputFolder ("GenianNAC-Rapport_{0:yyyyMMdd_HHmm}.csv" -f $start)
$results | Export-Csv $csvPath -NoTypeInformation -Encoding UTF8
# Export HTML simple
$css = @"
"@
$rows = $results | Select-Object Computer, Online, GpoApplied, GpoReason, Installed, ProductName, ProductVersion, EventId, EventProvider, EventTime, Status
$html = $rows | ConvertTo-Html -Title "Genian NAC - Rapport de déploiement" -Head $css -PreContent "Genian NAC – Rapport de déploiementGénéré le $((Get-Date).ToString()) – Périmètre : $($computers.Count) poste(s)."
$htmlPath = Join-Path $OutputFolder ("GenianNAC-Rapport_{0:yyyyMMdd_HHmm}.html" -f $start)
$html | Set-Content -Path $htmlPath -Encoding UTF8
Write-Host "OK : $csvPath"
Write-Host "OK : $htmlPath"
Colonnes clés du rapport
- Computer : nom NetBIOS/FQDN.
- GpoApplied / GpoReason : verdict d’application de la GPO et raison si refusée.
- Installed / ProductName / ProductVersion : présence réelle dans le registre.
- EventId / EventProvider / EventTime : dernière trace MSI pertinente, horodatée.
- Status : classification finale (Installé, Échec MSI, GPO non appliquée, Pas de trace MSI, Injoignable).
Dépanner les postes non visés
Checklist rapide
- OU & liaison GPO : l’ordinateur est‑il dans l’OU où la GPO est liée ? L’héritage est‑il bloqué ?
- Filtrage de sécurité : la GPO est‑elle Appliquée au groupe Authenticated Users (lecture + application) ou à un groupe cible contenant les comptes machines ?
- WMI filter : la requête correspond‑elle réellement aux machines visées (version d’OS, architecture, niveau de patch) ?
- Chemin du package : le package MSI/EXE est référencé via un chemin UNC (
\\serveur\partage\...
), pas un lecteur mappé. Les comptes ordinateurs ont‑ils les droits Lire sur le partage ? - Bande passante : si sites distants, envisager DFS-R ou un point de distribution local.
- Moment de l’installation : pour un déploiement côté Computer Configuration > Software Installation, l’installation se fait au démarrage ; prévoir un ou deux redémarrages.
- Paramètre réseau : activer « Toujours attendre le réseau lors du démarrage et de l’ouverture de session » afin de ne pas rater le traitement GPO au boot.
- Services MSI : Windows Installer n’est pas désactivé, l’espace disque est suffisant, et le cache CCMCache/SoftwareDistribution (selon outil) n’est pas corrompu.
Codes et messages d’erreur MSI courants
Symptôme | Piste | Action |
---|---|---|
ID 103/302 avec « access denied / 0x5 » | Partage UNC inaccessible pour le compte ordinateur. | Donner « Read » au groupe Domain Computers sur le partage/dossier. |
ID 103 avec « another installation is in progress » | MSI en conflit. | Attendre fin des installations, redémarrer, rejouer GPO. |
Échec silencieux, pas d’événement MSI | GPO non appliquée ou démarrage trop rapide. | Vérifier RSOP, activer « Toujours attendre le réseau », redémarrer 2×. |
Réinstaller manuellement sur les postes récalcitrants
Commande silencieuse type
Adaptez au package réel (MSI/EXE) et aux paramètres fournis par l’éditeur.
# MSI silencieux
msiexec /i "\\serveur\logiciels\GenianNAC.msi" /qn /norestart
# EXE (exemple générique)
\serveur\logiciels\GenianNAC_Setup.exe /silent /norestart
Exécution distante
Quelques options répandues :
- Intune / SCCM / PDQ : packager l’installeur avec switches silencieux.
- PsExec : lancer en Local System si besoin d’accès machine.
- Tâche planifiée : créer à distance une tâche qui exécute l’installation au prochain démarrage.
# Exemple PsExec (exécuté depuis un poste d'admin avec Sysinternals)
psexec \\PC-001 -s -d msiexec /i "\\serveur\logiciels\GenianNAC.msi" /qn /norestart
Bonnes pratiques pour éviter les échecs futurs
- Hébergement du package : partage hautement disponible, réplication DFS sur sites distants.
- Versionnement : nommez les GPO et packages avec un indicateur de version (GenianNAC_2.3.1), archivez les anciens MSI.
- Console serveur Genian : comparez la liste des agents vus par le serveur avec l’inventaire AD pour repérer les postes manquants.
- Event Forwarding : centralisez les événements MsiInstaller/Application Management pour audit global.
- Automatisation : exécutez le script d’inventaire en planifié, générez un HTML/CSV pour la DSI.
- Tests : OU de pré‑prod dédiée, représentative des sites et matériels.
FAQ – Questions fréquentes
Faut‑il redémarrer pour une GPO « Software Installation » côté ordinateur ?
Oui : l’installation se déclenche au démarrage. Après changement de GPO, prévoyez gpupdate /force
puis deux redémarrages pour garantir le cycle.
Pourquoi « Win32_Product » est déconseillé ?
Il est lent et peut déclencher des réparations MSI. Préférez la lecture des clés Uninstall dans le Registre (x86 et x64).
Le package s’installe pour certains utilisateurs seulement
Vérifiez si le déploiement a été configuré par utilisateur au lieu de par ordinateur. Selon le cas, l’installation se produit à l’ouverture de session ou au démarrage.
Le package ne se trouve pas
Vérifiez le chemin UNC, les droits NTFS/partage pour les comptes ordinateurs et la résolution DNS/NetBIOS.
Modèle de feuille de route corrective
- Exécuter le script pour obtenir le rapport consolidé.
- Filtrer sur « GPO non appliquée » : corriger OU/filtrage/WMI, déployer
gpupdate
. - Filtrer sur « Échec MSI » : lire EventMessage, traiter les causes (droits, verrouillage MSI, disque, dépendances).
- Relancer l’installation manuellement sur les machines encore « Non installé ».
- Re‑exécuter le script et valider que l’état passe à « Installé ».
Exemple de matrice d’état
GPO appliquée | Trace MSI | Produit trouvé | Statut final | Action |
---|---|---|---|---|
Oui | Succès | Oui | Installé | Aucune |
Oui | Échec | Non | Échec MSI | Analyser EventMessage, relancer installation |
Non | — | Non | GPO non appliquée | Corriger OU/filtrage/WMI |
Oui | — | Non | Pas de trace MSI | Vérifier timing au boot, redémarrer |
— | — | — | Injoignable | Corriger connectivité/pare-feu |
Conclusion
En combinant RSOP, journaux MSI et inventaire registre, vous obtenez une image complète du déploiement de Genian NAC. Le script fourni automatise la collecte et la classification, vous permettant d’agir immédiatement : corriger le ciblage GPO, traiter les erreurs MSI et finaliser l’installation sur 100 % du parc.