Scripts et planification via GPO¶
Ce que vous allez apprendre
- Les 4 types de scripts GPO (Startup, Shutdown, Logon, Logoff) — leur emplacement dans le GPT, leur fichier de configuration
scripts.ini, et les GUIDs des CSE associées - Le format exact de
scripts.ini: sections, clés numérotées, ordre d'exécution de scripts multiples - Le fonctionnement de
gpscript.exe: processus lanceur, politique d'exécution PowerShell requise, timeout par défaut de 600 secondes et comment le modifier - Les valeurs de registre contrôlant le mode synchrone/asynchrone et l'impact sur l'expérience d'ouverture de session
- GPP Scheduled Tasks : types disponibles, format XML dans SYSVOL, différences architecturales avec les scripts GPO, et pourquoi ce mécanisme est préférable pour les tâches longues
- Les Event IDs opérationnels (4016, 4017, 4018) pour diagnostiquer les délais de logon imputables aux scripts
Si vous ne retenez qu'une chose
Un script GPO Logon synchrone retarde l'ouverture de session jusqu'à sa complétion. Si ce script dure 45 secondes, l'utilisateur attend 45 secondes devant un écran vide. La solution n'est pas de réduire le timeout — c'est de migrer vers une GPP Scheduled Task de type Immediate, qui s'exécute dans le contexte SYSTEM en tâche de fond, sans bloquer la session.
Les 4 types de scripts GPO¶
Vue d'ensemble¶
Group Policy permet d'attacher des scripts à quatre événements du cycle de vie machine/utilisateur.
Deux événements sont liés à la machine : Startup (démarrage) et Shutdown (arrêt). Deux événements sont liés à l'utilisateur : Logon (ouverture de session) et Logoff (fermeture de session). Ces quatre points d'accroche correspondent à des CSE distinctes et à des emplacements distincts dans le GPT.
Emplacement dans le GPT¶
Les scripts sont stockés dans SYSVOL, à l'intérieur du dossier de la GPO :
\\<domain>\SYSVOL\<domain>\Policies\{GPO-GUID}\
Machine\
Scripts\
Startup\ ← scripts de démarrage machine
Shutdown\ ← scripts d'arrêt machine
scripts.ini ← configuration de tous les scripts machine
User\
Scripts\
Logon\ ← scripts d'ouverture de session utilisateur
Logoff\ ← scripts de fermeture de session utilisateur
scripts.ini ← configuration de tous les scripts utilisateur
Les fichiers de script eux-mêmes (.bat, .ps1, .vbs) doivent être copiés dans le sous-dossier correspondant à leur type. Si vous référencez un script par son nom seul dans scripts.ini, Windows le cherche dans ce sous-dossier. Vous pouvez aussi spécifier un chemin UNC absolu — le script n'a alors pas besoin d'être dans le GPT.
Chemin UNC vs chemin relatif
Un chemin relatif (ex. : Setup.ps1) est résolu relativement au sous-dossier du type de script dans le GPT. Un chemin UNC absolu (ex. : \\server\scripts\Setup.ps1) est utilisé tel quel — le compte d'exécution doit avoir accès à ce partage.
GUIDs des CSE Scripts¶
Chaque type de script est géré par une CSE enregistrée sous HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\.
| Type de script | GUID de la CSE | DLL |
|---|---|---|
| Startup (Machine) | {42B5FAAE-6536-11D2-AE5A-0000F87571E3} | gpscript.dll |
| Shutdown (Machine) | {42B5FAAE-6536-11D2-AE5A-0000F87571E3} | gpscript.dll |
| Logon (User) | {42B5FAAE-6536-11D2-AE5A-0000F87571E3} | gpscript.dll |
| Logoff (User) | {42B5FAAE-6536-11D2-AE5A-0000F87571E3} | gpscript.dll |
Un seul GUID pour les quatre types
Les quatre types de scripts partagent le même GUID de CSE ({42B5FAAE-6536-11D2-AE5A-0000F87571E3}) et la même DLL gpscript.dll. C'est la section dans scripts.ini qui détermine le type et le moment d'exécution — pas la CSE elle-même.
Comparatif des 4 types¶
| Type | Contexte | Compte d'exécution | Moment | Réseau disponible |
|---|---|---|---|---|
| Startup | Machine | SYSTEM | Démarrage, avant logon | Oui (réseau déjà actif) |
| Shutdown | Machine | SYSTEM | Arrêt, après logoff | Variable selon la vitesse d'arrêt |
| Logon | User | Utilisateur connecté | Ouverture de session | Oui |
| Logoff | User | Utilisateur connecté | Fermeture de session | Variable |
Lecture de scripts.ini par la CSE¶
Au moment du traitement (Startup, Logon, etc.), gpsvc invoque gpscript.dll. Celle-ci localise scripts.ini dans le GPT de chaque GPO applicable, lit la section correspondante au type d'événement, et lance gpscript.exe pour chaque script déclaré.
gpscript.exe est le processus intermédiaire responsable du lancement effectif. Il détermine le moteur à utiliser (cmd, PowerShell, wscript) en fonction de l'extension du script, et signale à gpsvc la complétion ou le timeout.
En résumé
- Quatre types de scripts GPO : Startup et Shutdown (machine, compte SYSTEM), Logon et Logoff (utilisateur).
- Tous partagent la même CSE (
{42B5FAAE-6536-11D2-AE5A-0000F87571E3},gpscript.dll). - Les scripts sont stockés dans
{GUID}/Machine/Scripts/{Type}/ou{GUID}/User/Scripts/{Type}/. - La configuration est dans
scripts.ini, lu pargpscript.dll, exécuté viagpscript.exe.
Format de scripts.ini¶
Structure générale¶
scripts.ini est un fichier INI standard avec quatre sections possibles, une par type de script.
[Startup]
0CmdLine=MonScript.ps1
0Parameters=-Mode Deploy -Verbose
[Shutdown]
0CmdLine=Cleanup.bat
0Parameters=
[Logon]
0CmdLine=MapDrives.ps1
0Parameters=-Env Prod
[Logoff]
0CmdLine=AuditSession.ps1
0Parameters=
Clés numérotées et ordre d'exécution¶
Chaque script dans une section est défini par deux clés numérotées : NCmdLine= (chemin du script) et NParameters= (paramètres à passer). La numérotation commence à 0 et est continue.
[Startup]
; Premier script : configuration réseau
0CmdLine=ConfigNetwork.ps1
0Parameters=-SiteCode PAR01
; Deuxième script : déploiement d'agent
1CmdLine=\\deploy.corp.local\agents\InstallAgent.ps1
1Parameters=-Silent -NoRestart
L'ordre d'exécution respecte la numérotation : 0 est exécuté avant 1, 1 avant 2, etc. Si une GPO de niveau supérieur et une GPO de niveau inférieur définissent toutes les deux des scripts Startup, ils sont fusionnés — les scripts de la GPO la plus haute dans LSDOU sont exécutés en premier pour Startup/Logon, et en dernier pour Shutdown/Logoff.
Numérotation discontinue = scripts manquants silencieux
Si vous avez 0CmdLine et 2CmdLine mais pas 1CmdLine, gpscript.dll s'arrête à 0 et n'exécute pas 2. La numérotation doit être strictement continue et commencer à 0. Ne modifiez jamais scripts.ini manuellement : laissez la GPMC gérer ce fichier.
Clés reconnues dans scripts.ini¶
| Clé | Description |
|---|---|
NCmdLine= | Chemin du script (relatif au sous-dossier du type, ou UNC absolu) |
NParameters= | Paramètres passés au script (peut être vide mais la clé doit exister) |
Les autres clés sont ignorées. Il n'y a pas de clé pour définir le timeout ou le compte d'exécution dans scripts.ini — ces comportements sont contrôlés par les Administrative Templates et les valeurs de registre Winlogon.
La clé NParameters= doit toujours être présente
Pour chaque script NCmdLine=, la clé NParameters= correspondante doit exister même si elle est vide. Un 0CmdLine sans 0Parameters peut provoquer un comportement indéfini selon la version de gpscript.dll.
En résumé
scripts.inicontient quatre sections possibles :[Startup],[Shutdown],[Logon],[Logoff].- Chaque script est défini par une paire
NCmdLine=/NParameters=numérotée à partir de0. - L'ordre d'exécution respecte la numérotation — les trous dans la numérotation stoppent silencieusement l'exécution.
- Ce fichier est géré exclusivement par la GPMC — ne l'éditez pas manuellement.
Scripts PowerShell dans le contexte GPO¶
Politique d'exécution requise¶
Par défaut, la politique d'exécution PowerShell sur les systèmes Windows est Restricted — aucun script n'est autorisé. Pour exécuter des scripts GPO en PowerShell, la politique doit être au minimum RemoteSigned.
La méthode recommandée est de la définir via GPO :
Computer Configuration
└── Policies
└── Administrative Templates
└── Windows Components
└── Windows PowerShell
└── Turn on Script Execution
→ Enabled : Allow local scripts and remote signed scripts
(équivalent à RemoteSigned)
Ne jamais passer -ExecutionPolicy Bypass dans les paramètres
Certains guides recommandent d'ajouter -ExecutionPolicy Bypass dans le champ NParameters= de scripts.ini. Cette approche contourne la politique de sécurité de l'organisation et constitue une mauvaise pratique. Définissez la politique correctement via ADMX.
Le processus gpscript.exe¶
gpscript.exe est le lanceur de scripts GPO. Il est invoqué par gpscript.dll pour chaque script à exécuter.
Pour un script PowerShell, gpscript.exe construit et exécute une commande de la forme :
powershell.exe -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned
-File "\\domain\SYSVOL\domain\Policies\{GUID}\Machine\Scripts\Startup\MonScript.ps1"
-Mode Deploy -Verbose
Pour un script .bat ou .cmd, il invoque cmd.exe /c. Pour un .vbs, il invoque wscript.exe ou cscript.exe.
gpscript.exe est visible dans le Gestionnaire des tâches et dans Process Monitor pendant la phase de traitement des scripts. Son PID parent est le processus gpsvc ou winlogon.exe selon le contexte.
Timeout par défaut : 600 secondes¶
Par défaut, gpscript.exe attend 600 secondes (10 minutes) l'exécution de chaque script avant de considérer le traitement comme échoué. Si le script dépasse ce délai, il est terminé de force et un événement d'erreur est consigné.
Ce timeout est modifiable via GPO :
Computer Configuration
└── Policies
└── Administrative Templates
└── System
└── Scripts
├── Maximum wait time for Group Policy scripts
│ → Valeur en secondes (0 = attente infinie, déconseillé)
└── (Paramètres séparés pour Startup, Shutdown, Logon, Logoff)
Timeout à 0 : risque de blocage permanent
Définir le timeout à 0 (attente infinie) est dangereux. Un script qui se bloque sur une ressource réseau inaccessible peut bloquer indéfiniment le démarrage ou la session. Augmentez le timeout jusqu'à une valeur raisonnable plutôt que de le supprimer.
Passer des paramètres à un script PowerShell¶
Les paramètres définis dans NParameters= sont transmis directement à la ligne de commande PowerShell. Ils doivent être compatibles avec la syntaxe -File de PowerShell — c'est-à-dire des paramètres nommés correspondant aux param() déclarés dans le script.
param(
[string]$Mode = "Default",
[switch]$Verbose
)
# Corps du script...
Write-EventLog -LogName Application -Source "GPO-Scripts" `
-EventId 9000 -Message "Script executed in mode: $Mode"
[Startup]
0CmdLine=MonScript.ps1
0Parameters=-Mode Deploy -Verbose
Pas de guillemets dans NParameters pour les valeurs avec espaces
Si un paramètre contient des espaces, encadrez la valeur avec des guillemets dans NParameters= : -Path "C:\Program Files\App". Les guillemets sont transmis tels quels à PowerShell.
En résumé
- La politique d'exécution PowerShell doit être
RemoteSignedminimum — définissez-la via ADMX, pas en ligne de commande. gpscript.exeest le processus lanceur ; il construit la commande PowerShell avec-NonInteractive -NoProfile.- Le timeout par défaut est de 600 secondes — modifiable via
Computer Configuration > Administrative Templates > System > Scripts. - Les paramètres dans
NParameters=sont transmis directement comme arguments-File.
Scripts synchrones vs asynchrones¶
Valeurs de registre Winlogon¶
Le comportement synchrone ou asynchrone des scripts GPO est contrôlé par des valeurs DWORD sous :
| Valeur | Type | Défaut | Effet |
|---|---|---|---|
RunStartupScriptSync | REG_DWORD | 1 | 1 = Startup synchrone (bloque le logon) |
RunLogonScriptSync | REG_DWORD | 0 | 1 = Logon synchrone (bloque l'affichage du bureau) |
RunShutdownScriptSync | REG_DWORD | 1 | 1 = Shutdown synchrone (bloque l'arrêt) |
Ces valeurs sont écrites par la GPO via les Administrative Templates (System > Scripts) — ne les modifiez pas directement dans le registre sans GPO associée, car un refresh GPO les écrasera.
Get-ItemProperty `
"HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" |
Select-Object RunStartupScriptSync, RunLogonScriptSync, RunShutdownScriptSync
RunStartupScriptSync RunLogonScriptSync RunShutdownScriptSync
-------------------- ------------------ ---------------------
1 0 1
Mode synchrone : comportement¶
En mode synchrone, Windows attend la complétion de tous les scripts du type concerné avant de continuer.
Pour Startup synchrone (RunStartupScriptSync=1) : la machine ne présente pas l'écran de logon tant que tous les scripts Startup ne sont pas terminés. L'utilisateur voit l'écran "Applying computer settings..." pendant toute la durée.
Pour Logon synchrone (RunLogonScriptSync=1) : le bureau de l'utilisateur n'est pas affiché tant que tous les scripts Logon ne sont pas terminés. L'utilisateur voit l'écran "Applying your settings..." pendant toute la durée.
Mode asynchrone : comportement¶
En mode asynchrone (défaut pour Logon), les scripts sont lancés en arrière-plan. Le bureau apparaît immédiatement et les scripts continuent de s'exécuter en parallèle.
L'impact visible est minimal pour l'utilisateur. Mais si le script doit produire un effet visible avant que l'utilisateur interagisse (mapper un lecteur réseau, créer un fichier de configuration), il peut ne pas être terminé au moment où l'utilisateur en a besoin.
Quand le mode asynchrone est dangereux¶
Certaines tâches doivent impérativement être terminées avant que l'utilisateur accède au bureau :
- Mappage de lecteurs réseau utilisés par des applications lancées au démarrage
- Configuration de proxy requise pour l'accès à l'intranet
- Création de profil ou de répertoire utilisateur absent
Pour ces cas, le script doit être synchrone — ou migré vers une GPP Scheduled Task de type Immediate qui s'exécute dans le contexte SYSTEM sans impacter le logon.
Logon synchrone sur VPN ou lien lent
Un script Logon synchrone qui accède à une ressource réseau distante via VPN peut bloquer la session pendant plusieurs minutes si la latence est élevée ou si le VPN n'est pas encore établi. Testez toujours vos scripts dans les conditions réseau les plus défavorables de votre parc.
En résumé
RunStartupScriptSync=1(défaut) : Startup synchrone — bloque l'affichage du logon.RunLogonScriptSync=0(défaut) : Logon asynchrone — le bureau s'affiche sans attendre la fin des scripts.- Le mode synchrone est requis pour les scripts dont la complétion est une précondition à l'utilisation du bureau.
- Ces valeurs sont écrites par les ADMX
System > Scripts— ne les modifiez pas directement.
Cycle de vie de gpscript.exe¶
Le diagramme suivant illustre le flux complet depuis l'appel de gpsvc jusqu'à la complétion ou l'expiration du timeout.
sequenceDiagram
participant W as winlogon.exe / gpsvc
participant G as gpscript.dll (CSE Scripts)
participant S as gpscript.exe
participant P as powershell.exe / cmd.exe
W->>G: ProcessGroupPolicy()<br/>(événement : Startup / Logon / etc.)
G->>G: Localise scripts.ini dans le GPT<br/>de chaque GPO applicable
G->>G: Parse la section [Startup] / [Logon]<br/>construit la liste des scripts
loop Pour chaque script (0, 1, 2…)
G->>S: CreateProcess(gpscript.exe)<br/>/startup "CmdLine" "Parameters"
S->>P: CreateProcess(powershell.exe -File ... -Params)<br/>ou cmd.exe /c ... ou wscript.exe ...
P-->>S: Exécution du script
alt Script terminé avant timeout (600s)
P->>S: ExitCode
S->>G: Complétion signalée
else Timeout dépassé
S->>P: TerminateProcess()
S->>G: Timeout signalé
G->>W: Event ID 4018 (timeout)<br/>écrit dans le journal System
end
end
G->>W: ProcessGroupPolicy() retourne<br/>(succès ou échec partiel)
W->>W: Continue (affichage bureau / démarrage) gpscript.exe est un processus éphémère
gpscript.exe est créé pour chaque script et se termine dès que le script est fini ou en timeout. Il ne reste pas résident en mémoire. En mode synchrone, gpscript.dll attend la fin du processus gpscript.exe avant de lancer le suivant.
En résumé
- Le diagramme suivant illustre le flux complet depuis l'appel de gpsvc jusqu'à la complétion ou l'expiration du timeout.
- Retenez surtout ce qui change la portée, l’ordre d’application ou le résultat final observé.
- Ce résumé sert à vérifier que vous avez retenu le mécanisme, sa portée et sa conséquence pratique.
GPP Scheduled Tasks¶
Pourquoi GPP Scheduled Tasks plutôt que scripts GPO¶
Les scripts GPO (Startup/Logon) présentent des limitations architecturales importantes :
- Ils s'exécutent dans un seul contexte temporel défini par l'événement système.
- Ils bloquent la session en mode synchrone.
- Ils ne supportent pas de déclencheurs avancés (délai, heure précise, inactivité).
- Ils n'offrent aucun reporting natif.
Les GPP Scheduled Tasks (Group Policy Preferences > Scheduled Tasks) permettent de créer, modifier ou supprimer des tâches planifiées Windows via GPO, avec toute la puissance du moteur de tâches planifiées Windows.
Types de tâches GPP¶
La GPMC propose plusieurs types de tâches dans Computer/User Configuration > Preferences > Control Panel Settings > Scheduled Tasks :
| Type | Comportement | Déclencheur |
|---|---|---|
| Immediate Task (Windows Vista+) | S'exécute une seule fois dès l'application de la GPO | Immédiat (à chaque refresh GPO si non marqué "run once") |
| Scheduled Task (Windows Vista+) | Tâche planifiée standard — déclencheurs multiples | Heure, événement, démarrage, session, inactivité |
| On Demand Task | Exécution manuelle via schtasks /run | Sur demande uniquement |
| At Log On | Exécution à chaque logon | Ouverture de session |
| At Startup | Exécution au démarrage système | Démarrage Windows |
Immediate Task : le couteau suisse du déploiement
Le type Immediate Task est exécuté dès que la GPO est appliquée lors du prochain refresh. Contrairement à un script Startup qui attend le prochain redémarrage, une Immediate Task s'exécute dans les 90 à 120 minutes suivant sa création si le poste est allumé. C'est le mécanisme de déploiement ponctuel le plus réactif sans reboot.
Format XML dans SYSVOL¶
Les tâches GPP sont stockées dans SYSVOL sous forme de fichiers XML :
\\<domain>\SYSVOL\<domain>\Policies\{GPO-GUID}\
Machine\
Preferences\
ScheduledTasks\
ScheduledTasks.xml
User\
Preferences\
ScheduledTasks\
ScheduledTasks.xml
Exemple de ScheduledTasks.xml pour une Immediate Task PowerShell exécutée en SYSTEM :
<?xml version="1.0" encoding="utf-8"?>
<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A0CE60491FE6}">
<ImmediateTaskV2
clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}"
name="Deploy-AgentCorp"
image="0"
changed="2025-03-01 09:00:00"
uid="{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
userContext="0"
removePolicy="0">
<Properties
action="C"
name="Deploy-AgentCorp"
runAs="NT AUTHORITY\System"
logonType="S4U">
<Task version="1.3">
<RegistrationInfo>
<Author>CORP\gpo-admin</Author>
<Description>Deploy monitoring agent via GPO</Description>
</RegistrationInfo>
<Principals>
<Principal id="Author">
<UserId>NT AUTHORITY\System</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<ExecutionTimeLimit>PT30M</ExecutionTimeLimit>
</Settings>
<Actions>
<Exec>
<Command>powershell.exe</Command>
<Arguments>-NonInteractive -NoProfile -ExecutionPolicy RemoteSigned
-File "\\deploy.corp.local\scripts\Install-Agent.ps1" -Silent</Arguments>
</Exec>
</Actions>
</Task>
</Properties>
</ImmediateTaskV2>
</ScheduledTasks>
Ne jamais éditer ScheduledTasks.xml manuellement
Ce fichier est généré et maintenu par la GPMC. Une modification manuelle peut corrompre le GUID de l'item, provoquer des erreurs de parsing par gpprefcl.dll, ou désynchroniser l'état entre le fichier XML et les attributs GPO dans AD.
GPP Scheduled Tasks vs Scripts GPO¶
| Critère | Scripts GPO | GPP Scheduled Tasks |
|---|---|---|
| Déclencheurs | Startup, Shutdown, Logon, Logoff uniquement | Démarrage, session, heure, événement, inactivité, immédiat |
| Compte d'exécution | SYSTEM (machine) ou utilisateur (user) | SYSTEM, utilisateur spécifique, service account |
| Timeout configurable | Oui (via ADMX, global) | Oui (par tâche, ExecutionTimeLimit) |
| Impact sur le logon | Oui si synchrone | Aucun (s'exécute en tâche de fond) |
| Déclenchement sans reboot | Non — attend l'événement système | Oui — Immediate Task au prochain refresh GPO |
| Visibilité dans le planificateur | Non (gpscript.exe, éphémère) | Oui — visible dans Task Scheduler |
| Reporting | Event Log uniquement | Task Scheduler + Event Log |
| Suppression automatique | Non | Configurable (removePolicy) |
Options de compte d'exécution¶
Les GPP Scheduled Tasks offrent plusieurs options pour le compte sous lequel la tâche s'exécute :
- NT AUTHORITY\System : recommandé pour les tâches d'infrastructure (installation, configuration système). Accès complet à la machine locale, mais pas d'accès aux ressources réseau avec l'identité de la machine.
- Utilisateur connecté (
logonType="InteractiveToken") : la tâche s'exécute dans le contexte de la session courante — utile pour les tâches utilisateur avec accès à la session graphique. - Compte de service : un compte de service AD dédié — requis si la tâche doit accéder à des ressources réseau authentifiées (partages, bases de données).
NT AUTHORITY\System et les ressources réseau
Une tâche exécutée en SYSTEM peut accéder aux ressources réseau via le compte machine (DOMAIN\COMPUTERNAME$). Si le partage cible accorde des permissions au compte machine ou à un groupe de machines, l'accès est possible. Sinon, utilisez un compte de service dédié.
Exemple complet : PowerShell en SYSTEM au démarrage¶
Scénario : déployer un agent de supervision lors du démarrage, sans bloquer la session.
Dans la GPMC :
Computer Configuration
└── Preferences
└── Control Panel Settings
└── Scheduled Tasks
└── Clic droit → New → Immediate Task (Windows Vista and later)
→ General : Run as NT AUTHORITY\System, Run whether user is logged on or not
→ Actions : powershell.exe
Arguments : -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned
-File "\\deploy.corp.local\scripts\Install-Agent.ps1" -Silent
→ Settings : Stop task if it runs longer than 30 minutes
Vérification sur le poste cible :
Get-ScheduledTask -TaskName "Deploy-AgentCorp" |
Select-Object TaskName, State, @{n="LastRunTime";e={$_.LastRunTime}},
@{n="LastResult";e={$_.LastTaskResult}}
TaskName State LastRunTime LastResult
-------- ----- ----------- ----------
Deploy-AgentCorp Ready 2025-03-01 09:14:32 0
Un LastResult de 0 indique une exécution réussie (0x00000000 = S_OK).
En résumé
- GPP Scheduled Tasks offre des déclencheurs, des comptes d'exécution et un reporting bien supérieurs aux scripts GPO.
- Le type Immediate Task s'exécute sans attendre un redémarrage ou un logon — au prochain refresh GPO.
- Les tâches sont stockées dans
{GUID}/Machine/Preferences/ScheduledTasks/ScheduledTasks.xml. - Pour les opérations d'infrastructure longues ou potentiellement lentes, GPP Scheduled Tasks est toujours préférable aux scripts Startup/Logon synchrones.
Event IDs pour le diagnostic des scripts¶
Tableau des Event IDs Scripts CSE¶
Les événements liés au traitement des scripts GPO sont enregistrés dans le journal System (pour les scripts Machine) et Application (pour certains scripts utilisateur), sous la source Microsoft-Windows-GroupPolicy.
| Event ID | Journal | Source | Signification |
|---|---|---|---|
4016 | System / Application | GroupPolicy | Début du traitement par la CSE Scripts |
4017 | System / Application | GroupPolicy | Fin du traitement par la CSE Scripts |
4018 | System / Application | GroupPolicy | Timeout — un script a dépassé le délai maximum |
5308 | System | GroupPolicy | Traitement des scripts ignoré (lien lent détecté) |
Analyser les délais de logon avec Event ID 4018¶
L'Event ID 4018 contient les informations critiques pour identifier le script incriminé et la durée dépassée.
Log Name: System
Source: Microsoft-Windows-GroupPolicy
Event ID: 4018
Level: Error
Description: The Group Policy Scripts Client Side Extension timed out
(600 seconds) while processing Logon script for user CORP\jdoe.
The script was: \\corp.local\SYSVOL\corp.local\Policies\
{A1B2C3D4-...}\User\Scripts\Logon\MapDrives.ps1
Mesurer la durée réelle avec les Event IDs 4016 et 4017¶
Les Event IDs 4016 (début) et 4017 (fin) permettent de calculer la durée exacte du traitement de la CSE Scripts.
$start = Get-WinEvent -LogName System |
Where-Object { $_.Id -eq 4016 -and $_.ProviderName -eq "Microsoft-Windows-GroupPolicy" } |
Sort-Object TimeCreated -Descending |
Select-Object -First 1
$end = Get-WinEvent -LogName System |
Where-Object { $_.Id -eq 4017 -and $_.ProviderName -eq "Microsoft-Windows-GroupPolicy" } |
Sort-Object TimeCreated -Descending |
Select-Object -First 1
$duration = $end.TimeCreated - $start.TimeCreated
Write-Output "Scripts CSE duration: $($duration.TotalSeconds) seconds"
Event ID 4016 et 4017 dans le journal opérationnel
Sur les systèmes récents, les Event IDs les plus détaillés se trouvent dans le journal analytique Microsoft-Windows-GroupPolicy/Operational (Applications and Services Logs > Microsoft > Windows > GroupPolicy > Operational). Ce journal doit être activé manuellement s'il ne l'est pas.
wevtutil set-log "Microsoft-Windows-GroupPolicy/Operational" /enabled:true
Corrélation avec le délai perçu par l'utilisateur¶
En mode Logon synchrone, la durée entre les Event IDs 4016 et 4017 (ou le timeout 4018) correspond exactement au délai que l'utilisateur perçoit entre la saisie de ses credentials et l'apparition du bureau.
Un délai > 10 secondes mérite investigation. Un délai > 30 secondes est un incident de niveau 2.
En résumé
- Event ID
4016/4017: début et fin du traitement de la CSE Scripts — permettent de mesurer la durée exacte. - Event ID
4018: timeout — contient le nom du script, le type d'événement, et l'utilisateur concerné. - Le journal
Microsoft-Windows-GroupPolicy/Operationalfournit le détail le plus fin — activez-le sur les postes de diagnostic. - La durée
4016→4017en logon synchrone = délai ressenti par l'utilisateur.
Piège de production : logon bloqué par un script lent¶
Symptôme¶
Un parc de 300 postes présente un délai d'ouverture de session systématique de 35 à 50 secondes après l'entrée des credentials. L'écran "Applying your settings..." reste affiché pendant toute cette durée. Le phénomène est apparu après le déploiement d'un nouveau script Logon GPO il y a deux semaines.
Diagnostic¶
Étape 1 : Identifier le délai dans les Event Logs.
Sur un poste affecté, dans le journal System (source Microsoft-Windows-GroupPolicy) :
Get-WinEvent -LogName System -MaxEvents 500 |
Where-Object {
$_.ProviderName -eq "Microsoft-Windows-GroupPolicy" -and
$_.Id -in @(4016, 4017, 4018)
} |
Select-Object TimeCreated, Id, Message |
Sort-Object TimeCreated
TimeCreated Id Message
----------- -- -------
2025-03-15 08:42:11 4016 The Group Policy Scripts Client Side Extension...
2025-03-15 08:42:56 4017 The Group Policy Scripts Client Side Extension...
La différence : 45 secondes. C'est le temps que prend la CSE Scripts à traiter tous les scripts Logon.
Étape 2 : Identifier le script responsable.
Avec le journal opérationnel activé, les Event IDs 5000–5010 détaillent chaque script individuel et sa durée.
Get-WinEvent -LogName "Microsoft-Windows-GroupPolicy/Operational" |
Where-Object { $_.Message -match "script" -and $_.Level -ne 4 } |
Select-Object TimeCreated, Id, Message |
Sort-Object TimeCreated -Descending |
Select-Object -First 20
Le résultat pointe vers MapNetworkDrives.ps1 — un script qui tente de mapper 8 lecteurs réseau via des chemins UNC vers un serveur de fichiers distant, avec un timeout de connexion de 5 secondes par lecteur.
Étape 3 : Confirmer la cause.
Le script MapNetworkDrives.ps1 effectue une résolution DNS pour chaque serveur de fichiers et attend une réponse réseau. Sur des sites distants avec une latence WAN élevée, cela prend 4 à 6 secondes par lecteur × 8 lecteurs = 32 à 48 secondes.
Résolution¶
Option 1 (recommandée) : Migrer vers une GPP Drive Map.
La GPP Drive Maps est conçue exactement pour ce cas d'usage. Elle s'exécute en arrière-plan (asynchrone par design), supporte l'Item-Level Targeting, et ne bloque pas le logon.
User Configuration
└── Preferences
└── Windows Settings
└── Drive Maps
└── New → Mapped Drive
Action : Create
Location : \\server\share
Drive Letter : H
Label : Profil (H:)
Connect As : (laisser vide pour l'utilisateur connecté)
Option 2 (si le script doit rester) : Le convertir en GPP Scheduled Task asynchrone.
Si le script contient une logique complexe qui ne peut pas être remplacée par une Drive Map native :
- Supprimer le script du nœud
User Configuration > Policies > Windows Settings > Scripts > Logon. - Créer une GPP Scheduled Task de type Immediate Task dans
User Configuration > Preferences > Control Panel Settings > Scheduled Tasks. - Configurer l'action :
powershell.exe -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned -File "\\server\scripts\MapNetworkDrives.ps1". - Compte d'exécution : utilisateur connecté (
logonType="InteractiveToken").
La tâche s'exécute en arrière-plan pendant que le bureau se charge. Les lecteurs réseau seront disponibles quelques secondes après l'apparition du bureau — délai imperceptible pour l'utilisateur.
Immediate Task en contexte utilisateur : la session doit exister
Une Immediate Task configurée dans User Configuration s'exécute dans le contexte de la session de l'utilisateur. Si la tâche est créée alors qu'aucun utilisateur n'est connecté, elle sera en attente jusqu'au prochain logon. Ce comportement est attendu et correct.
Option 3 (si le script Logon doit rester synchrone) : Optimiser le script.
Si la synchronicité est indispensable (ex. : mappage requis avant le lancement d'une application de démarrage) :
- Remplacer les timeouts de connexion par des tests préalables (
Test-NetConnectionavec-InformationLevel Quiet -Count 1). - Paralléliser les mappages avec
Start-JobouForEach-Object -Parallel(PowerShell 7+). - Supprimer les mappages de lecteurs inutilisés du script.
En résumé
- Un script Logon synchrone qui prend 45 secondes bloque la session 45 secondes — Event ID
4016/4017mesure ce délai exactement. - La migration vers GPP Drive Maps est la solution la plus propre pour les mappages réseau.
- Si le script doit rester, une GPP Immediate Task en contexte utilisateur l'exécute en arrière-plan sans bloquer le logon.
- Toujours mesurer avant d'optimiser : les Event IDs
4016et4017fournissent la durée exacte.
Voir aussi¶
- 03 — Client-Side Extensions (CSE) — structure interne de la CSE Scripts (
gpscript.dll), cycle de déclenchement, valeurs de registreGPExtensions - 07 — Traitement des GPO — contexte du traitement synchrone vs asynchrone, foreground vs background, impact sur les CSE
- 11 — Preferences GPP — architecture GPP, Drive Maps, ScheduledTasks XML, Item-Level Targeting
En résumé
- À relire : 03 — Client-Side Extensions (CSE).
- À relire : 07 — Traitement des GPO.
- À relire : 11 — Preferences GPP.
- Ces renvois prolongent le chapitre avec des mécanismes complémentaires ou des cas d’usage voisins.
- Gardez ces chapitres sous la main pour le diagnostic ou la conception d’une GPO liée à ce thème.